Merge "Clean up Hal AIDL imports" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 233fb8a..4c235e4 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -83,6 +83,7 @@
         "com.android.internal.pm.pkg.component.flags-aconfig-java",
         "com.android.media.flags.bettertogether-aconfig-java",
         "com.android.media.flags.editing-aconfig-java",
+        "com.android.media.flags.performance-aconfig-java",
         "com.android.media.flags.projection-aconfig-java",
         "com.android.net.thread.platform.flags-aconfig-java",
         "com.android.server.flags.services-aconfig-java",
@@ -158,6 +159,7 @@
 aconfig_declarations {
     name: "com.android.window.flags.window-aconfig",
     package: "com.android.window.flags",
+    container: "system",
     srcs: ["core/java/android/window/flags/*.aconfig"],
 }
 
@@ -170,7 +172,9 @@
 // DeviceStateManager
 aconfig_declarations {
     name: "android.hardware.devicestate.feature.flags-aconfig",
+    exportable: true,
     package: "android.hardware.devicestate.feature.flags",
+    container: "system",
     srcs: ["core/java/android/hardware/devicestate/feature/*.aconfig"],
 }
 
@@ -183,7 +187,9 @@
 // Input
 aconfig_declarations {
     name: "com.android.hardware.input.input-aconfig",
+    exportable: true,
     package: "com.android.hardware.input",
+    container: "system",
     srcs: ["core/java/android/hardware/input/*.aconfig"],
 }
 
@@ -203,6 +209,7 @@
 aconfig_declarations {
     name: "com.android.text.flags-aconfig",
     package: "com.android.text.flags",
+    container: "system",
     srcs: ["core/java/android/text/flags/*.aconfig"],
 }
 
@@ -221,6 +228,7 @@
 aconfig_declarations {
     name: "android.location.flags-aconfig",
     package: "android.location.flags",
+    container: "system",
     srcs: [
         "location/java/android/location/flags/*.aconfig",
     ],
@@ -242,6 +250,7 @@
 aconfig_declarations {
     name: "android.nfc.flags-aconfig",
     package: "android.nfc",
+    container: "system",
     srcs: ["nfc/java/android/nfc/*.aconfig"],
 }
 
@@ -272,6 +281,7 @@
 aconfig_declarations {
     name: "android.security.flags-aconfig",
     package: "android.security",
+    container: "system",
     srcs: ["core/java/android/security/*.aconfig"],
 }
 
@@ -292,6 +302,7 @@
 aconfig_declarations {
     name: "android.app.usage.flags-aconfig",
     package: "android.app.usage",
+    container: "system",
     srcs: ["core/java/android/app/usage/*.aconfig"],
 }
 
@@ -339,6 +350,7 @@
     apex_available: [
         "//apex_available:platform",
         "com.android.mediaprovider",
+        "com.android.permission",
     ],
 }
 
@@ -374,6 +386,7 @@
 aconfig_declarations {
     name: "android.companion.virtualdevice.flags-aconfig",
     package: "android.companion.virtualdevice.flags",
+    container: "system",
     srcs: ["core/java/android/companion/virtual/flags/*.aconfig"],
 }
 
@@ -386,6 +399,7 @@
 aconfig_declarations {
     name: "android.companion.virtual.flags-aconfig",
     package: "android.companion.virtual.flags",
+    container: "system",
     srcs: ["core/java/android/companion/virtual/*.aconfig"],
 }
 
@@ -393,6 +407,7 @@
 aconfig_declarations {
     name: "android.view.inputmethod.flags-aconfig",
     package: "android.view.inputmethod",
+    container: "system",
     srcs: ["core/java/android/view/inputmethod/flags.aconfig"],
 }
 
@@ -406,6 +421,7 @@
 aconfig_declarations {
     name: "android.os.vibrator.flags-aconfig",
     package: "android.os.vibrator",
+    container: "system",
     srcs: ["core/java/android/os/vibrator/*.aconfig"],
 }
 
@@ -419,6 +435,7 @@
 aconfig_declarations {
     name: "android.view.flags-aconfig",
     package: "android.view.flags",
+    container: "system",
     srcs: ["core/java/android/view/flags/*.aconfig"],
 }
 
@@ -437,6 +454,7 @@
 aconfig_declarations {
     name: "android.view.accessibility.flags-aconfig",
     package: "android.view.accessibility",
+    container: "system",
     srcs: ["core/java/android/view/accessibility/flags/*.aconfig"],
 }
 
@@ -454,7 +472,9 @@
 // Hardware
 aconfig_declarations {
     name: "android.hardware.flags-aconfig",
+    exportable: true,
     package: "android.hardware.flags",
+    container: "system",
     srcs: ["core/java/android/hardware/flags/*.aconfig"],
 }
 
@@ -468,6 +488,7 @@
 aconfig_declarations {
     name: "android.widget.flags-aconfig",
     package: "android.widget.flags",
+    container: "system",
     srcs: ["core/java/android/widget/flags/*.aconfig"],
 }
 
@@ -487,6 +508,7 @@
 aconfig_declarations {
     name: "android.content.pm.flags-aconfig",
     package: "android.content.pm",
+    container: "system",
     srcs: ["core/java/android/content/pm/flags.aconfig"],
 }
 
@@ -507,6 +529,7 @@
 aconfig_declarations {
     name: "android.content.res.flags-aconfig",
     package: "android.content.res",
+    container: "system",
     srcs: ["core/java/android/content/res/*.aconfig"],
 }
 
@@ -527,6 +550,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"],
 }
 
@@ -546,7 +570,9 @@
 // Media Editing
 aconfig_declarations {
     name: "com.android.media.flags.editing-aconfig",
+    exportable: true,
     package: "com.android.media.editing.flags",
+    container: "system",
     srcs: [
         "media/java/android/media/flags/editing.aconfig",
     ],
@@ -562,6 +588,7 @@
 aconfig_declarations {
     name: "com.android.media.flags.projection-aconfig",
     package: "com.android.media.projection.flags",
+    container: "system",
     srcs: [
         "media/java/android/media/flags/projection.aconfig",
     ],
@@ -573,10 +600,27 @@
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
+// Media Performance
+aconfig_declarations {
+    name: "com.android.media.flags.performance-aconfig",
+    package: "com.android.media.performance.flags",
+    srcs: [
+        "media/java/android/media/flags/performance.aconfig",
+    ],
+}
+
+java_aconfig_library {
+    name: "com.android.media.flags.performance-aconfig-java",
+    aconfig_declarations: "com.android.media.flags.performance-aconfig",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
 // Media TV
 aconfig_declarations {
     name: "android.media.tv.flags-aconfig",
+    exportable: true,
     package: "android.media.tv.flags",
+    container: "system",
     srcs: ["media/java/android/media/tv/flags/media_tv.aconfig"],
 }
 
@@ -589,7 +633,9 @@
 // OnDeviceIntelligence
 aconfig_declarations {
     name: "android.app.ondeviceintelligence-aconfig",
+    exportable: true,
     package: "android.app.ondeviceintelligence.flags",
+    container: "system",
     srcs: ["core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig"],
 }
 
@@ -603,6 +649,7 @@
 aconfig_declarations {
     name: "android.permission.flags-aconfig",
     package: "android.permission.flags",
+    container: "system",
     srcs: ["core/java/android/permission/flags.aconfig"],
 }
 
@@ -622,6 +669,7 @@
 aconfig_declarations {
     name: "android.database.sqlite-aconfig",
     package: "android.database.sqlite",
+    container: "system",
     srcs: ["core/java/android/database/sqlite/*.aconfig"],
 }
 
@@ -640,7 +688,9 @@
 // Biometrics
 aconfig_declarations {
     name: "android.hardware.biometrics.flags-aconfig",
+    exportable: true,
     package: "android.hardware.biometrics",
+    container: "system",
     srcs: ["core/java/android/hardware/biometrics/flags.aconfig"],
 }
 
@@ -692,6 +742,7 @@
 aconfig_declarations {
     name: "android.multiuser.flags-aconfig",
     package: "android.multiuser",
+    container: "system",
     srcs: ["core/java/android/content/pm/multiuser.aconfig"],
 }
 
@@ -705,6 +756,7 @@
 aconfig_declarations {
     name: "android.app.flags-aconfig",
     package: "android.app",
+    container: "system",
     srcs: ["core/java/android/app/*.aconfig"],
 }
 
@@ -717,7 +769,9 @@
 // Broadcast Radio
 aconfig_declarations {
     name: "android.hardware.radio.flags-aconfig",
+    exportable: true,
     package: "android.hardware.radio",
+    container: "system",
     srcs: ["core/java/android/hardware/radio/*.aconfig"],
 }
 
@@ -731,6 +785,7 @@
 aconfig_declarations {
     name: "android.credentials.flags-aconfig",
     package: "android.credentials.flags",
+    container: "system",
     srcs: ["core/java/android/credentials/flags.aconfig"],
     exportable: true,
 }
@@ -751,7 +806,9 @@
 // Content Protection
 aconfig_declarations {
     name: "android.view.contentprotection.flags-aconfig",
+    exportable: true,
     package: "android.view.contentprotection.flags",
+    container: "system",
     srcs: ["core/java/android/view/contentprotection/flags/*.aconfig"],
 }
 
@@ -765,6 +822,7 @@
 aconfig_declarations {
     name: "com.android.server.flags.services-aconfig",
     package: "com.android.server.flags",
+    container: "system",
     srcs: ["services/core/java/com/android/server/flags/*.aconfig"],
 }
 
@@ -777,7 +835,9 @@
 // App prediction
 aconfig_declarations {
     name: "android.service.appprediction.flags-aconfig",
+    exportable: true,
     package: "android.service.appprediction.flags",
+    container: "system",
     srcs: ["core/java/android/service/appprediction/flags/*.aconfig"],
 }
 
@@ -790,7 +850,9 @@
 // Controls
 aconfig_declarations {
     name: "android.service.controls.flags-aconfig",
+    exportable: true,
     package: "android.service.controls.flags",
+    container: "system",
     srcs: ["core/java/android/service/controls/flags/*.aconfig"],
 }
 
@@ -803,7 +865,9 @@
 // Voice
 aconfig_declarations {
     name: "android.service.voice.flags-aconfig",
+    exportable: true,
     package: "android.service.voice.flags",
+    container: "system",
     srcs: ["core/java/android/service/voice/flags/*.aconfig"],
 }
 
@@ -817,6 +881,7 @@
 aconfig_declarations {
     name: "android.service.autofill.flags-aconfig",
     package: "android.service.autofill",
+    container: "system",
     srcs: [
         "services/autofill/bugfixes.aconfig",
         "services/autofill/features.aconfig",
@@ -832,7 +897,9 @@
 // Companion
 aconfig_declarations {
     name: "android.companion.flags-aconfig",
+    exportable: true,
     package: "android.companion",
+    container: "system",
     srcs: ["core/java/android/companion/*.aconfig"],
 }
 
@@ -845,7 +912,9 @@
 // Networking
 aconfig_declarations {
     name: "android.net.platform.flags-aconfig",
+    exportable: true,
     package: "android.net.platform.flags",
+    container: "system",
     srcs: ["core/java/android/net/flags.aconfig"],
     visibility: [":__subpackages__"],
 }
@@ -853,7 +922,9 @@
 // Thread network
 aconfig_declarations {
     name: "com.android.net.thread.platform.flags-aconfig",
+    exportable: true,
     package: "com.android.net.thread.platform.flags",
+    container: "system",
     srcs: ["core/java/android/net/thread/flags.aconfig"],
 }
 
@@ -874,6 +945,7 @@
 aconfig_declarations {
     name: "android.media.playback.flags-aconfig",
     package: "com.android.media.playback.flags",
+    container: "system",
     srcs: ["media/jni/playback_flags.aconfig"],
 }
 
@@ -892,6 +964,7 @@
 aconfig_declarations {
     name: "android.net.vcn.flags-aconfig",
     package: "android.net.vcn",
+    container: "system",
     srcs: ["core/java/android/net/vcn/*.aconfig"],
 }
 
@@ -905,6 +978,7 @@
 aconfig_declarations {
     name: "device_policy_aconfig_flags",
     package: "android.app.admin.flags",
+    container: "system",
     srcs: [
         "core/java/android/app/admin/flags/flags.aconfig",
     ],
@@ -932,6 +1006,7 @@
 aconfig_declarations {
     name: "android.service.chooser.flags-aconfig",
     package: "android.service.chooser",
+    container: "system",
     srcs: ["core/java/android/service/chooser/flags.aconfig"],
 }
 
@@ -950,6 +1025,8 @@
 aconfig_declarations {
     name: "framework-jobscheduler-job.flags-aconfig",
     package: "android.app.job",
+    container: "system",
+    exportable: true,
     srcs: ["apex/jobscheduler/framework/aconfig/job.aconfig"],
 }
 
@@ -963,6 +1040,7 @@
 aconfig_declarations {
     name: "android.service.dreams.flags-aconfig",
     package: "android.service.dreams",
+    container: "system",
     srcs: ["core/java/android/service/dreams/flags.aconfig"],
 }
 
@@ -1003,6 +1081,7 @@
 aconfig_declarations {
     name: "android.app.contextualsearch.flags-aconfig",
     package: "android.app.contextualsearch.flags",
+    container: "system",
     srcs: ["core/java/android/app/contextualsearch/flags.aconfig"],
 }
 
@@ -1015,7 +1094,9 @@
 // Smartspace
 aconfig_declarations {
     name: "android.app.smartspace.flags-aconfig",
+    exportable: true,
     package: "android.app.smartspace.flags",
+    container: "system",
     srcs: ["core/java/android/app/smartspace/flags.aconfig"],
 }
 
@@ -1036,6 +1117,7 @@
 aconfig_declarations {
     name: "android.view.contentcapture.flags-aconfig",
     package: "android.view.contentcapture.flags",
+    container: "system",
     srcs: ["core/java/android/view/contentcapture/flags/*.aconfig"],
 }
 
@@ -1048,7 +1130,9 @@
 // USB
 aconfig_declarations {
     name: "android.hardware.usb.flags-aconfig",
+    exportable: true,
     package: "android.hardware.usb.flags",
+    container: "system",
     srcs: ["core/java/android/hardware/usb/flags/*.aconfig"],
 }
 
@@ -1069,6 +1153,7 @@
 aconfig_declarations {
     name: "android.tracing.flags-aconfig",
     package: "android.tracing",
+    container: "system",
     srcs: ["core/java/android/tracing/flags.aconfig"],
 }
 
@@ -1087,6 +1172,7 @@
 aconfig_declarations {
     name: "android.appwidget.flags-aconfig",
     package: "android.appwidget.flags",
+    container: "system",
     srcs: ["core/java/android/appwidget/flags.aconfig"],
 }
 
@@ -1100,6 +1186,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"],
 }
 
@@ -1113,6 +1200,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",
@@ -1128,7 +1216,9 @@
 // Provider
 aconfig_declarations {
     name: "android.provider.flags-aconfig",
+    exportable: true,
     package: "android.provider",
+    container: "system",
     srcs: ["core/java/android/provider/*.aconfig"],
 }
 
@@ -1148,7 +1238,9 @@
 // Speech
 aconfig_declarations {
     name: "android.speech.flags-aconfig",
+    exportable: true,
     package: "android.speech.flags",
+    container: "system",
     srcs: ["core/java/android/speech/flags/*.aconfig"],
 }
 
@@ -1168,7 +1260,9 @@
 // Content
 aconfig_declarations {
     name: "android.content.flags-aconfig",
+    exportable: true,
     package: "android.content.flags",
+    container: "system",
     srcs: ["core/java/android/content/flags/flags.aconfig"],
 }
 
@@ -1182,6 +1276,7 @@
 aconfig_declarations {
     name: "android.adaptiveauth.flags-aconfig",
     package: "android.adaptiveauth",
+    container: "system",
     srcs: ["core/java/android/adaptiveauth/*.aconfig"],
 }
 
@@ -1194,7 +1289,9 @@
 // CrashRecovery Module
 aconfig_declarations {
     name: "android.crashrecovery.flags-aconfig",
+    exportable: true,
     package: "android.crashrecovery.flags",
+    container: "system",
     srcs: ["packages/CrashRecovery/aconfig/flags.aconfig"],
 }
 
@@ -1215,6 +1312,7 @@
 aconfig_declarations {
     name: "android.net.wifi.flags-aconfig",
     package: "android.net.wifi.flags",
+    container: "system",
     srcs: ["wifi/*.aconfig"],
 }
 
@@ -1232,7 +1330,9 @@
 // Wearable Sensing
 aconfig_declarations {
     name: "android.app.wearable.flags-aconfig",
+    exportable: true,
     package: "android.app.wearable",
+    container: "system",
     srcs: ["core/java/android/app/wearable/*.aconfig"],
 }
 
@@ -1245,6 +1345,7 @@
 aconfig_declarations {
     name: "com.android.internal.pm.pkg.component.flags-aconfig",
     package: "com.android.internal.pm.pkg.component.flags",
+    container: "system",
     srcs: ["core/java/com/android/internal/pm/pkg/component/flags/flags.aconfig"],
 }
 
@@ -1265,6 +1366,7 @@
 aconfig_declarations {
     name: "android.systemserver.flags-aconfig",
     package: "android.server",
+    container: "system",
     srcs: ["services/java/com/android/server/flags.aconfig"],
 }
 
diff --git a/Android.bp b/Android.bp
index 59e903e..4f715f8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -150,7 +150,6 @@
         ":framework-javastream-protos",
         ":statslog-framework-java-gen", // FrameworkStatsLog.java
         ":audio_policy_configuration_V7_0",
-        ":perfetto_trace_javastream_protos",
     ],
 }
 
@@ -389,7 +388,6 @@
         // TODO(b/120066492): remove gps_debug and protolog.conf.json when the build
         // system propagates "required" properly.
         "gps_debug.conf",
-        "core.protolog.pb",
         "framework-res",
         // any install dependencies should go into framework-minus-apex-install-dependencies
         // rather than here to avoid bloating incremental build time
@@ -426,6 +424,7 @@
         "audiopolicy-aidl-java",
         "sounddose-aidl-java",
         "modules-utils-expresslog",
+        "perfetto_trace_javastream_protos_jarjar",
     ],
 }
 
@@ -665,6 +664,16 @@
     visibility: ["//frameworks/base/api"],
 }
 
+java_library {
+    name: "perfetto_trace_javastream_protos_jarjar",
+    srcs: [
+        ":perfetto_trace_javastream_protos",
+    ],
+    jarjar_rules: ":framework-jarjar-rules",
+    sdk_version: "core_platform",
+    installable: false,
+}
+
 build = [
     "AconfigFlags.bp",
     "ProtoLibraries.bp",
diff --git a/Ravenwood.bp b/Ravenwood.bp
index 6237e3e..7c7c0e2 100644
--- a/Ravenwood.bp
+++ b/Ravenwood.bp
@@ -30,7 +30,7 @@
     name: "framework-minus-apex.ravenwood-base",
     tools: ["hoststubgen"],
     cmd: "$(location hoststubgen) " +
-        "@$(location ravenwood/ravenwood-standard-options.txt) " +
+        "@$(location ravenwood/texts/ravenwood-standard-options.txt) " +
 
         "--debug-log $(location hoststubgen_framework-minus-apex.log) " +
         "--stats-file $(location hoststubgen_framework-minus-apex_stats.csv) " +
@@ -41,13 +41,13 @@
         "--gen-input-dump-file $(location hoststubgen_dump.txt) " +
 
         "--in-jar $(location :framework-minus-apex-for-hoststubgen) " +
-        "--policy-override-file $(location ravenwood/framework-minus-apex-ravenwood-policies.txt) " +
-        "--annotation-allowed-classes-file $(location ravenwood/ravenwood-annotation-allowed-classes.txt) ",
+        "--policy-override-file $(location ravenwood/texts/framework-minus-apex-ravenwood-policies.txt) " +
+        "--annotation-allowed-classes-file $(location ravenwood/texts/ravenwood-annotation-allowed-classes.txt) ",
     srcs: [
         ":framework-minus-apex-for-hoststubgen",
-        "ravenwood/framework-minus-apex-ravenwood-policies.txt",
-        "ravenwood/ravenwood-standard-options.txt",
-        "ravenwood/ravenwood-annotation-allowed-classes.txt",
+        "ravenwood/texts/framework-minus-apex-ravenwood-policies.txt",
+        "ravenwood/texts/ravenwood-standard-options.txt",
+        "ravenwood/texts/ravenwood-annotation-allowed-classes.txt",
     ],
     out: [
         "ravenwood.jar",
@@ -104,7 +104,7 @@
     name: "services.core.ravenwood-base",
     tools: ["hoststubgen"],
     cmd: "$(location hoststubgen) " +
-        "@$(location ravenwood/ravenwood-standard-options.txt) " +
+        "@$(location ravenwood/texts/ravenwood-standard-options.txt) " +
 
         "--debug-log $(location hoststubgen_services.core.log) " +
         "--stats-file $(location hoststubgen_services.core_stats.csv) " +
@@ -115,13 +115,13 @@
         "--gen-input-dump-file $(location hoststubgen_dump.txt) " +
 
         "--in-jar $(location :services.core-for-hoststubgen) " +
-        "--policy-override-file $(location ravenwood/services.core-ravenwood-policies.txt) " +
-        "--annotation-allowed-classes-file $(location ravenwood/ravenwood-annotation-allowed-classes.txt) ",
+        "--policy-override-file $(location ravenwood/texts/services.core-ravenwood-policies.txt) " +
+        "--annotation-allowed-classes-file $(location ravenwood/texts/ravenwood-annotation-allowed-classes.txt) ",
     srcs: [
         ":services.core-for-hoststubgen",
-        "ravenwood/services.core-ravenwood-policies.txt",
-        "ravenwood/ravenwood-standard-options.txt",
-        "ravenwood/ravenwood-annotation-allowed-classes.txt",
+        "ravenwood/texts/services.core-ravenwood-policies.txt",
+        "ravenwood/texts/ravenwood-standard-options.txt",
+        "ravenwood/texts/ravenwood-annotation-allowed-classes.txt",
     ],
     out: [
         "ravenwood.jar",
@@ -168,6 +168,7 @@
         "services.core.ravenwood",
     ],
     jarjar_rules: ":ravenwood-services-jarjar-rules",
+    visibility: ["//visibility:private"],
 }
 
 java_library {
@@ -179,6 +180,7 @@
         "services.core.ravenwood",
     ],
     jarjar_rules: ":ravenwood-services-jarjar-rules",
+    visibility: ["//visibility:private"],
 }
 
 java_library {
diff --git a/apex/jobscheduler/OWNERS b/apex/jobscheduler/OWNERS
index 58434f1..22b6489 100644
--- a/apex/jobscheduler/OWNERS
+++ b/apex/jobscheduler/OWNERS
@@ -2,7 +2,6 @@
 ctate@google.com
 dplotnikov@google.com
 jji@google.com
-kwekua@google.com
 omakoto@google.com
 suprabh@google.com
 varunshah@google.com
diff --git a/apex/jobscheduler/framework/aconfig/job.aconfig b/apex/jobscheduler/framework/aconfig/job.aconfig
index 2c1a853..80db264 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/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index 60eb4ac..c74c48c 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -2054,8 +2054,8 @@
          * or in a state where launching an activity is allowed, as defined
          * <a href=
          * "https://developer.android.com/guide/components/activities/background-starts#exceptions">
-         * here</a>. Attempting to schedule one outside of these conditions will throw a
-         * {@link SecurityException}.
+         * here</a>. Attempting to schedule one outside of these conditions will return a
+         * {@link JobScheduler#RESULT_FAILURE}.
          *
          * <p>
          * This should <b>NOT</b> be used for automatic features.
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java b/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
index 36174c6..3c218421 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
@@ -19,8 +19,6 @@
 import android.annotation.SystemApi;
 import android.app.JobSchedulerImpl;
 import android.app.SystemServiceRegistry;
-import android.app.tare.EconomyManager;
-import android.app.tare.IEconomyManager;
 import android.content.Context;
 import android.os.DeviceIdleManager;
 import android.os.IDeviceIdleController;
@@ -58,8 +56,5 @@
         SystemServiceRegistry.registerContextAwareService(
                 Context.POWER_EXEMPTION_SERVICE, PowerExemptionManager.class,
                 PowerExemptionManager::new);
-        SystemServiceRegistry.registerStaticService(
-                Context.RESOURCE_ECONOMY_SERVICE, EconomyManager.class,
-                (b) -> new EconomyManager(IEconomyManager.Stub.asInterface(b)));
     }
 }
diff --git a/apex/jobscheduler/framework/java/android/app/job/OWNERS b/apex/jobscheduler/framework/java/android/app/job/OWNERS
index b4a45f5..0b1e559 100644
--- a/apex/jobscheduler/framework/java/android/app/job/OWNERS
+++ b/apex/jobscheduler/framework/java/android/app/job/OWNERS
@@ -4,4 +4,3 @@
 omakoto@google.com
 ctate@android.com
 ctate@google.com
-kwekua@google.com
diff --git a/apex/jobscheduler/framework/java/android/app/tare/EconomyManager.java b/apex/jobscheduler/framework/java/android/app/tare/EconomyManager.java
deleted file mode 100644
index 0bea028..0000000
--- a/apex/jobscheduler/framework/java/android/app/tare/EconomyManager.java
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.tare;
-
-import android.annotation.IntDef;
-import android.annotation.Nullable;
-import android.annotation.SystemService;
-import android.annotation.TestApi;
-import android.content.Context;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Provides access to the resource economy service.
- *
- * @hide
- */
-@TestApi
-@SystemService(Context.RESOURCE_ECONOMY_SERVICE)
-public class EconomyManager {
-    private static final String TAG = "TARE-" + EconomyManager.class.getSimpleName();
-
-    /**
-     * 1 ARC = 1 GIGA-CAKE!
-     *
-     * @hide
-     */
-    public static final long CAKE_IN_ARC = 1_000_000_000L;
-
-    /** @hide */
-    public static long arcToCake(int arcs) {
-        return arcs * CAKE_IN_ARC;
-    }
-
-    /**
-     * Parses a configuration string to get the value in cakes.
-     *
-     * @hide
-     */
-    public static long parseCreditValue(@Nullable final String val, final long defaultValCakes) {
-        String trunc;
-        if (val == null || (trunc = val.trim()).isEmpty()) {
-            return defaultValCakes;
-        }
-        long multiplier;
-        if (trunc.endsWith("c")) {
-            trunc = trunc.substring(0, trunc.length() - 1);
-            multiplier = 1;
-        } else if (trunc.endsWith("ck")) {
-            trunc = trunc.substring(0, trunc.length() - 2);
-            multiplier = 1;
-        } else if (trunc.endsWith("A")) {
-            trunc = trunc.substring(0, trunc.length() - 1);
-            multiplier = CAKE_IN_ARC;
-        } else if (trunc.endsWith("ARC")) {
-            trunc = trunc.substring(0, trunc.length() - 3);
-            multiplier = CAKE_IN_ARC;
-        } else {
-            // Don't risk using the wrong units
-            Log.e(TAG, "Couldn't determine units of credit value: " + val);
-            return defaultValCakes;
-        }
-
-        // Allow people to shorten notation (eg. Mc for Megacake).
-        if (trunc.endsWith("k")) {
-            trunc = trunc.substring(0, trunc.length() - 1);
-            multiplier *= 1_000;
-        } else if (trunc.endsWith("M")) {
-            trunc = trunc.substring(0, trunc.length() - 1);
-            multiplier *= 1_000_000;
-        } else if (trunc.endsWith("G")) {
-            trunc = trunc.substring(0, trunc.length() - 1);
-            multiplier *= 1_000_000_000;
-        }
-
-        try {
-            return Long.parseLong(trunc) * multiplier;
-        } catch (NumberFormatException e) {
-            Log.e(TAG, "Malformed config string: " + val + " to " + trunc, e);
-            return defaultValCakes;
-        }
-    }
-
-    /** @hide */
-    @TestApi
-    public static final int ENABLED_MODE_OFF = 0;
-    /** @hide */
-    public static final int ENABLED_MODE_ON = 1;
-    /**
-     * Go through the motions, tracking events, updating balances and other TARE state values,
-     * but don't use TARE to affect actual device behavior.
-     * @hide
-     */
-    @TestApi
-    public static final int ENABLED_MODE_SHADOW = 2;
-
-    /** @hide */
-    @IntDef(prefix = {"ENABLED_MODE_"}, value = {
-            ENABLED_MODE_OFF,
-            ENABLED_MODE_ON,
-            ENABLED_MODE_SHADOW,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface EnabledMode {
-    }
-
-    /** @hide */
-    public static String enabledModeToString(@EnabledMode int mode) {
-        switch (mode) {
-            case ENABLED_MODE_OFF: return "ENABLED_MODE_OFF";
-            case ENABLED_MODE_ON: return "ENABLED_MODE_ON";
-            case ENABLED_MODE_SHADOW: return "ENABLED_MODE_SHADOW";
-            default: return "ENABLED_MODE_" + mode;
-        }
-    }
-
-    /** @hide */
-    @TestApi
-    public static final String KEY_ENABLE_TARE_MODE = "enable_tare_mode";
-    /** @hide */
-    public static final String KEY_ENABLE_POLICY_ALARM = "enable_policy_alarm";
-    /** @hide */
-    public static final String KEY_ENABLE_POLICY_JOB_SCHEDULER = "enable_policy_job";
-    /** @hide */
-    public static final int DEFAULT_ENABLE_TARE_MODE = ENABLED_MODE_OFF;
-    /** @hide */
-    public static final boolean DEFAULT_ENABLE_POLICY_ALARM = true;
-    /** @hide */
-    public static final boolean DEFAULT_ENABLE_POLICY_JOB_SCHEDULER = true;
-
-    // Keys for AlarmManager TARE factors
-    /** @hide */
-    public static final String KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED =
-            "am_min_satiated_balance_exempted";
-    /** @hide */
-    public static final String KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP =
-            "am_min_satiated_balance_headless_system_app";
-    /** @hide */
-    public static final String KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP =
-            "am_min_satiated_balance_other_app";
-    /** @hide */
-    public static final String KEY_AM_MAX_SATIATED_BALANCE = "am_max_satiated_balance";
-    /** @hide */
-    public static final String KEY_AM_INITIAL_CONSUMPTION_LIMIT = "am_initial_consumption_limit";
-    /** @hide */
-    public static final String KEY_AM_MIN_CONSUMPTION_LIMIT = "am_minimum_consumption_limit";
-    /** @hide */
-    public static final String KEY_AM_MAX_CONSUMPTION_LIMIT = "am_maximum_consumption_limit";
-    // TODO: Add AlarmManager modifier keys
-    /** @hide */
-    public static final String KEY_AM_REWARD_TOP_ACTIVITY_INSTANT =
-            "am_reward_top_activity_instant";
-    /** @hide */
-    public static final String KEY_AM_REWARD_TOP_ACTIVITY_ONGOING =
-            "am_reward_top_activity_ongoing";
-    /** @hide */
-    public static final String KEY_AM_REWARD_TOP_ACTIVITY_MAX = "am_reward_top_activity_max";
-    /** @hide */
-    public static final String KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT =
-            "am_reward_notification_seen_instant";
-    /** @hide */
-    public static final String KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING =
-            "am_reward_notification_seen_ongoing";
-    /** @hide */
-    public static final String KEY_AM_REWARD_NOTIFICATION_SEEN_MAX =
-            "am_reward_notification_seen_max";
-    /** @hide */
-    public static final String KEY_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_INSTANT =
-            "am_reward_notification_seen_within_15_instant";
-    /** @hide */
-    public static final String KEY_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_ONGOING =
-            "am_reward_notification_seen_within_15_ongoing";
-    /** @hide */
-    public static final String KEY_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_MAX =
-            "am_reward_notification_seen_within_15_max";
-    /** @hide */
-    public static final String KEY_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT =
-            "am_reward_notification_interaction_instant";
-    /** @hide */
-    public static final String KEY_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING =
-            "am_reward_notification_interaction_ongoing";
-    /** @hide */
-    public static final String KEY_AM_REWARD_NOTIFICATION_INTERACTION_MAX =
-            "am_reward_notification_interaction_max";
-    /** @hide */
-    public static final String KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT =
-            "am_reward_widget_interaction_instant";
-    /** @hide */
-    public static final String KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING =
-            "am_reward_widget_interaction_ongoing";
-    /** @hide */
-    public static final String KEY_AM_REWARD_WIDGET_INTERACTION_MAX =
-            "am_reward_widget_interaction_max";
-    /** @hide */
-    public static final String KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT =
-            "am_reward_other_user_interaction_instant";
-    /** @hide */
-    public static final String KEY_AM_REWARD_OTHER_USER_INTERACTION_ONGOING =
-            "am_reward_other_user_interaction_ongoing";
-    /** @hide */
-    public static final String KEY_AM_REWARD_OTHER_USER_INTERACTION_MAX =
-            "am_reward_other_user_interaction_max";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP =
-            "am_action_alarm_allow_while_idle_exact_wakeup_ctp";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP =
-            "am_action_alarm_allow_while_idle_inexact_wakeup_ctp";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP =
-            "am_action_alarm_exact_wakeup_ctp";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP =
-            "am_action_alarm_inexact_wakeup_ctp";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP =
-            "am_action_alarm_allow_while_idle_exact_nonwakeup_ctp";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP =
-            "am_action_alarm_exact_nonwakeup_ctp";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP =
-            "am_action_alarm_allow_while_idle_inexact_nonwakeup_ctp";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP =
-            "am_action_alarm_inexact_nonwakeup_ctp";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP =
-            "am_action_alarm_alarmclock_ctp";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE =
-            "am_action_alarm_allow_while_idle_exact_wakeup_base_price";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE =
-            "am_action_alarm_allow_while_idle_inexact_wakeup_base_price";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE =
-            "am_action_alarm_exact_wakeup_base_price";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE =
-            "am_action_alarm_inexact_wakeup_base_price";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE =
-            "am_action_alarm_allow_while_idle_exact_nonwakeup_base_price";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE =
-            "am_action_alarm_exact_nonwakeup_base_price";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE =
-            "am_action_alarm_allow_while_idle_inexact_nonwakeup_base_price";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE =
-            "am_action_alarm_inexact_nonwakeup_base_price";
-    /** @hide */
-    public static final String KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE =
-            "am_action_alarm_alarmclock_base_price";
-
-// Keys for JobScheduler TARE factors
-    /** @hide */
-    public static final String KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED =
-            "js_min_satiated_balance_exempted";
-    /** @hide */
-    public static final String KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP =
-            "js_min_satiated_balance_headless_system_app";
-    /** @hide */
-    public static final String KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP =
-            "js_min_satiated_balance_other_app";
-    /** @hide */
-    public static final String KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER =
-            "js_min_satiated_balance_increment_updater";
-    /** @hide */
-    public static final String KEY_JS_MAX_SATIATED_BALANCE =
-            "js_max_satiated_balance";
-    /** @hide */
-    public static final String KEY_JS_INITIAL_CONSUMPTION_LIMIT = "js_initial_consumption_limit";
-    /** @hide */
-    public static final String KEY_JS_MIN_CONSUMPTION_LIMIT = "js_minimum_consumption_limit";
-    /** @hide */
-    public static final String KEY_JS_MAX_CONSUMPTION_LIMIT = "js_maximum_consumption_limit";
-    // TODO: Add JobScheduler modifier keys
-    /** @hide */
-    public static final String KEY_JS_REWARD_APP_INSTALL_INSTANT =
-            "js_reward_app_install_instant";
-    /** @hide */
-    public static final String KEY_JS_REWARD_APP_INSTALL_ONGOING =
-            "js_reward_app_install_ongoing";
-    /** @hide */
-    public static final String KEY_JS_REWARD_APP_INSTALL_MAX =
-            "js_reward_app_install_max";
-    /** @hide */
-    public static final String KEY_JS_REWARD_TOP_ACTIVITY_INSTANT =
-            "js_reward_top_activity_instant";
-    /** @hide */
-    public static final String KEY_JS_REWARD_TOP_ACTIVITY_ONGOING =
-            "js_reward_top_activity_ongoing";
-    /** @hide */
-    public static final String KEY_JS_REWARD_TOP_ACTIVITY_MAX =
-            "js_reward_top_activity_max";
-    /** @hide */
-    public static final String KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT =
-            "js_reward_notification_seen_instant";
-    /** @hide */
-    public static final String KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING =
-            "js_reward_notification_seen_ongoing";
-    /** @hide */
-    public static final String KEY_JS_REWARD_NOTIFICATION_SEEN_MAX =
-            "js_reward_notification_seen_max";
-    /** @hide */
-    public static final String KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT =
-            "js_reward_notification_interaction_instant";
-    /** @hide */
-    public static final String KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING =
-            "js_reward_notification_interaction_ongoing";
-    /** @hide */
-    public static final String KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX =
-            "js_reward_notification_interaction_max";
-    /** @hide */
-    public static final String KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT =
-            "js_reward_widget_interaction_instant";
-    /** @hide */
-    public static final String KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING =
-            "js_reward_widget_interaction_ongoing";
-    /** @hide */
-    public static final String KEY_JS_REWARD_WIDGET_INTERACTION_MAX =
-            "js_reward_widget_interaction_max";
-    /** @hide */
-    public static final String KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT =
-            "js_reward_other_user_interaction_instant";
-    /** @hide */
-    public static final String KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING =
-            "js_reward_other_user_interaction_ongoing";
-    /** @hide */
-    public static final String KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX =
-            "js_reward_other_user_interaction_max";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_MAX_START_CTP = "js_action_job_max_start_ctp";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_MAX_RUNNING_CTP = "js_action_job_max_running_ctp";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_HIGH_START_CTP = "js_action_job_high_start_ctp";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP =
-            "js_action_job_high_running_ctp";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_DEFAULT_START_CTP =
-            "js_action_job_default_start_ctp";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP =
-            "js_action_job_default_running_ctp";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_LOW_START_CTP = "js_action_job_low_start_ctp";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_LOW_RUNNING_CTP = "js_action_job_low_running_ctp";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_MIN_START_CTP = "js_action_job_min_start_ctp";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_MIN_RUNNING_CTP = "js_action_job_min_running_ctp";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP =
-            "js_action_job_timeout_penalty_ctp";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE =
-            "js_action_job_max_start_base_price";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE =
-            "js_action_job_max_running_base_price";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE =
-            "js_action_job_high_start_base_price";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE =
-            "js_action_job_high_running_base_price";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE =
-            "js_action_job_default_start_base_price";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE =
-            "js_action_job_default_running_base_price";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE =
-            "js_action_job_low_start_base_price";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE =
-            "js_action_job_low_running_base_price";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE =
-            "js_action_job_min_start_base_price";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE =
-            "js_action_job_min_running_base_price";
-    /** @hide */
-    public static final String KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE =
-            "js_action_job_timeout_penalty_base_price";
-
-    // Default values AlarmManager factors
-    /** @hide */
-    public static final long DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES = arcToCake(500);
-    /** @hide */
-    public static final long DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES =
-            arcToCake(256);
-    /** @hide */
-    public static final long DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES = arcToCake(160);
-    /** @hide */
-    public static final long DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES = arcToCake(960);
-    /** @hide */
-    public static final long DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES = arcToCake(2880);
-    /** @hide */
-    public static final long DEFAULT_AM_MIN_CONSUMPTION_LIMIT_CAKES = arcToCake(1440);
-    /** @hide */
-    public static final long DEFAULT_AM_MAX_CONSUMPTION_LIMIT_CAKES = arcToCake(15_000);
-    // TODO: add AlarmManager modifier default values
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT_CAKES = arcToCake(0);
-    /** @hide */
-    // 10 megacakes = .01 ARC
-    public static final long DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES = 10_000_000;
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES = arcToCake(500);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES = arcToCake(3);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES = arcToCake(0);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES = arcToCake(60);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_INSTANT_CAKES =
-            arcToCake(5);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_ONGOING_CAKES =
-            arcToCake(0);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_NOTIFICATION_SEEN_WITHIN_15_MAX_CAKES =
-            arcToCake(500);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES =
-            arcToCake(5);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES =
-            arcToCake(0);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES = arcToCake(500);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES = arcToCake(10);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES = arcToCake(0);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES = arcToCake(500);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES = arcToCake(10);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES = arcToCake(0);
-    /** @hide */
-    public static final long DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES = arcToCake(500);
-    /** @hide */
-    public static final long DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES =
-            arcToCake(3);
-    /** @hide */
-    public static final long DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES =
-            arcToCake(3);
-    /** @hide */
-    public static final long DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES = arcToCake(3);
-    /** @hide */
-    public static final long DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES = arcToCake(3);
-    /** @hide */
-    public static final long DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES =
-            arcToCake(1);
-    /** @hide */
-    public static final long DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES = arcToCake(1);
-    /** @hide */
-    public static final long DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES =
-            arcToCake(1);
-    /** @hide */
-    public static final long DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES = arcToCake(1);
-    /** @hide */
-    public static final long DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES = arcToCake(5);
-    /** @hide */
-    public static final long
-            DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES = arcToCake(5);
-    /** @hide */
-    public static final long
-            DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES = arcToCake(4);
-    /** @hide */
-    public static final long DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES = arcToCake(4);
-    /** @hide */
-    public static final long DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE_CAKES = arcToCake(3);
-    /** @hide */
-    public static final long
-            DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE_CAKES =
-            arcToCake(3);
-    /** @hide */
-    public static final long DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE_CAKES =
-            arcToCake(2);
-    /** @hide */
-    public static final long
-            DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES =
-            arcToCake(2);
-    /** @hide */
-    public static final long DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES =
-            arcToCake(1);
-    /** @hide */
-    public static final long DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES = arcToCake(10);
-
-    // Default values JobScheduler factors
-    // TODO: add time_since_usage variable to min satiated balance factors
-    /** @hide */
-    public static final long DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES = arcToCake(15000);
-    /** @hide */
-    public static final long DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES =
-            arcToCake(7500);
-    /** @hide */
-    public static final long DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES = arcToCake(2000);
-    /** @hide */
-    public static final long DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES = arcToCake(60000);
-    /** @hide */
-    public static final long DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES = arcToCake(29_000);
-    /** @hide */
-    public static final long DEFAULT_JS_MIN_CONSUMPTION_LIMIT_CAKES = arcToCake(17_000);
-    /** @hide */
-    // TODO: set maximum limit based on device type (phone vs tablet vs etc) + battery size
-    public static final long DEFAULT_JS_MAX_CONSUMPTION_LIMIT_CAKES = arcToCake(250_000);
-    // TODO: add JobScheduler modifier default values
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_APP_INSTALL_INSTANT_CAKES = arcToCake(408);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_APP_INSTALL_ONGOING_CAKES = arcToCake(0);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_APP_INSTALL_MAX_CAKES = arcToCake(4000);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES = arcToCake(0);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES = CAKE_IN_ARC / 2;
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES = arcToCake(15000);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES = arcToCake(1);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES = arcToCake(0);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES = arcToCake(10);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES =
-            arcToCake(5);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES =
-            arcToCake(0);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES = arcToCake(5000);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES = arcToCake(10);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES = arcToCake(0);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES = arcToCake(5000);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES = arcToCake(10);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES = arcToCake(0);
-    /** @hide */
-    public static final long DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES = arcToCake(5000);
-    /**
-     * How many credits to increase the updating app's min satiated balance by for each app that it
-     * is responsible for updating.
-     * @hide
-     */
-    public static final long DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES =
-            // Research indicates that the median time between popular app updates is 13-14 days,
-            // so adjust by 14 to amortize over that time.
-            DEFAULT_JS_REWARD_APP_INSTALL_INSTANT_CAKES / 14;
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES = arcToCake(3);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES = arcToCake(2);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES = arcToCake(3);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES = arcToCake(2);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES = arcToCake(3);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES = arcToCake(2);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES = arcToCake(3);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES = arcToCake(2);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES = arcToCake(3);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES = arcToCake(2);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES = arcToCake(30);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES = arcToCake(10);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES = arcToCake(5);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES = arcToCake(8);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES = arcToCake(4);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES = arcToCake(6);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES = arcToCake(3);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES = arcToCake(4);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES = arcToCake(2);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES = arcToCake(2);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES = arcToCake(1);
-    /** @hide */
-    public static final long DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES = arcToCake(60);
-
-    //////// APIs below ////////
-
-    private final IEconomyManager mService;
-
-    /** @hide */
-    public EconomyManager(IEconomyManager service) {
-        mService = service;
-    }
-
-    /**
-     * Returns the current enabled status of TARE.
-     * @hide
-     */
-    @EnabledMode
-    @TestApi
-    public int getEnabledMode() {
-        try {
-            return mService.getEnabledMode();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-}
diff --git a/apex/jobscheduler/framework/java/android/app/tare/OWNERS b/apex/jobscheduler/framework/java/android/app/tare/OWNERS
deleted file mode 100644
index 217a5ed..0000000
--- a/apex/jobscheduler/framework/java/android/app/tare/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include /apex/jobscheduler/service/java/com/android/server/tare/OWNERS
\ No newline at end of file
diff --git a/apex/jobscheduler/service/aconfig/Android.bp b/apex/jobscheduler/service/aconfig/Android.bp
index 4db39dc..859c67a 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",
     ],
@@ -32,6 +34,7 @@
 aconfig_declarations {
     name: "alarm_flags",
     package: "com.android.server.alarm",
+    container: "system",
     srcs: ["alarm.aconfig"],
 }
 
diff --git a/apex/jobscheduler/service/aconfig/alarm.aconfig b/apex/jobscheduler/service/aconfig/alarm.aconfig
index bb0f3cb..d3068d7 100644
--- a/apex/jobscheduler/service/aconfig/alarm.aconfig
+++ b/apex/jobscheduler/service/aconfig/alarm.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.alarm"
+container: "system"
 
 flag {
     name: "use_frozen_state_to_drop_listener_alarms"
diff --git a/apex/jobscheduler/service/aconfig/device_idle.aconfig b/apex/jobscheduler/service/aconfig/device_idle.aconfig
index e4cb5ad..e8c99b1 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 5e6d377..75e2efd2 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: "batch_active_bucket_jobs"
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
index 6f8014f..7958d81 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/Alarm.java
@@ -45,7 +45,7 @@
  */
 class Alarm {
     @VisibleForTesting
-    public static final int NUM_POLICIES = 5;
+    public static final int NUM_POLICIES = 4;
     /**
      * Index used to store the time the alarm was requested to expire. To be used with
      * {@link #setPolicyElapsed(int, long)}.
@@ -69,12 +69,6 @@
     public static final int BATTERY_SAVER_POLICY_INDEX = 3;
 
     /**
-     * Index used to store the earliest time the alarm can expire based on TARE policy.
-     * To be used with {@link #setPolicyElapsed(int, long)}.
-     */
-    public static final int TARE_POLICY_INDEX = 4;
-
-    /**
      * Reason to use for inexact alarms.
      */
     static final int EXACT_ALLOW_REASON_NOT_APPLICABLE = -1;
@@ -278,8 +272,6 @@
                 return "device_idle";
             case BATTERY_SAVER_POLICY_INDEX:
                 return "battery_saver";
-            case TARE_POLICY_INDEX:
-                return "tare";
             default:
                 return "--unknown(" + index + ")--";
         }
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 154b2d7..f9c8e0b 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -57,7 +57,6 @@
 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_POLICY_PERMISSION;
 import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_PRIORITIZED;
 import static com.android.server.alarm.Alarm.REQUESTER_POLICY_INDEX;
-import static com.android.server.alarm.Alarm.TARE_POLICY_INDEX;
 import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED;
 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_ALARM_CANCELLED;
 import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_DATA_CLEARED;
@@ -88,7 +87,6 @@
 import android.app.PendingIntent;
 import android.app.compat.CompatChanges;
 import android.app.role.RoleManager;
-import android.app.tare.EconomyManager;
 import android.app.usage.UsageStatsManager;
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.BroadcastReceiver;
@@ -137,7 +135,6 @@
 import android.util.LongArrayQueue;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.util.SparseArrayMap;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 import android.util.SparseLongArray;
@@ -171,8 +168,6 @@
 import com.android.server.pm.permission.PermissionManagerService;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
 import com.android.server.pm.pkg.AndroidPackage;
-import com.android.server.tare.AlarmManagerEconomicPolicy;
-import com.android.server.tare.EconomyManagerInternal;
 import com.android.server.usage.AppStandbyInternal;
 import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
 
@@ -222,7 +217,6 @@
     static final boolean DEBUG_WAKELOCK = localLOGV || false;
     static final boolean DEBUG_BG_LIMIT = localLOGV || false;
     static final boolean DEBUG_STANDBY = localLOGV || false;
-    static final boolean DEBUG_TARE = localLOGV || false;
     static final boolean RECORD_ALARMS_IN_HISTORY = true;
     static final boolean RECORD_DEVICE_IDLE_ALARMS = false;
 
@@ -259,7 +253,6 @@
     DeviceIdleInternal mLocalDeviceIdleController;
     private UsageStatsManagerInternal mUsageStatsManagerInternal;
     private ActivityManagerInternal mActivityManagerInternal;
-    private final EconomyManagerInternal mEconomyManagerInternal;
     private PackageManagerInternal mPackageManagerInternal;
     private BatteryStatsInternal mBatteryStatsInternal;
     private RoleManager mRoleManager;
@@ -280,14 +273,6 @@
     @GuardedBy("mLock")
     SparseIntArray mLastOpScheduleExactAlarm = new SparseIntArray();
 
-    /**
-     * Local cache of the ability of each userId-pkg to afford the various bills we're tracking for
-     * them.
-     */
-    @GuardedBy("mLock")
-    private final SparseArrayMap<String, ArrayMap<EconomyManagerInternal.ActionBill, Boolean>>
-            mAffordabilityCache = new SparseArrayMap<>();
-
     // List of alarms per uid deferred due to user applied background restrictions on the source app
     SparseArray<ArrayList<Alarm>> mPendingBackgroundAlarms = new SparseArray<>();
 
@@ -361,13 +346,11 @@
     interface Stats {
         int REORDER_ALARMS_FOR_STANDBY = 0;
         int HAS_SCHEDULE_EXACT_ALARM = 1;
-        int REORDER_ALARMS_FOR_TARE = 2;
     }
 
     private final StatLogger mStatLogger = new StatLogger("Alarm manager stats", new String[]{
             "REORDER_ALARMS_FOR_STANDBY",
             "HAS_SCHEDULE_EXACT_ALARM",
-            "REORDER_ALARMS_FOR_TARE",
     });
 
     BroadcastOptions mOptsWithFgs = makeBasicAlarmBroadcastOptions();
@@ -686,8 +669,7 @@
      * holding the AlarmManagerService.mLock lock.
      */
     @VisibleForTesting
-    final class Constants implements DeviceConfig.OnPropertiesChangedListener,
-            EconomyManagerInternal.TareStateChangeListener {
+    final class Constants implements DeviceConfig.OnPropertiesChangedListener {
         // Key names stored in the settings value.
         @VisibleForTesting
         static final String KEY_MIN_FUTURITY = "min_futurity";
@@ -858,9 +840,6 @@
          */
         public long MAX_DEVICE_IDLE_FUZZ = DEFAULT_MAX_DEVICE_IDLE_FUZZ;
 
-        public int USE_TARE_POLICY = EconomyManager.DEFAULT_ENABLE_POLICY_ALARM
-                ? EconomyManager.DEFAULT_ENABLE_TARE_MODE : EconomyManager.ENABLED_MODE_OFF;
-
         /**
          * The amount of temporary reserve quota to give apps on receiving the
          * {@link AppIdleStateChangeListener#triggerTemporaryQuotaBump(String, int)} callback
@@ -900,13 +879,7 @@
 
         public void start() {
             mInjector.registerDeviceConfigListener(this);
-            final EconomyManagerInternal economyManagerInternal =
-                    LocalServices.getService(EconomyManagerInternal.class);
-            economyManagerInternal.registerTareStateChangeListener(this,
-                    AlarmManagerEconomicPolicy.POLICY_ALARM);
             onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_ALARM_MANAGER));
-            updateTareSettings(
-                    economyManagerInternal.getEnabledMode(AlarmManagerEconomicPolicy.POLICY_ALARM));
         }
 
         @SuppressLint("MissingPermission")
@@ -1064,42 +1037,6 @@
             }
         }
 
-        @Override
-        public void onTareEnabledModeChanged(@EconomyManager.EnabledMode int enabledMode) {
-            updateTareSettings(enabledMode);
-        }
-
-        private void updateTareSettings(int enabledMode) {
-            synchronized (mLock) {
-                if (USE_TARE_POLICY != enabledMode) {
-                    USE_TARE_POLICY = enabledMode;
-                    final boolean changed = mAlarmStore.updateAlarmDeliveries(alarm -> {
-                        final boolean standbyChanged = adjustDeliveryTimeBasedOnBucketLocked(alarm);
-                        final boolean tareChanged = adjustDeliveryTimeBasedOnTareLocked(alarm);
-                        if (USE_TARE_POLICY == EconomyManager.ENABLED_MODE_ON) {
-                            // Only register listeners if we're going to be acting on the policy.
-                            registerTareListener(alarm);
-                        } else {
-                            mEconomyManagerInternal.unregisterAffordabilityChangeListener(
-                                    UserHandle.getUserId(alarm.uid), alarm.sourcePackage,
-                                    mAffordabilityChangeListener,
-                                    TareBill.getAppropriateBill(alarm));
-                        }
-                        return standbyChanged || tareChanged;
-                    });
-                    if (USE_TARE_POLICY != EconomyManager.ENABLED_MODE_ON) {
-                        // Remove the cached values so we don't accidentally use them when TARE is
-                        // re-enabled.
-                        mAffordabilityCache.clear();
-                    }
-                    if (changed) {
-                        rescheduleKernelAlarmsLocked();
-                        updateNextAlarmClockLocked();
-                    }
-                }
-            }
-        }
-
         private void updateDeviceIdleFuzzBoundaries() {
             final DeviceConfig.Properties properties = DeviceConfig.getProperties(
                     DeviceConfig.NAMESPACE_ALARM_MANAGER,
@@ -1255,10 +1192,6 @@
             TimeUtils.formatDuration(MAX_DEVICE_IDLE_FUZZ, pw);
             pw.println();
 
-            pw.print(Settings.Global.ENABLE_TARE,
-                    EconomyManager.enabledModeToString(USE_TARE_POLICY));
-            pw.println();
-
             pw.print(KEY_TEMPORARY_QUOTA_BUMP, TEMPORARY_QUOTA_BUMP);
             pw.println();
 
@@ -1394,7 +1327,6 @@
     AlarmManagerService(Context context, Injector injector) {
         super(context);
         mInjector = injector;
-        mEconomyManagerInternal = LocalServices.getService(EconomyManagerInternal.class);
     }
 
     public AlarmManagerService(Context context) {
@@ -1501,29 +1433,6 @@
         return changed;
     }
 
-    /**
-     * Recalculates alarm send times based on TARE wealth.
-     *
-     * @param targetPackages [Package, User] pairs for which alarms need to be re-evaluated,
-     *                       null indicates all
-     * @return True if there was any reordering done to the current list.
-     */
-    boolean reorderAlarmsBasedOnTare(ArraySet<UserPackage> targetPackages) {
-        final long start = mStatLogger.getTime();
-
-        final boolean changed = mAlarmStore.updateAlarmDeliveries(a -> {
-            final UserPackage userPackage =
-                    UserPackage.of(UserHandle.getUserId(a.creatorUid), a.sourcePackage);
-            if (targetPackages != null && !targetPackages.contains(userPackage)) {
-                return false;
-            }
-            return adjustDeliveryTimeBasedOnTareLocked(a);
-        });
-
-        mStatLogger.logDurationStat(Stats.REORDER_ALARMS_FOR_TARE, start);
-        return changed;
-    }
-
     private boolean restoreRequestedTime(Alarm a) {
         return a.setPolicyElapsed(REQUESTER_POLICY_INDEX, convertToElapsed(a.origWhen, a.type));
     }
@@ -2581,8 +2490,7 @@
      */
     private boolean adjustDeliveryTimeBasedOnBucketLocked(Alarm alarm) {
         final long nowElapsed = mInjector.getElapsedRealtimeMillis();
-        if (mConstants.USE_TARE_POLICY == EconomyManager.ENABLED_MODE_ON
-                || isExemptFromAppStandby(alarm) || mAppStandbyParole) {
+        if (isExemptFromAppStandby(alarm) || mAppStandbyParole) {
             return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed);
         }
 
@@ -2633,60 +2541,6 @@
         return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed);
     }
 
-    /**
-     * Adjusts the alarm's policy time for TARE.
-     *
-     * @param alarm The alarm to update.
-     * @return {@code true} if the actual delivery time of the given alarm was updated due to
-     * adjustments made in this call.
-     */
-    private boolean adjustDeliveryTimeBasedOnTareLocked(Alarm alarm) {
-        final long nowElapsed = mInjector.getElapsedRealtimeMillis();
-        if (mConstants.USE_TARE_POLICY != EconomyManager.ENABLED_MODE_ON
-                || isExemptFromTare(alarm) || hasEnoughWealthLocked(alarm)) {
-            return alarm.setPolicyElapsed(TARE_POLICY_INDEX, nowElapsed);
-        }
-
-        // Not enough wealth. Just keep deferring indefinitely till the quota changes.
-        return alarm.setPolicyElapsed(TARE_POLICY_INDEX, nowElapsed + INDEFINITE_DELAY);
-    }
-
-    private void registerTareListener(Alarm alarm) {
-        if (mConstants.USE_TARE_POLICY != EconomyManager.ENABLED_MODE_ON) {
-            // Only register listeners if we're going to be acting on the policy.
-            return;
-        }
-        mEconomyManagerInternal.registerAffordabilityChangeListener(
-                UserHandle.getUserId(alarm.creatorUid), alarm.sourcePackage,
-                mAffordabilityChangeListener, TareBill.getAppropriateBill(alarm));
-    }
-
-    /** Unregister the TARE listener associated with the alarm if it's no longer needed. */
-    @GuardedBy("mLock")
-    private void maybeUnregisterTareListenerLocked(Alarm alarm) {
-        if (mConstants.USE_TARE_POLICY != EconomyManager.ENABLED_MODE_ON) {
-            return;
-        }
-        final EconomyManagerInternal.ActionBill bill = TareBill.getAppropriateBill(alarm);
-        final Predicate<Alarm> isSameAlarmTypeForSameApp = (a) ->
-                alarm.creatorUid == a.creatorUid
-                        && alarm.sourcePackage.equals(a.sourcePackage)
-                        && bill.equals(TareBill.getAppropriateBill(a));
-        if (mAlarmStore.getCount(isSameAlarmTypeForSameApp) == 0) {
-            final int userId = UserHandle.getUserId(alarm.creatorUid);
-            mEconomyManagerInternal.unregisterAffordabilityChangeListener(
-                    userId, alarm.sourcePackage,
-                    mAffordabilityChangeListener, bill);
-            // Remove the cached value so we don't accidentally use it when the app
-            // schedules a new alarm.
-            ArrayMap<EconomyManagerInternal.ActionBill, Boolean> actionAffordability =
-                    mAffordabilityCache.get(userId, alarm.sourcePackage);
-            if (actionAffordability != null) {
-                actionAffordability.remove(bill);
-            }
-        }
-    }
-
     @GuardedBy("mLock")
     private void setImplLocked(Alarm a) {
         if ((a.flags & AlarmManager.FLAG_IDLE_UNTIL) != 0) {
@@ -2734,8 +2588,6 @@
         }
         adjustDeliveryTimeBasedOnBatterySaver(a);
         adjustDeliveryTimeBasedOnBucketLocked(a);
-        adjustDeliveryTimeBasedOnTareLocked(a);
-        registerTareListener(a);
         mAlarmStore.add(a);
         rescheduleKernelAlarmsLocked();
         updateNextAlarmClockLocked();
@@ -3168,37 +3020,8 @@
             pw.println();
             pw.println();
 
-            if (mConstants.USE_TARE_POLICY == EconomyManager.ENABLED_MODE_ON) {
-                pw.println("TARE details:");
-                pw.increaseIndent();
-
-                pw.println("Affordability cache:");
-                pw.increaseIndent();
-                mAffordabilityCache.forEach((userId, pkgName, billMap) -> {
-                    final int numBills = billMap.size();
-                    if (numBills > 0) {
-                        pw.print(userId);
-                        pw.print(":");
-                        pw.print(pkgName);
-                        pw.println(":");
-
-                        pw.increaseIndent();
-                        for (int i = 0; i < numBills; ++i) {
-                            pw.print(TareBill.getName(billMap.keyAt(i)));
-                            pw.print(": ");
-                            pw.println(billMap.valueAt(i));
-                        }
-                        pw.decreaseIndent();
-                    }
-                });
-                pw.decreaseIndent();
-
-                pw.decreaseIndent();
-                pw.println();
-            } else {
-                pw.println("App Standby Parole: " + mAppStandbyParole);
-                pw.println();
-            }
+            pw.println("App Standby Parole: " + mAppStandbyParole);
+            pw.println();
 
             if (mAppStateTracker != null) {
                 mAppStateTracker.dump(pw);
@@ -4136,7 +3959,6 @@
                 mRemovalHistory.put(removed.uid, bufferForUid);
             }
             bufferForUid.append(new RemovedAlarm(removed, reason, nowRtc, nowElapsed));
-            maybeUnregisterTareListenerLocked(removed);
         }
 
         if (removedFromStore) {
@@ -4496,11 +4318,6 @@
                             alarm.uid, alarm.statsTag);
                 }
                 mDeliveryTracker.deliverLocked(alarm, nowELAPSED);
-                reportAlarmEventToTare(alarm);
-                if (alarm.repeatInterval <= 0) {
-                    // Don't bother trying to unregister for a repeating alarm.
-                    maybeUnregisterTareListenerLocked(alarm);
-                }
             } catch (RuntimeException e) {
                 Slog.w(TAG, "Failure sending alarm.", e);
             }
@@ -4509,52 +4326,6 @@
         }
     }
 
-    private void reportAlarmEventToTare(Alarm alarm) {
-        // Don't bother reporting events if TARE is completely off.
-        if (mConstants.USE_TARE_POLICY == EconomyManager.ENABLED_MODE_OFF) {
-            return;
-        }
-        final boolean allowWhileIdle =
-                (alarm.flags & (FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED | FLAG_ALLOW_WHILE_IDLE)) != 0;
-        final int action;
-        if (alarm.alarmClock != null) {
-            action = AlarmManagerEconomicPolicy.ACTION_ALARM_CLOCK;
-        } else if (alarm.wakeup) {
-            if (alarm.windowLength == 0) {
-                if (allowWhileIdle) {
-                    action = AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE;
-                } else {
-                    action = AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_EXACT;
-                }
-            } else {
-                if (allowWhileIdle) {
-                    action =
-                            AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE;
-                } else {
-                    action = AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_INEXACT;
-                }
-            }
-        } else {
-            if (alarm.windowLength == 0) {
-                if (allowWhileIdle) {
-                    action = AlarmManagerEconomicPolicy
-                            .ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE;
-                } else {
-                    action = AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_EXACT;
-                }
-            } else {
-                if (allowWhileIdle) {
-                    action = AlarmManagerEconomicPolicy
-                            .ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE;
-                } else {
-                    action = AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_INEXACT;
-                }
-            }
-        }
-        mEconomyManagerInternal.noteInstantaneousEvent(
-                UserHandle.getUserId(alarm.creatorUid), alarm.sourcePackage, action, null);
-    }
-
     @VisibleForTesting
     static boolean isExemptFromAppStandby(Alarm a) {
         return a.alarmClock != null || UserHandle.isCore(a.creatorUid)
@@ -4562,12 +4333,6 @@
     }
 
     @VisibleForTesting
-    static boolean isExemptFromTare(Alarm a) {
-        return a.alarmClock != null || UserHandle.isCore(a.creatorUid)
-                || (a.flags & (FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED)) != 0;
-    }
-
-    @VisibleForTesting
     static class Injector {
         private long mNativeData;
         private Context mContext;
@@ -4814,13 +4579,7 @@
                                     wakeupUids.add(a.uid);
                                     increment(wakeupCountsPerUid, a.uid);
                                 }
-                                if (mConstants.USE_TARE_POLICY == EconomyManager.ENABLED_MODE_ON) {
-                                    if (!isExemptFromTare(a)) {
-                                        triggerPackages.add(UserPackage.of(
-                                                UserHandle.getUserId(a.creatorUid),
-                                                a.sourcePackage));
-                                    }
-                                } else if (!isExemptFromAppStandby(a)) {
+                                if (!isExemptFromAppStandby(a)) {
                                     triggerPackages.add(UserPackage.of(
                                             UserHandle.getUserId(a.creatorUid), a.sourcePackage));
                                 }
@@ -4831,11 +4590,7 @@
                             }
                             deliverAlarmsLocked(triggerList, nowELAPSED);
                             mTemporaryQuotaReserve.cleanUpExpiredQuotas(nowELAPSED);
-                            if (mConstants.USE_TARE_POLICY == EconomyManager.ENABLED_MODE_ON) {
-                                reorderAlarmsBasedOnTare(triggerPackages);
-                            } else {
-                                reorderAlarmsBasedOnStandbyBuckets(triggerPackages);
-                            }
+                            reorderAlarmsBasedOnStandbyBuckets(triggerPackages);
                             rescheduleKernelAlarmsLocked();
                             updateNextAlarmClockLocked();
                             logAlarmBatchDelivered(
@@ -4914,32 +4669,6 @@
         return alarm.creatorUid;
     }
 
-    @GuardedBy("mLock")
-    private boolean canAffordBillLocked(@NonNull Alarm alarm,
-            @NonNull EconomyManagerInternal.ActionBill bill) {
-        final int userId = UserHandle.getUserId(alarm.creatorUid);
-        final String pkgName = alarm.sourcePackage;
-        ArrayMap<EconomyManagerInternal.ActionBill, Boolean> actionAffordability =
-                mAffordabilityCache.get(userId, pkgName);
-        if (actionAffordability == null) {
-            actionAffordability = new ArrayMap<>();
-            mAffordabilityCache.add(userId, pkgName, actionAffordability);
-        }
-
-        if (actionAffordability.containsKey(bill)) {
-            return actionAffordability.get(bill);
-        }
-
-        final boolean canAfford = mEconomyManagerInternal.canPayFor(userId, pkgName, bill);
-        actionAffordability.put(bill, canAfford);
-        return canAfford;
-    }
-
-    @GuardedBy("mLock")
-    private boolean hasEnoughWealthLocked(@NonNull Alarm alarm) {
-        return canAffordBillLocked(alarm, TareBill.getAppropriateBill(alarm));
-    }
-
     private Bundle getAlarmOperationBundle(Alarm alarm) {
         if (alarm.mIdleOptions != null) {
             return alarm.mIdleOptions;
@@ -4965,7 +4694,6 @@
         // Unused id 9
         // Unused id 10
         public static final int REFRESH_EXACT_ALARM_CANDIDATES = 11;
-        public static final int TARE_AFFORDABILITY_CHANGED = 12;
         public static final int CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE = 13;
         public static final int TEMPORARY_QUOTA_CHANGED = 14;
         public static final int REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED = 15;
@@ -5046,20 +4774,6 @@
                     }
                     break;
 
-                case TARE_AFFORDABILITY_CHANGED:
-                    synchronized (mLock) {
-                        final int userId = msg.arg1;
-                        final String packageName = (String) msg.obj;
-
-                        final ArraySet<UserPackage> filterPackages = new ArraySet<>();
-                        filterPackages.add(UserPackage.of(userId, packageName));
-                        if (reorderAlarmsBasedOnTare(filterPackages)) {
-                            rescheduleKernelAlarmsLocked();
-                            updateNextAlarmClockLocked();
-                        }
-                    }
-                    break;
-
                 case REMOVE_FOR_CANCELED:
                     final PendingIntent operation = (PendingIntent) msg.obj;
                     synchronized (mLock) {
@@ -5366,33 +5080,6 @@
         }
     }
 
-    private final EconomyManagerInternal.AffordabilityChangeListener mAffordabilityChangeListener =
-            new EconomyManagerInternal.AffordabilityChangeListener() {
-                @Override
-                public void onAffordabilityChanged(int userId, @NonNull String packageName,
-                        @NonNull EconomyManagerInternal.ActionBill bill, boolean canAfford) {
-                    if (DEBUG_TARE) {
-                        Slog.d(TAG,
-                                userId + ":" + packageName + " affordability for "
-                                        + TareBill.getName(bill) + " changed to " + canAfford);
-                    }
-
-                    synchronized (mLock) {
-                        ArrayMap<EconomyManagerInternal.ActionBill, Boolean> actionAffordability =
-                                mAffordabilityCache.get(userId, packageName);
-                        if (actionAffordability == null) {
-                            actionAffordability = new ArrayMap<>();
-                            mAffordabilityCache.add(userId, packageName, actionAffordability);
-                        }
-                        actionAffordability.put(bill, canAfford);
-                    }
-
-                    mHandler.obtainMessage(AlarmHandler.TARE_AFFORDABILITY_CHANGED, userId,
-                            canAfford ? 1 : 0, packageName)
-                            .sendToTarget();
-                }
-            };
-
     private final Listener mForceAppStandbyListener = new Listener() {
 
         @Override
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/TareBill.java b/apex/jobscheduler/service/java/com/android/server/alarm/TareBill.java
deleted file mode 100644
index a348136..0000000
--- a/apex/jobscheduler/service/java/com/android/server/alarm/TareBill.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.alarm;
-
-import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE;
-import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
-
-import static com.android.server.tare.AlarmManagerEconomicPolicy.ACTION_ALARM_CLOCK;
-import static com.android.server.tare.AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_EXACT;
-import static com.android.server.tare.AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE;
-import static com.android.server.tare.AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_INEXACT;
-import static com.android.server.tare.AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE;
-import static com.android.server.tare.AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_EXACT;
-import static com.android.server.tare.AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE;
-import static com.android.server.tare.AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_INEXACT;
-import static com.android.server.tare.AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE;
-
-import android.annotation.NonNull;
-
-import com.android.server.tare.EconomyManagerInternal;
-import com.android.server.tare.EconomyManagerInternal.ActionBill;
-
-import java.util.List;
-
-/**
- * Container to maintain alarm TARE {@link ActionBill ActionBills} and their related methods.
- */
-final class TareBill {
-    /**
-     * Bill to use for AlarmClocks.
-     */
-    static final ActionBill ALARM_CLOCK = new ActionBill(List.of(
-            new EconomyManagerInternal.AnticipatedAction(ACTION_ALARM_CLOCK, 1, 0)));
-    /**
-     * Bills to use for various alarm types.
-     */
-    static final ActionBill NONWAKEUP_INEXACT_ALARM = new ActionBill(List.of(
-            new EconomyManagerInternal.AnticipatedAction(ACTION_ALARM_NONWAKEUP_INEXACT, 1, 0)));
-    static final ActionBill NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE_ALARM = new ActionBill(List.of(
-            new EconomyManagerInternal.AnticipatedAction(
-                    ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE, 1, 0)));
-    static final ActionBill NONWAKEUP_EXACT_ALARM = new ActionBill(List.of(
-            new EconomyManagerInternal.AnticipatedAction(ACTION_ALARM_NONWAKEUP_EXACT, 1, 0)));
-    static final ActionBill NONWAKEUP_EXACT_ALLOW_WHILE_IDLE_ALARM = new ActionBill(List.of(
-            new EconomyManagerInternal.AnticipatedAction(
-                    ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE, 1, 0)));
-    static final ActionBill WAKEUP_INEXACT_ALARM = new ActionBill(List.of(
-            new EconomyManagerInternal.AnticipatedAction(ACTION_ALARM_WAKEUP_INEXACT, 1, 0)));
-    static final ActionBill WAKEUP_INEXACT_ALLOW_WHILE_IDLE_ALARM = new ActionBill(List.of(
-            new EconomyManagerInternal.AnticipatedAction(
-                    ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE, 1, 0)));
-    static final ActionBill WAKEUP_EXACT_ALARM = new ActionBill(List.of(
-            new EconomyManagerInternal.AnticipatedAction(ACTION_ALARM_WAKEUP_EXACT, 1, 0)));
-    static final ActionBill WAKEUP_EXACT_ALLOW_WHILE_IDLE_ALARM = new ActionBill(List.of(
-            new EconomyManagerInternal.AnticipatedAction(
-                    ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE, 1, 0)));
-
-    @NonNull
-    static ActionBill getAppropriateBill(@NonNull Alarm alarm) {
-        if (alarm.alarmClock != null) {
-            return ALARM_CLOCK;
-        }
-
-        final boolean allowWhileIdle =
-                (alarm.flags & (FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED | FLAG_ALLOW_WHILE_IDLE)) != 0;
-        final boolean isExact = alarm.windowLength == 0;
-
-        if (alarm.wakeup) {
-            if (isExact) {
-                if (allowWhileIdle) {
-                    return WAKEUP_EXACT_ALLOW_WHILE_IDLE_ALARM;
-                }
-                return WAKEUP_EXACT_ALARM;
-            }
-            // Inexact
-            if (allowWhileIdle) {
-                return WAKEUP_INEXACT_ALLOW_WHILE_IDLE_ALARM;
-            }
-            return WAKEUP_INEXACT_ALARM;
-        }
-
-        // Nonwakeup
-        if (isExact) {
-            if (allowWhileIdle) {
-                return NONWAKEUP_EXACT_ALLOW_WHILE_IDLE_ALARM;
-            }
-            return NONWAKEUP_EXACT_ALARM;
-
-        }
-        if (allowWhileIdle) {
-            return NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE_ALARM;
-        }
-        return NONWAKEUP_INEXACT_ALARM;
-    }
-
-    @NonNull
-    static String getName(@NonNull ActionBill bill) {
-        if (bill.equals(ALARM_CLOCK)) {
-            return "ALARM_CLOCK_BILL";
-        }
-        if (bill.equals(NONWAKEUP_INEXACT_ALARM)) {
-            return "NONWAKEUP_INEXACT_ALARM_BILL";
-        }
-        if (bill.equals(NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE_ALARM)) {
-            return "NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE_ALARM_BILL";
-        }
-        if (bill.equals(NONWAKEUP_EXACT_ALARM)) {
-            return "NONWAKEUP_EXACT_ALARM_BILL";
-        }
-        if (bill.equals(NONWAKEUP_EXACT_ALLOW_WHILE_IDLE_ALARM)) {
-            return "NONWAKEUP_EXACT_ALLOW_WHILE_IDLE_ALARM_BILL";
-        }
-        if (bill.equals(WAKEUP_INEXACT_ALARM)) {
-            return "WAKEUP_INEXACT_ALARM_BILL";
-        }
-        if (bill.equals(WAKEUP_INEXACT_ALLOW_WHILE_IDLE_ALARM)) {
-            return "WAKEUP_INEXACT_ALLOW_WHILE_IDLE_ALARM_BILL";
-        }
-        if (bill.equals(WAKEUP_EXACT_ALARM)) {
-            return "WAKEUP_EXACT_ALARM_BILL";
-        }
-        if (bill.equals(WAKEUP_EXACT_ALLOW_WHILE_IDLE_ALARM)) {
-            return "WAKEUP_EXACT_ALLOW_WHILE_IDLE_ALARM_BILL";
-        }
-        return "UNKNOWN_BILL (" + bill.toString() + ")";
-    }
-
-    private TareBill() {
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
index 012ede2..096238a 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -1737,6 +1737,17 @@
                     continue;
                 }
 
+                if (!nextPending.isReady()) {
+                    // This could happen when the job count reached its quota, the constrains
+                    // for the job has been updated but hasn't been removed from the pending
+                    // queue yet.
+                    if (DEBUG) {
+                        Slog.w(TAG, "Pending+not ready job: " + nextPending);
+                    }
+                    pendingJobQueue.remove(nextPending);
+                    continue;
+                }
+
                 if (DEBUG && isSimilarJobRunningLocked(nextPending)) {
                     Slog.w(TAG, "Already running similar job to: " + nextPending);
                 }
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 88a3c6f..10162fd 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -45,7 +45,6 @@
 import android.app.job.JobSnapshot;
 import android.app.job.JobWorkItem;
 import android.app.job.UserVisibleJobSummary;
-import android.app.tare.EconomyManager;
 import android.app.usage.UsageStatsManager;
 import android.app.usage.UsageStatsManagerInternal;
 import android.compat.annotation.ChangeId;
@@ -85,7 +84,6 @@
 import android.os.WorkSource;
 import android.os.storage.StorageManagerInternal;
 import android.provider.DeviceConfig;
-import android.provider.Settings;
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -130,13 +128,10 @@
 import com.android.server.job.controllers.RestrictingController;
 import com.android.server.job.controllers.StateController;
 import com.android.server.job.controllers.StorageController;
-import com.android.server.job.controllers.TareController;
 import com.android.server.job.controllers.TimeController;
 import com.android.server.job.restrictions.JobRestriction;
 import com.android.server.job.restrictions.ThermalStatusRestriction;
 import com.android.server.pm.UserManagerInternal;
-import com.android.server.tare.EconomyManagerInternal;
-import com.android.server.tare.JobSchedulerEconomicPolicy;
 import com.android.server.usage.AppStandbyInternal;
 import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener;
 import com.android.server.utils.quota.Categorizer;
@@ -310,8 +305,6 @@
     private final PrefetchController mPrefetchController;
     /** Needed to get remaining quota time. */
     private final QuotaController mQuotaController;
-    /** Needed to get max execution time and expedited-job allowance. */
-    private final TareController mTareController;
     /**
      * List of restrictions.
      * Note: do not add to or remove from this list at runtime except in the constructor, because we
@@ -485,8 +478,7 @@
     // (ScheduledJobStateChanged and JobStatusDumpProto).
     public static final int EXEMPTED_INDEX = 6;
 
-    private class ConstantsObserver implements DeviceConfig.OnPropertiesChangedListener,
-            EconomyManagerInternal.TareStateChangeListener {
+    private class ConstantsObserver implements DeviceConfig.OnPropertiesChangedListener {
         @Nullable
         @GuardedBy("mLock")
         private DeviceConfig.Properties mLastPropertiesPulled;
@@ -516,16 +508,6 @@
         public void start() {
             DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_JOB_SCHEDULER,
                     AppSchedulingModuleThread.getExecutor(), this);
-            final EconomyManagerInternal economyManagerInternal =
-                    LocalServices.getService(EconomyManagerInternal.class);
-            economyManagerInternal
-                    .registerTareStateChangeListener(this, JobSchedulerEconomicPolicy.POLICY_JOB);
-            // Load all the constants.
-            synchronized (mLock) {
-                mConstants.updateTareSettingsLocked(
-                        economyManagerInternal.getEnabledMode(
-                                JobSchedulerEconomicPolicy.POLICY_JOB));
-            }
             onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_JOB_SCHEDULER));
         }
 
@@ -645,16 +627,6 @@
             mHandler.sendEmptyMessage(MSG_CHECK_JOB);
         }
 
-        @Override
-        public void onTareEnabledModeChanged(@EconomyManager.EnabledMode int enabledMode) {
-            if (mConstants.updateTareSettingsLocked(enabledMode)) {
-                for (int controller = 0; controller < mControllers.size(); controller++) {
-                    final StateController sc = mControllers.get(controller);
-                    sc.onConstantsUpdatedLocked();
-                }
-                onControllerStateChanged(null);
-            }
-        }
     }
 
     @VisibleForTesting
@@ -1051,12 +1023,6 @@
          */
         public int MAX_NUM_PERSISTED_JOB_WORK_ITEMS = DEFAULT_MAX_NUM_PERSISTED_JOB_WORK_ITEMS;
 
-        /**
-         * If true, use TARE policy for job limiting. If false, use quotas.
-         */
-        public boolean USE_TARE_POLICY = EconomyManager.DEFAULT_ENABLE_POLICY_JOB_SCHEDULER
-                && EconomyManager.DEFAULT_ENABLE_TARE_MODE == EconomyManager.ENABLED_MODE_ON;
-
         public Constants() {
             copyTransportBatchThresholdDefaults();
         }
@@ -1300,16 +1266,6 @@
                     DEFAULT_RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS);
         }
 
-        private boolean updateTareSettingsLocked(@EconomyManager.EnabledMode int enabledMode) {
-            boolean changed = false;
-            final boolean useTare = enabledMode == EconomyManager.ENABLED_MODE_ON;
-            if (USE_TARE_POLICY != useTare) {
-                USE_TARE_POLICY = useTare;
-                changed = true;
-            }
-            return changed;
-        }
-
         void dump(IndentingPrintWriter pw) {
             pw.println("Settings:");
             pw.increaseIndent();
@@ -1383,8 +1339,6 @@
             pw.print(KEY_MAX_NUM_PERSISTED_JOB_WORK_ITEMS, MAX_NUM_PERSISTED_JOB_WORK_ITEMS)
                     .println();
 
-            pw.print(Settings.Global.ENABLE_TARE, USE_TARE_POLICY).println();
-
             pw.decreaseIndent();
         }
 
@@ -1869,9 +1823,7 @@
 
             // Return failure early if expedited job quota used up.
             if (jobStatus.isRequestedExpeditedJob()) {
-                if ((mConstants.USE_TARE_POLICY && !mTareController.canScheduleEJ(jobStatus))
-                        || (!mConstants.USE_TARE_POLICY
-                        && !mQuotaController.isWithinEJQuotaLocked(jobStatus))) {
+                if (!mQuotaController.isWithinEJQuotaLocked(jobStatus)) {
                     Counter.logIncrementWithUid(
                             "job_scheduler.value_cntr_w_uid_schedule_failure_ej_out_of_quota",
                             callingUid);
@@ -2726,9 +2678,6 @@
                 new QuotaController(this, backgroundJobsController, mConnectivityController);
         mControllers.add(mQuotaController);
         mControllers.add(new ComponentController(this));
-        mTareController =
-                new TareController(this, backgroundJobsController, mConnectivityController);
-        mControllers.add(mTareController);
 
         startControllerTrackingAsync();
 
@@ -4243,10 +4192,7 @@
                             job.getTimeoutBlamePackageName(), timeoutTag)
                             ? normalUpperLimitMs
                             : mConstants.RUNTIME_MIN_GUARANTEE_MS;
-            return Math.min(upperLimitMs,
-                    mConstants.USE_TARE_POLICY
-                            ? mTareController.getMaxJobExecutionTimeMsLocked(job)
-                            : mQuotaController.getMaxJobExecutionTimeMsLocked(job));
+            return Math.min(upperLimitMs, mQuotaController.getMaxJobExecutionTimeMsLocked(job));
         }
     }
 
@@ -5747,11 +5693,6 @@
     }
 
     @VisibleForTesting
-    protected TareController getTareController() {
-        return mTareController;
-    }
-
-    @VisibleForTesting
     protected void waitOnAsyncLoadingForTesting() throws Exception {
         mStartControllerTrackingLatch.await();
         // Ignore the job store loading for testing.
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index 8ab7d2f..39d50f5 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -16,8 +16,6 @@
 
 package com.android.server.job;
 
-import static android.app.job.JobInfo.getPriorityString;
-
 import static com.android.server.job.JobConcurrencyManager.WORK_TYPE_NONE;
 import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
 import static com.android.server.job.JobSchedulerService.safelyScaleBytesToKBForHistogram;
@@ -73,9 +71,6 @@
 import com.android.server.EventLogTags;
 import com.android.server.LocalServices;
 import com.android.server.job.controllers.JobStatus;
-import com.android.server.tare.EconomicPolicy;
-import com.android.server.tare.EconomyManagerInternal;
-import com.android.server.tare.JobSchedulerEconomicPolicy;
 
 import java.util.Objects;
 
@@ -159,7 +154,6 @@
     private final Object mLock;
     private final ActivityManagerInternal mActivityManagerInternal;
     private final IBatteryStats mBatteryStats;
-    private final EconomyManagerInternal mEconomyManagerInternal;
     private final JobPackageTracker mJobPackageTracker;
     private final PowerManager mPowerManager;
     private final UsageStatsManagerInternal mUsageStatsManagerInternal;
@@ -324,7 +318,6 @@
         mService = service;
         mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
         mBatteryStats = batteryStats;
-        mEconomyManagerInternal = LocalServices.getService(EconomyManagerInternal.class);
         mJobPackageTracker = tracker;
         mCallbackHandler = new JobServiceHandler(looper);
         mJobConcurrencyManager = concurrencyManager;
@@ -414,11 +407,6 @@
             mWakeLock.setReferenceCounted(false);
             mWakeLock.acquire();
 
-            // Note the start when we try to bind so that the app is charged for some processing
-            // even if binding fails.
-            mEconomyManagerInternal.noteInstantaneousEvent(
-                    job.getSourceUserId(), job.getSourcePackageName(),
-                    getStartActionId(job), String.valueOf(job.getJobId()));
             mVerb = VERB_BINDING;
             scheduleOpTimeOutLocked();
             // Use FLAG_FROM_BACKGROUND to avoid resetting the bad-app tracking.
@@ -619,25 +607,6 @@
         return result == PermissionChecker.PERMISSION_GRANTED;
     }
 
-    @EconomicPolicy.AppAction
-    private static int getStartActionId(@NonNull JobStatus job) {
-        switch (job.getEffectivePriority()) {
-            case JobInfo.PRIORITY_MAX:
-                return JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START;
-            case JobInfo.PRIORITY_HIGH:
-                return JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_START;
-            case JobInfo.PRIORITY_LOW:
-                return JobSchedulerEconomicPolicy.ACTION_JOB_LOW_START;
-            case JobInfo.PRIORITY_MIN:
-                return JobSchedulerEconomicPolicy.ACTION_JOB_MIN_START;
-            default:
-                Slog.wtf(TAG, "Unknown priority: " + getPriorityString(job.getEffectivePriority()));
-                // Intentional fallthrough
-            case JobInfo.PRIORITY_DEFAULT:
-                return JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_START;
-        }
-    }
-
     /**
      * Used externally to query the running job. Will return null if there is no job running.
      */
@@ -1649,12 +1618,6 @@
         } catch (RemoteException e) {
             // Whatever.
         }
-        if (loggingStopReason == JobParameters.STOP_REASON_TIMEOUT) {
-            mEconomyManagerInternal.noteInstantaneousEvent(
-                    mRunningJob.getSourceUserId(), mRunningJob.getSourcePackageName(),
-                    JobSchedulerEconomicPolicy.ACTION_JOB_TIMEOUT,
-                    String.valueOf(mRunningJob.getJobId()));
-        }
         mNotificationCoordinator.removeNotificationAssociation(this,
                 reschedulingStopReason, completedJob);
         if (mWakeLock != null) {
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
index 3219f7e..7a39610 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
@@ -1001,8 +1001,7 @@
             NetworkCapabilities capabilities, Constants constants) {
         // A restricted job that's out of quota MUST use an unmetered network.
         if (jobStatus.getEffectiveStandbyBucket() == RESTRICTED_INDEX
-                && (!jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)
-                || !jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_TARE_WEALTH))) {
+                && (!jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA))) {
             final NetworkCapabilities.Builder builder =
                     copyCapabilities(jobStatus.getJob().getRequiredNetwork());
             builder.addCapability(NET_CAPABILITY_NOT_METERED);
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index d643768..9985543 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -116,7 +116,6 @@
     public static final int CONSTRAINT_TIMING_DELAY = 1 << 31;
     public static final int CONSTRAINT_DEADLINE = 1 << 30;
     public static final int CONSTRAINT_CONNECTIVITY = 1 << 28;
-    static final int CONSTRAINT_TARE_WEALTH = 1 << 27; // Implicit constraint
     public static final int CONSTRAINT_CONTENT_TRIGGER = 1 << 26;
     static final int CONSTRAINT_DEVICE_NOT_DOZING = 1 << 25; // Implicit constraint
     static final int CONSTRAINT_WITHIN_QUOTA = 1 << 24;      // Implicit constraint
@@ -128,7 +127,6 @@
             | CONSTRAINT_BACKGROUND_NOT_RESTRICTED
             | CONSTRAINT_DEVICE_NOT_DOZING
             | CONSTRAINT_FLEXIBLE
-            | CONSTRAINT_TARE_WEALTH
             | CONSTRAINT_WITHIN_QUOTA;
 
     // The following set of dynamic constraints are for specific use cases (as explained in their
@@ -196,7 +194,6 @@
     private static final int STATSD_CONSTRAINTS_TO_LOG = CONSTRAINT_CONTENT_TRIGGER
             | CONSTRAINT_DEADLINE
             | CONSTRAINT_PREFETCH
-            | CONSTRAINT_TARE_WEALTH
             | CONSTRAINT_TIMING_DELAY
             | CONSTRAINT_WITHIN_QUOTA;
 
@@ -532,10 +529,6 @@
      * Whether or not this job is approved to be treated as expedited per quota policy.
      */
     private boolean mExpeditedQuotaApproved;
-    /**
-     * Whether or not this job is approved to be treated as expedited per TARE policy.
-     */
-    private boolean mExpeditedTareApproved;
 
     /**
      * Summary describing this job. Lazily created in {@link #getUserVisibleJobSummary()}
@@ -568,9 +561,6 @@
     /** The job is within its quota based on its standby bucket. */
     private boolean mReadyWithinQuota;
 
-    /** The job has enough credits to run based on TARE. */
-    private boolean mReadyTareWealth;
-
     /** The job's dynamic requirements have been satisfied. */
     private boolean mReadyDynamicSatisfied;
 
@@ -1719,7 +1709,7 @@
      * treated as an expedited job.
      */
     public boolean shouldTreatAsExpeditedJob() {
-        return mExpeditedQuotaApproved && mExpeditedTareApproved && isRequestedExpeditedJob();
+        return mExpeditedQuotaApproved && isRequestedExpeditedJob();
     }
 
     /**
@@ -1868,16 +1858,6 @@
     }
 
     /** @return true if the constraint was changed, false otherwise. */
-    boolean setTareWealthConstraintSatisfied(final long nowElapsed, boolean state) {
-        if (setConstraintSatisfied(CONSTRAINT_TARE_WEALTH, nowElapsed, state)) {
-            // The constraint was changed. Update the ready flag.
-            mReadyTareWealth = state;
-            return true;
-        }
-        return false;
-    }
-
-    /** @return true if the constraint was changed, false otherwise. */
     boolean setFlexibilityConstraintSatisfied(final long nowElapsed, boolean state) {
         return setConstraintSatisfied(CONSTRAINT_FLEXIBLE, nowElapsed, state);
     }
@@ -1904,28 +1884,6 @@
         return true;
     }
 
-    /**
-     * Sets whether or not this job is approved to be treated as an expedited job based on TARE
-     * policy.
-     *
-     * @return true if the approval bit was changed, false otherwise.
-     */
-    boolean setExpeditedJobTareApproved(final long nowElapsed, boolean state) {
-        if (mExpeditedTareApproved == state) {
-            return false;
-        }
-        final boolean wasReady = !state && isReady();
-        mExpeditedTareApproved = state;
-        updateExpeditedDependencies();
-        final boolean isReady = isReady();
-        if (wasReady && !isReady) {
-            mReasonReadyToUnready = JobParameters.STOP_REASON_QUOTA;
-        } else if (!wasReady && isReady) {
-            mReasonReadyToUnready = JobParameters.STOP_REASON_UNDEFINED;
-        }
-        return true;
-    }
-
     private void updateExpeditedDependencies() {
         // DeviceIdleJobsController currently only tracks jobs with the WILL_BE_FOREGROUND flag.
         // Making it also track requested-expedited jobs would add unnecessary hops since the
@@ -2041,7 +1999,6 @@
             case CONSTRAINT_PREFETCH:
                 return JobParameters.STOP_REASON_ESTIMATED_APP_LAUNCH_TIME_CHANGED;
 
-            case CONSTRAINT_TARE_WEALTH:
             case CONSTRAINT_WITHIN_QUOTA:
                 return JobParameters.STOP_REASON_QUOTA;
 
@@ -2130,9 +2087,6 @@
         if ((CONSTRAINT_STORAGE_NOT_LOW & unsatisfiedConstraints) != 0) {
             return JobScheduler.PENDING_JOB_REASON_CONSTRAINT_STORAGE_NOT_LOW;
         }
-        if ((CONSTRAINT_TARE_WEALTH & unsatisfiedConstraints) != 0) {
-            return JobScheduler.PENDING_JOB_REASON_QUOTA;
-        }
         if ((CONSTRAINT_TIMING_DELAY & unsatisfiedConstraints) != 0) {
             return JobScheduler.PENDING_JOB_REASON_CONSTRAINT_MINIMUM_LATENCY;
         }
@@ -2207,11 +2161,6 @@
             Slog.wtf(TAG, "Tried to set quota as a dynamic constraint");
             constraints &= ~CONSTRAINT_WITHIN_QUOTA;
         }
-        if ((constraints & CONSTRAINT_TARE_WEALTH) != 0) {
-            // Quota should never be used as a dynamic constraint.
-            Slog.wtf(TAG, "Tried to set TARE as a dynamic constraint");
-            constraints &= ~CONSTRAINT_TARE_WEALTH;
-        }
 
         // Connectivity and content trigger are special since they're only valid to add if the
         // job has requested network or specific content URIs. Adding these constraints to jobs
@@ -2280,10 +2229,6 @@
                 oldValue = mReadyNotDozing;
                 mReadyNotDozing = value;
                 break;
-            case CONSTRAINT_TARE_WEALTH:
-                oldValue = mReadyTareWealth;
-                mReadyTareWealth = value;
-                break;
             case CONSTRAINT_WITHIN_QUOTA:
                 oldValue = mReadyWithinQuota;
                 mReadyWithinQuota = value;
@@ -2321,9 +2266,6 @@
             case CONSTRAINT_DEVICE_NOT_DOZING:
                 mReadyNotDozing = oldValue;
                 break;
-            case CONSTRAINT_TARE_WEALTH:
-                mReadyTareWealth = oldValue;
-                break;
             case CONSTRAINT_WITHIN_QUOTA:
                 mReadyWithinQuota = oldValue;
                 break;
@@ -2341,7 +2283,7 @@
         // sessions (exempt from dynamic restrictions), we need the additional check to ensure
         // that NEVER jobs don't run.
         // TODO: cleanup quota and standby bucket management so we don't need the additional checks
-        if (((!mReadyWithinQuota || !mReadyTareWealth)
+        if (((!mReadyWithinQuota)
                 && !mReadyDynamicSatisfied && !shouldTreatAsExpeditedJob())
                 || getEffectiveStandbyBucket() == NEVER_INDEX) {
             return false;
@@ -2577,9 +2519,6 @@
         if ((constraints & CONSTRAINT_PREFETCH) != 0) {
             pw.print(" PREFETCH");
         }
-        if ((constraints & CONSTRAINT_TARE_WEALTH) != 0) {
-            pw.print(" TARE_WEALTH");
-        }
         if ((constraints & CONSTRAINT_WITHIN_QUOTA) != 0) {
             pw.print(" WITHIN_QUOTA");
         }
@@ -2615,8 +2554,6 @@
                 return JobServerProtoEnums.CONSTRAINT_PREFETCH;
             case CONSTRAINT_STORAGE_NOT_LOW:
                 return JobServerProtoEnums.CONSTRAINT_STORAGE_NOT_LOW;
-            case CONSTRAINT_TARE_WEALTH:
-                return JobServerProtoEnums.CONSTRAINT_TARE_WEALTH;
             case CONSTRAINT_TIMING_DELAY:
                 return JobServerProtoEnums.CONSTRAINT_TIMING_DELAY;
             case CONSTRAINT_WITHIN_QUOTA:
@@ -2869,7 +2806,7 @@
             pw.println();
             pw.print("Unsatisfied constraints:");
             dumpConstraints(pw,
-                    ((requiredConstraints | CONSTRAINT_WITHIN_QUOTA | CONSTRAINT_TARE_WEALTH)
+                    ((requiredConstraints | CONSTRAINT_WITHIN_QUOTA)
                             & ~satisfiedConstraints));
             pw.println();
             if (hasFlexibilityConstraint()) {
@@ -2937,8 +2874,6 @@
         if ((getFlags() & JobInfo.FLAG_EXPEDITED) != 0) {
             pw.print("expeditedQuotaApproved: ");
             pw.print(mExpeditedQuotaApproved);
-            pw.print(" expeditedTareApproved: ");
-            pw.print(mExpeditedTareApproved);
             pw.print(" (started as EJ: ");
             pw.print(startedAsExpeditedJob);
             pw.println(")");
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
index 8ddbf69..cfbfa5d 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
@@ -328,9 +328,6 @@
     private final BackgroundJobsController mBackgroundJobsController;
     private final ConnectivityController mConnectivityController;
 
-    @GuardedBy("mLock")
-    private boolean mIsEnabled;
-
     /** How much time each app will have to run jobs within their standby bucket window. */
     private final long[] mAllowedTimePerPeriodMs = new long[]{
             QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS,
@@ -515,7 +512,7 @@
 
     /** An app has reached its quota. The message should contain a {@link UserPackage} object. */
     @VisibleForTesting
-    static final int MSG_REACHED_QUOTA = 0;
+    static final int MSG_REACHED_TIME_QUOTA = 0;
     /** Drop any old timing sessions. */
     private static final int MSG_CLEAN_UP_SESSIONS = 1;
     /** Check if a package is now within its quota. */
@@ -527,7 +524,7 @@
      * object.
      */
     @VisibleForTesting
-    static final int MSG_REACHED_EJ_QUOTA = 4;
+    static final int MSG_REACHED_EJ_TIME_QUOTA = 4;
     /**
      * Process a new {@link UsageEvents.Event}. The event will be the message's object and the
      * userId will the first arg.
@@ -536,6 +533,11 @@
     /** A UID's free quota grace period has ended. */
     @VisibleForTesting
     static final int MSG_END_GRACE_PERIOD = 6;
+    /**
+     * An app has reached its job count quota. The message should contain a {@link UserPackage}
+     * object.
+     */
+    static final int MSG_REACHED_COUNT_QUOTA = 7;
 
     public QuotaController(@NonNull JobSchedulerService service,
             @NonNull BackgroundJobsController backgroundJobsController,
@@ -546,7 +548,6 @@
         mQcConstants = new QcConstants();
         mBackgroundJobsController = backgroundJobsController;
         mConnectivityController = connectivityController;
-        mIsEnabled = !mConstants.USE_TARE_POLICY;
         mInQuotaAlarmQueue =
                 new InQuotaAlarmQueue(mContext, AppSchedulingModuleThread.get().getLooper());
 
@@ -835,9 +836,6 @@
     /** @return true if the job is within expedited job quota. */
     @GuardedBy("mLock")
     public boolean isWithinEJQuotaLocked(@NonNull final JobStatus jobStatus) {
-        if (!mIsEnabled) {
-            return true;
-        }
         if (isQuotaFreeLocked(jobStatus.getEffectiveStandbyBucket())) {
             return true;
         }
@@ -881,20 +879,37 @@
     }
 
     @VisibleForTesting
+    @GuardedBy("mLock")
     boolean isWithinQuotaLocked(@NonNull final JobStatus jobStatus) {
-        if (!mIsEnabled) {
-            return true;
-        }
         final int standbyBucket = jobStatus.getEffectiveStandbyBucket();
         // A job is within quota if one of the following is true:
         //   1. it was started while the app was in the TOP state
         //   2. the app is currently in the foreground
         //   3. the app overall is within its quota
-        return jobStatus.shouldTreatAsUserInitiatedJob()
+        if (jobStatus.shouldTreatAsUserInitiatedJob()
                 || isTopStartedJobLocked(jobStatus)
-                || isUidInForeground(jobStatus.getSourceUid())
-                || isWithinQuotaLocked(
-                jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(), standbyBucket);
+                || isUidInForeground(jobStatus.getSourceUid())) {
+            return true;
+        }
+
+        if (standbyBucket == NEVER_INDEX) return false;
+
+        if (isQuotaFreeLocked(standbyBucket)) return true;
+
+        final ExecutionStats stats = getExecutionStatsLocked(jobStatus.getSourceUserId(),
+                jobStatus.getSourcePackageName(), standbyBucket);
+        if (!(getRemainingExecutionTimeLocked(stats) > 0)) {
+            // Out of execution time quota.
+            return false;
+        }
+
+        if (mService.isCurrentlyRunningLocked(jobStatus)) {
+            // if job is running, considered as in quota so it can keep running.
+            return true;
+        }
+
+        // Check if the app is within job count quota.
+        return isUnderJobCountQuotaLocked(stats) && isUnderSessionCountQuotaLocked(stats);
     }
 
     @GuardedBy("mLock")
@@ -912,9 +927,6 @@
     @GuardedBy("mLock")
     boolean isWithinQuotaLocked(final int userId, @NonNull final String packageName,
             final int standbyBucket) {
-        if (!mIsEnabled) {
-            return true;
-        }
         if (standbyBucket == NEVER_INDEX) return false;
 
         if (isQuotaFreeLocked(standbyBucket)) return true;
@@ -922,12 +934,11 @@
         ExecutionStats stats = getExecutionStatsLocked(userId, packageName, standbyBucket);
         // TODO: use a higher minimum remaining time for jobs with MINIMUM priority
         return getRemainingExecutionTimeLocked(stats) > 0
-                && isUnderJobCountQuotaLocked(stats, standbyBucket)
-                && isUnderSessionCountQuotaLocked(stats, standbyBucket);
+                && isUnderJobCountQuotaLocked(stats)
+                && isUnderSessionCountQuotaLocked(stats);
     }
 
-    private boolean isUnderJobCountQuotaLocked(@NonNull ExecutionStats stats,
-            final int standbyBucket) {
+    private boolean isUnderJobCountQuotaLocked(@NonNull ExecutionStats stats) {
         final long now = sElapsedRealtimeClock.millis();
         final boolean isUnderAllowedTimeQuota =
                 (stats.jobRateLimitExpirationTimeElapsed <= now
@@ -936,8 +947,7 @@
                 && stats.bgJobCountInWindow < stats.jobCountLimit;
     }
 
-    private boolean isUnderSessionCountQuotaLocked(@NonNull ExecutionStats stats,
-            final int standbyBucket) {
+    private boolean isUnderSessionCountQuotaLocked(@NonNull ExecutionStats stats) {
         final long now = sElapsedRealtimeClock.millis();
         final boolean isUnderAllowedTimeQuota = (stats.sessionRateLimitExpirationTimeElapsed <= now
                 || stats.sessionCountInRateLimitingWindow < mMaxSessionCountPerRateLimitingWindow);
@@ -1462,6 +1472,7 @@
                 stats.jobCountInRateLimitingWindow = 0;
             }
             stats.jobCountInRateLimitingWindow += count;
+            stats.bgJobCountInWindow += count;
         }
     }
 
@@ -1696,10 +1707,11 @@
                     changedJobs.add(js);
                 }
             } else if (realStandbyBucket != EXEMPTED_INDEX && realStandbyBucket != ACTIVE_INDEX
-                    && realStandbyBucket == js.getEffectiveStandbyBucket()) {
+                    && realStandbyBucket == js.getEffectiveStandbyBucket()
+                    && !mService.isCurrentlyRunningLocked(js)) {
                 // An app in the ACTIVE bucket may be out of quota while the job could be in quota
                 // for some reason. Therefore, avoid setting the real value here and check each job
-                // individually.
+                // individually. Running job need to determine its own quota status as well.
                 if (setConstraintSatisfied(js, nowElapsed, realInQuota, isWithinEJQuota)) {
                     changedJobs.add(js);
                 }
@@ -1818,9 +1830,8 @@
         }
 
         ExecutionStats stats = getExecutionStatsLocked(userId, packageName, standbyBucket);
-        final boolean isUnderJobCountQuota = isUnderJobCountQuotaLocked(stats, standbyBucket);
-        final boolean isUnderTimingSessionCountQuota = isUnderSessionCountQuotaLocked(stats,
-                standbyBucket);
+        final boolean isUnderJobCountQuota = isUnderJobCountQuotaLocked(stats);
+        final boolean isUnderTimingSessionCountQuota = isUnderSessionCountQuotaLocked(stats);
         final long remainingEJQuota = getRemainingEJExecutionTimeLocked(userId, packageName);
 
         final boolean inRegularQuota =
@@ -2139,6 +2150,11 @@
                 mBgJobCount++;
                 if (mRegularJobTimer) {
                     incrementJobCountLocked(mPkg.userId, mPkg.packageName, 1);
+                    final ExecutionStats stats = getExecutionStatsLocked(mPkg.userId,
+                            mPkg.packageName, jobStatus.getEffectiveStandbyBucket(), false);
+                    if (stats.bgJobCountInWindow >= stats.jobCountLimit) {
+                        mHandler.obtainMessage(MSG_REACHED_COUNT_QUOTA, mPkg).sendToTarget();
+                    }
                 }
                 if (mRunningBgJobs.size() == 1) {
                     // Started tracking the first job.
@@ -2270,7 +2286,6 @@
                     // repeatedly plugged in and unplugged, or an app changes foreground state
                     // very frequently, the job count for a package may be artificially high.
                     mBgJobCount = mRunningBgJobs.size();
-
                     if (mRegularJobTimer) {
                         incrementJobCountLocked(mPkg.userId, mPkg.packageName, mBgJobCount);
                         // Starting the timer means that all cached execution stats are now
@@ -2297,7 +2312,8 @@
                     return;
                 }
                 Message msg = mHandler.obtainMessage(
-                        mRegularJobTimer ? MSG_REACHED_QUOTA : MSG_REACHED_EJ_QUOTA, mPkg);
+                        mRegularJobTimer ? MSG_REACHED_TIME_QUOTA : MSG_REACHED_EJ_TIME_QUOTA,
+                        mPkg);
                 final long timeRemainingMs = mRegularJobTimer
                         ? getTimeUntilQuotaConsumedLocked(mPkg.userId, mPkg.packageName)
                         : getTimeUntilEJQuotaConsumedLocked(mPkg.userId, mPkg.packageName);
@@ -2314,7 +2330,7 @@
 
         private void cancelCutoff() {
             mHandler.removeMessages(
-                    mRegularJobTimer ? MSG_REACHED_QUOTA : MSG_REACHED_EJ_QUOTA, mPkg);
+                    mRegularJobTimer ? MSG_REACHED_TIME_QUOTA : MSG_REACHED_EJ_TIME_QUOTA, mPkg);
         }
 
         public void dump(IndentingPrintWriter pw, Predicate<JobStatus> predicate) {
@@ -2570,7 +2586,7 @@
                     break;
                 default:
                     if (DEBUG) {
-                        Slog.d(TAG, "Dropping event " + event.getEventType());
+                        Slog.d(TAG, "Dropping usage event " + event.getEventType());
                     }
                     break;
             }
@@ -2679,7 +2695,7 @@
         public void handleMessage(Message msg) {
             synchronized (mLock) {
                 switch (msg.what) {
-                    case MSG_REACHED_QUOTA: {
+                    case MSG_REACHED_TIME_QUOTA: {
                         UserPackage pkg = (UserPackage) msg.obj;
                         if (DEBUG) {
                             Slog.d(TAG, "Checking if " + pkg + " has reached its quota.");
@@ -2698,7 +2714,7 @@
                             // This could potentially happen if an old session phases out while a
                             // job is currently running.
                             // Reschedule message
-                            Message rescheduleMsg = obtainMessage(MSG_REACHED_QUOTA, pkg);
+                            Message rescheduleMsg = obtainMessage(MSG_REACHED_TIME_QUOTA, pkg);
                             timeRemainingMs = getTimeUntilQuotaConsumedLocked(pkg.userId,
                                     pkg.packageName);
                             if (DEBUG) {
@@ -2708,7 +2724,7 @@
                         }
                         break;
                     }
-                    case MSG_REACHED_EJ_QUOTA: {
+                    case MSG_REACHED_EJ_TIME_QUOTA: {
                         UserPackage pkg = (UserPackage) msg.obj;
                         if (DEBUG) {
                             Slog.d(TAG, "Checking if " + pkg + " has reached its EJ quota.");
@@ -2726,7 +2742,7 @@
                             // This could potentially happen if an old session phases out while a
                             // job is currently running.
                             // Reschedule message
-                            Message rescheduleMsg = obtainMessage(MSG_REACHED_EJ_QUOTA, pkg);
+                            Message rescheduleMsg = obtainMessage(MSG_REACHED_EJ_TIME_QUOTA, pkg);
                             timeRemainingMs = getTimeUntilEJQuotaConsumedLocked(
                                     pkg.userId, pkg.packageName);
                             if (DEBUG) {
@@ -2736,6 +2752,18 @@
                         }
                         break;
                     }
+                    case MSG_REACHED_COUNT_QUOTA: {
+                        UserPackage pkg = (UserPackage) msg.obj;
+                        if (DEBUG) {
+                            Slog.d(TAG, pkg + " has reached its count quota.");
+                        }
+
+                        mStateChangedListener.onControllerStateChanged(
+                                maybeUpdateConstraintForPkgLocked(
+                                        sElapsedRealtimeClock.millis(),
+                                        pkg.userId, pkg.packageName));
+                        break;
+                    }
                     case MSG_CLEAN_UP_SESSIONS:
                         if (DEBUG) {
                             Slog.d(TAG, "Cleaning up timing sessions.");
@@ -2948,8 +2976,7 @@
 
     @Override
     public void onConstantsUpdatedLocked() {
-        if (mQcConstants.mShouldReevaluateConstraints || mIsEnabled == mConstants.USE_TARE_POLICY) {
-            mIsEnabled = !mConstants.USE_TARE_POLICY;
+        if (mQcConstants.mShouldReevaluateConstraints) {
             // Update job bookkeeping out of band.
             AppSchedulingModuleThread.getHandler().post(() -> {
                 synchronized (mLock) {
@@ -4454,7 +4481,6 @@
     @Override
     public void dumpControllerStateLocked(final IndentingPrintWriter pw,
             final Predicate<JobStatus> predicate) {
-        pw.println("Is enabled: " + mIsEnabled);
         pw.println("Current elapsed time: " + sElapsedRealtimeClock.millis());
         pw.println();
 
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java
deleted file mode 100644
index 7408088..0000000
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java
+++ /dev/null
@@ -1,764 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.job.controllers;
-
-import static android.app.job.JobInfo.getPriorityString;
-
-import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
-
-import android.annotation.NonNull;
-import android.app.job.JobInfo;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.IndentingPrintWriter;
-import android.util.Log;
-import android.util.Slog;
-import android.util.SparseArrayMap;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.server.AppSchedulingModuleThread;
-import com.android.server.LocalServices;
-import com.android.server.job.JobSchedulerService;
-import com.android.server.tare.EconomicPolicy;
-import com.android.server.tare.EconomyManagerInternal;
-import com.android.server.tare.EconomyManagerInternal.ActionBill;
-import com.android.server.tare.JobSchedulerEconomicPolicy;
-
-import java.util.List;
-import java.util.function.Predicate;
-
-/**
- * Controller that interfaces with Tare ({@link EconomyManagerInternal} and manages each job's
- * ability to run per TARE policies.
- *
- * @see JobSchedulerEconomicPolicy
- */
-public class TareController extends StateController {
-    private static final String TAG = "JobScheduler.TARE";
-    private static final boolean DEBUG = JobSchedulerService.DEBUG
-            || Log.isLoggable(TAG, Log.DEBUG);
-
-    /**
-     * Bill to use while we're waiting to start a min priority job. If a job isn't running yet,
-     * don't consider it eligible to run unless it can pay for a job start and at least some
-     * period of execution time. We don't want min priority jobs to use up all available credits,
-     * so we make sure to only run them while there are enough credits to run higher priority jobs.
-     */
-    private static final ActionBill BILL_JOB_START_MIN =
-            new ActionBill(List.of(
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_START, 1, 0),
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, 0, 120_000L)
-            ));
-
-    /**
-     * Bill to use when a min priority job is currently running. We don't want min priority jobs
-     * to use up remaining credits, so we make sure to only run them while there are enough
-     * credits to run higher priority jobs. We stop the job when the app's credits get too low.
-     */
-    private static final ActionBill BILL_JOB_RUNNING_MIN =
-            new ActionBill(List.of(
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, 0, 60_000L)
-            ));
-
-    /**
-     * Bill to use while we're waiting to start a low priority job. If a job isn't running yet,
-     * don't consider it eligible to run unless it can pay for a job start and at least some
-     * period of execution time. We don't want low priority jobs to use up all available credits,
-     * so we make sure to only run them while there are enough credits to run higher priority jobs.
-     */
-    private static final ActionBill BILL_JOB_START_LOW =
-            new ActionBill(List.of(
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_START, 1, 0),
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, 0, 60_000L)
-            ));
-
-    /**
-     * Bill to use when a low priority job is currently running. We don't want low priority jobs
-     * to use up all available credits, so we make sure to only run them while there are enough
-     * credits to run higher priority jobs. We stop the job when the app's credits get too low.
-     */
-    private static final ActionBill BILL_JOB_RUNNING_LOW =
-            new ActionBill(List.of(
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, 0, 30_000L)
-            ));
-
-    /**
-     * Bill to use while we're waiting to start a job. If a job isn't running yet, don't consider it
-     * eligible to run unless it can pay for a job start and at least some period of execution time.
-     */
-    private static final ActionBill BILL_JOB_START_DEFAULT =
-            new ActionBill(List.of(
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_START, 1, 0),
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, 0, 30_000L)
-            ));
-
-    /**
-     * Bill to use when a default priority job is currently running. We want to track and make
-     * sure the app can continue to pay for 1 more second of execution time. We stop the job when
-     * the app can no longer pay for that time.
-     */
-    private static final ActionBill BILL_JOB_RUNNING_DEFAULT =
-            new ActionBill(List.of(
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, 0, 1_000L)
-            ));
-
-    /**
-     * Bill to use while we're waiting to start a job. If a job isn't running yet, don't consider it
-     * eligible to run unless it can pay for a job start and at least some period of execution time.
-     */
-    private static final ActionBill BILL_JOB_START_HIGH =
-            new ActionBill(List.of(
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_START, 1, 0),
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING, 0, 30_000L)
-            ));
-
-    /**
-     * Bill to use when a high priority job is currently running. We want to track and make sure
-     * the app can continue to pay for 1 more second of execution time. We stop the job when the
-     * app can no longer pay for that time.
-     */
-    private static final ActionBill BILL_JOB_RUNNING_HIGH =
-            new ActionBill(List.of(
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING, 0, 1_000L)
-            ));
-
-
-    /**
-     * Bill to use while we're waiting to start a max priority job. This should only be used for
-     * requested-EJs that aren't allowed to run as EJs. If a job isn't running yet, don't consider
-     * it eligible to run unless it can pay for a job start and at least some period of execution
-     * time.
-     */
-    private static final ActionBill BILL_JOB_START_MAX =
-            new ActionBill(List.of(
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 1, 0),
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING, 0, 30_000L)
-            ));
-
-    /**
-     * Bill to use when a max priority job is currently running. This should only be used for
-     * requested-EJs that aren't allowed to run as EJs. We want to track and make sure
-     * the app can continue to pay for 1 more second of execution time. We stop the job when the
-     * app can no longer pay for that time.
-     */
-    private static final ActionBill BILL_JOB_RUNNING_MAX =
-            new ActionBill(List.of(
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING, 0, 1_000L)
-            ));
-
-    /**
-     * Bill to use while we're waiting to start a job. If a job isn't running yet, don't consider it
-     * eligible to run unless it can pay for a job start and at least some period of execution time.
-     */
-    private static final ActionBill BILL_JOB_START_MAX_EXPEDITED =
-            new ActionBill(List.of(
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 1, 0),
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING, 0, 30_000L)
-            ));
-
-    /**
-     * Bill to use when a max priority EJ is currently running (as an EJ). We want to track and
-     * make sure the app can continue to pay for 1 more second of execution time. We stop the job
-     * when the app can no longer pay for that time.
-     */
-    private static final ActionBill BILL_JOB_RUNNING_MAX_EXPEDITED =
-            new ActionBill(List.of(
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING, 0, 1_000L)
-            ));
-
-    /**
-     * Bill to use while we're waiting to start a job. If a job isn't running yet, don't consider it
-     * eligible to run unless it can pay for a job start and at least some period of execution time.
-     */
-    private static final ActionBill BILL_JOB_START_HIGH_EXPEDITED =
-            new ActionBill(List.of(
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_START, 1, 0),
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING, 0, 30_000L)
-            ));
-
-    /**
-     * Bill to use when a high priority EJ is currently running (as an EJ). We want to track and
-     * make sure the app can continue to pay for 1 more second of execution time. We stop the job
-     * when the app can no longer pay for that time.
-     */
-    private static final ActionBill BILL_JOB_RUNNING_HIGH_EXPEDITED =
-            new ActionBill(List.of(
-                    new EconomyManagerInternal.AnticipatedAction(
-                            JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING, 0, 1_000L)
-            ));
-
-    private final EconomyManagerInternal mEconomyManagerInternal;
-
-    private final BackgroundJobsController mBackgroundJobsController;
-    private final ConnectivityController mConnectivityController;
-
-    /**
-     * Local cache of the ability of each userId-pkg to afford the various bills we're tracking for
-     * them.
-     */
-    @GuardedBy("mLock")
-    private final SparseArrayMap<String, ArrayMap<ActionBill, Boolean>> mAffordabilityCache =
-            new SparseArrayMap<>();
-
-    /**
-     * List of all tracked jobs. Out SparseArrayMap is userId-sourcePkg. The inner mapping is the
-     * anticipated actions and all the jobs that are applicable to them.
-     */
-    @GuardedBy("mLock")
-    private final SparseArrayMap<String, ArrayMap<ActionBill, ArraySet<JobStatus>>>
-            mRegisteredBillsAndJobs = new SparseArrayMap<>();
-
-    private final EconomyManagerInternal.AffordabilityChangeListener mAffordabilityChangeListener =
-            (userId, pkgName, bill, canAfford) -> {
-                final long nowElapsed = sElapsedRealtimeClock.millis();
-                if (DEBUG) {
-                    Slog.d(TAG,
-                            userId + ":" + pkgName + " affordability for " + getBillName(bill)
-                                    + " changed to " + canAfford);
-                }
-                synchronized (mLock) {
-                    ArrayMap<ActionBill, Boolean> actionAffordability =
-                            mAffordabilityCache.get(userId, pkgName);
-                    if (actionAffordability == null) {
-                        actionAffordability = new ArrayMap<>();
-                        mAffordabilityCache.add(userId, pkgName, actionAffordability);
-                    }
-                    actionAffordability.put(bill, canAfford);
-
-                    final ArrayMap<ActionBill, ArraySet<JobStatus>> billToJobMap =
-                            mRegisteredBillsAndJobs.get(userId, pkgName);
-                    if (billToJobMap != null) {
-                        final ArraySet<JobStatus> jobs = billToJobMap.get(bill);
-                        if (jobs != null) {
-                            final ArraySet<JobStatus> changedJobs = new ArraySet<>();
-                            for (int i = 0; i < jobs.size(); ++i) {
-                                final JobStatus job = jobs.valueAt(i);
-                                // Use hasEnoughWealth if canAfford is false in case the job has
-                                // other bills it can depend on (eg. EJs being demoted to
-                                // regular jobs).
-                                if (job.setTareWealthConstraintSatisfied(nowElapsed,
-                                        canAfford || hasEnoughWealthLocked(job))) {
-                                    changedJobs.add(job);
-                                }
-                                if (job.isRequestedExpeditedJob()
-                                        && setExpeditedTareApproved(job, nowElapsed,
-                                        canAffordExpeditedBillLocked(job))) {
-                                    changedJobs.add(job);
-                                }
-                            }
-                            if (changedJobs.size() > 0) {
-                                mStateChangedListener.onControllerStateChanged(changedJobs);
-                            }
-                        }
-                    }
-                }
-            };
-
-    /**
-     * List of jobs that started while the UID was in the TOP state. There will usually be no more
-     * than {@value JobConcurrencyManager#MAX_STANDARD_JOB_CONCURRENCY} running at once, so an
-     * ArraySet is fine.
-     */
-    @GuardedBy("mLock")
-    private final ArraySet<JobStatus> mTopStartedJobs = new ArraySet<>();
-
-    @GuardedBy("mLock")
-    private boolean mIsEnabled;
-
-    public TareController(JobSchedulerService service,
-            @NonNull BackgroundJobsController backgroundJobsController,
-            @NonNull ConnectivityController connectivityController) {
-        super(service);
-        mBackgroundJobsController = backgroundJobsController;
-        mConnectivityController = connectivityController;
-        mEconomyManagerInternal = LocalServices.getService(EconomyManagerInternal.class);
-        mIsEnabled = mConstants.USE_TARE_POLICY;
-    }
-
-    @Override
-    @GuardedBy("mLock")
-    public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
-        final long nowElapsed = sElapsedRealtimeClock.millis();
-        if (jobStatus.shouldTreatAsUserInitiatedJob()) {
-            // User-initiated jobs should always be allowed to run.
-            jobStatus.setTareWealthConstraintSatisfied(nowElapsed, true);
-            return;
-        }
-        jobStatus.setTareWealthConstraintSatisfied(nowElapsed, hasEnoughWealthLocked(jobStatus));
-        setExpeditedTareApproved(jobStatus, nowElapsed,
-                jobStatus.isRequestedExpeditedJob() && canAffordExpeditedBillLocked(jobStatus));
-
-        final ArraySet<ActionBill> bills = getPossibleStartBills(jobStatus);
-        for (int i = 0; i < bills.size(); ++i) {
-            addJobToBillList(jobStatus, bills.valueAt(i));
-        }
-    }
-
-    @Override
-    @GuardedBy("mLock")
-    public void prepareForExecutionLocked(JobStatus jobStatus) {
-        if (jobStatus.shouldTreatAsUserInitiatedJob()) {
-            // TODO(202954395): consider noting execution with the EconomyManager even though it
-            //                  won't affect this job
-            return;
-        }
-        final int userId = jobStatus.getSourceUserId();
-        final String pkgName = jobStatus.getSourcePackageName();
-        ArrayMap<ActionBill, ArraySet<JobStatus>> billToJobMap =
-                mRegisteredBillsAndJobs.get(userId, pkgName);
-        if (billToJobMap == null) {
-            Slog.e(TAG, "Job is being prepared but doesn't have a pre-existing billToJobMap");
-        } else {
-            for (int i = 0; i < billToJobMap.size(); ++i) {
-                removeJobFromBillList(jobStatus, billToJobMap.keyAt(i));
-            }
-        }
-
-        final int uid = jobStatus.getSourceUid();
-        if (mService.getUidBias(uid) == JobInfo.BIAS_TOP_APP) {
-            if (DEBUG) {
-                Slog.d(TAG, jobStatus.toShortString() + " is top started job");
-            }
-            mTopStartedJobs.add(jobStatus);
-            // Top jobs won't count towards quota so there's no need to involve the EconomyManager.
-        } else {
-            addJobToBillList(jobStatus, getRunningBill(jobStatus));
-            mEconomyManagerInternal.noteOngoingEventStarted(userId, pkgName,
-                    getRunningActionId(jobStatus), String.valueOf(jobStatus.getJobId()));
-        }
-    }
-
-    @Override
-    @GuardedBy("mLock")
-    public void unprepareFromExecutionLocked(JobStatus jobStatus) {
-        if (jobStatus.shouldTreatAsUserInitiatedJob()) {
-            return;
-        }
-        final int userId = jobStatus.getSourceUserId();
-        final String pkgName = jobStatus.getSourcePackageName();
-        // If this method is called, then jobStatus.madeActive was never updated, so don't use it
-        // to determine if the EconomyManager was notified.
-        if (!mTopStartedJobs.remove(jobStatus)) {
-            // If the job was started while the app was top, then the EconomyManager wasn't notified
-            // of the job start.
-            mEconomyManagerInternal.noteOngoingEventStopped(userId, pkgName,
-                    getRunningActionId(jobStatus), String.valueOf(jobStatus.getJobId()));
-        }
-
-        final ArraySet<ActionBill> bills = getPossibleStartBills(jobStatus);
-        ArrayMap<ActionBill, ArraySet<JobStatus>> billToJobMap =
-                mRegisteredBillsAndJobs.get(userId, pkgName);
-        if (billToJobMap == null) {
-            Slog.e(TAG, "Job was just unprepared but didn't have a pre-existing billToJobMap");
-        } else {
-            for (int i = 0; i < billToJobMap.size(); ++i) {
-                removeJobFromBillList(jobStatus, billToJobMap.keyAt(i));
-            }
-        }
-        for (int i = 0; i < bills.size(); ++i) {
-            addJobToBillList(jobStatus, bills.valueAt(i));
-        }
-    }
-
-    @Override
-    @GuardedBy("mLock")
-    public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob) {
-        if (jobStatus.shouldTreatAsUserInitiatedJob()) {
-            return;
-        }
-        final int userId = jobStatus.getSourceUserId();
-        final String pkgName = jobStatus.getSourcePackageName();
-        if (!mTopStartedJobs.remove(jobStatus) && jobStatus.madeActive > 0) {
-            // Only note the job stop if we previously told the EconomyManager that the job started.
-            // If the job was started while the app was top, then the EconomyManager wasn't notified
-            // of the job start.
-            mEconomyManagerInternal.noteOngoingEventStopped(userId, pkgName,
-                    getRunningActionId(jobStatus), String.valueOf(jobStatus.getJobId()));
-        }
-        ArrayMap<ActionBill, ArraySet<JobStatus>> billToJobMap =
-                mRegisteredBillsAndJobs.get(userId, pkgName);
-        if (billToJobMap != null) {
-            for (int i = 0; i < billToJobMap.size(); ++i) {
-                removeJobFromBillList(jobStatus, billToJobMap.keyAt(i));
-            }
-        }
-    }
-
-    @Override
-    @GuardedBy("mLock")
-    public void onConstantsUpdatedLocked() {
-        if (mIsEnabled != mConstants.USE_TARE_POLICY) {
-            mIsEnabled = mConstants.USE_TARE_POLICY;
-            // Update job bookkeeping out of band.
-            AppSchedulingModuleThread.getHandler().post(() -> {
-                synchronized (mLock) {
-                    final long nowElapsed = sElapsedRealtimeClock.millis();
-                    mService.getJobStore().forEachJob((jobStatus) -> {
-                        if (!mIsEnabled) {
-                            jobStatus.setTareWealthConstraintSatisfied(nowElapsed, true);
-                            setExpeditedTareApproved(jobStatus, nowElapsed, true);
-                        } else {
-                            jobStatus.setTareWealthConstraintSatisfied(
-                                    nowElapsed, hasEnoughWealthLocked(jobStatus));
-                            setExpeditedTareApproved(jobStatus, nowElapsed,
-                                    jobStatus.isRequestedExpeditedJob()
-                                            && canAffordExpeditedBillLocked(jobStatus));
-                        }
-                    });
-                }
-            });
-        }
-    }
-
-    @GuardedBy("mLock")
-    public boolean canScheduleEJ(@NonNull JobStatus jobStatus) {
-        if (!mIsEnabled) {
-            return true;
-        }
-        if (jobStatus.getEffectivePriority() == JobInfo.PRIORITY_MAX) {
-            return canAffordBillLocked(jobStatus, BILL_JOB_START_MAX_EXPEDITED);
-        }
-        return canAffordBillLocked(jobStatus, BILL_JOB_START_HIGH_EXPEDITED);
-    }
-
-    /** @return true if the job was started while the app was in the TOP state. */
-    @GuardedBy("mLock")
-    private boolean isTopStartedJobLocked(@NonNull final JobStatus jobStatus) {
-        return mTopStartedJobs.contains(jobStatus);
-    }
-
-    @GuardedBy("mLock")
-    public long getMaxJobExecutionTimeMsLocked(@NonNull JobStatus jobStatus) {
-        if (!mIsEnabled) {
-            return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS;
-        }
-        return mEconomyManagerInternal.getMaxDurationMs(
-                jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(),
-                getRunningBill(jobStatus));
-    }
-
-    @GuardedBy("mLock")
-    private void addJobToBillList(@NonNull JobStatus jobStatus, @NonNull ActionBill bill) {
-        final int userId = jobStatus.getSourceUserId();
-        final String pkgName = jobStatus.getSourcePackageName();
-        ArrayMap<ActionBill, ArraySet<JobStatus>> billToJobMap =
-                mRegisteredBillsAndJobs.get(userId, pkgName);
-        if (billToJobMap == null) {
-            billToJobMap = new ArrayMap<>();
-            mRegisteredBillsAndJobs.add(userId, pkgName, billToJobMap);
-        }
-        ArraySet<JobStatus> jobs = billToJobMap.get(bill);
-        if (jobs == null) {
-            jobs = new ArraySet<>();
-            billToJobMap.put(bill, jobs);
-        }
-        if (jobs.add(jobStatus)) {
-            mEconomyManagerInternal.registerAffordabilityChangeListener(userId, pkgName,
-                    mAffordabilityChangeListener, bill);
-        }
-    }
-
-    @GuardedBy("mLock")
-    private void removeJobFromBillList(@NonNull JobStatus jobStatus, @NonNull ActionBill bill) {
-        final int userId = jobStatus.getSourceUserId();
-        final String pkgName = jobStatus.getSourcePackageName();
-        final ArrayMap<ActionBill, ArraySet<JobStatus>> billToJobMap =
-                mRegisteredBillsAndJobs.get(userId, pkgName);
-        if (billToJobMap != null) {
-            final ArraySet<JobStatus> jobs = billToJobMap.get(bill);
-            if (jobs == null || (jobs.remove(jobStatus) && jobs.size() == 0)) {
-                mEconomyManagerInternal.unregisterAffordabilityChangeListener(
-                        userId, pkgName, mAffordabilityChangeListener, bill);
-                // Remove the cached value so we don't accidentally use it when the app
-                // schedules a new job.
-                final ArrayMap<ActionBill, Boolean> actionAffordability =
-                        mAffordabilityCache.get(userId, pkgName);
-                if (actionAffordability != null) {
-                    actionAffordability.remove(bill);
-                }
-            }
-        }
-    }
-
-    @NonNull
-    private ArraySet<ActionBill> getPossibleStartBills(JobStatus jobStatus) {
-        // TODO: factor in network cost when available
-        final ArraySet<ActionBill> bills = new ArraySet<>();
-        if (jobStatus.isRequestedExpeditedJob()) {
-            if (jobStatus.getEffectivePriority() == JobInfo.PRIORITY_MAX) {
-                bills.add(BILL_JOB_START_MAX_EXPEDITED);
-            } else {
-                bills.add(BILL_JOB_START_HIGH_EXPEDITED);
-            }
-        }
-        switch (jobStatus.getEffectivePriority()) {
-            case JobInfo.PRIORITY_MAX:
-                bills.add(BILL_JOB_START_MAX);
-                break;
-            case JobInfo.PRIORITY_HIGH:
-                bills.add(BILL_JOB_START_HIGH);
-                break;
-            case JobInfo.PRIORITY_DEFAULT:
-                bills.add(BILL_JOB_START_DEFAULT);
-                break;
-            case JobInfo.PRIORITY_LOW:
-                bills.add(BILL_JOB_START_LOW);
-                break;
-            case JobInfo.PRIORITY_MIN:
-                bills.add(BILL_JOB_START_MIN);
-                break;
-            default:
-                Slog.wtf(TAG, "Unexpected priority: "
-                        + JobInfo.getPriorityString(jobStatus.getEffectivePriority()));
-                break;
-        }
-        return bills;
-    }
-
-    @NonNull
-    private ActionBill getRunningBill(JobStatus jobStatus) {
-        // TODO: factor in network cost when available
-        if (jobStatus.shouldTreatAsExpeditedJob() || jobStatus.startedAsExpeditedJob) {
-            if (jobStatus.getEffectivePriority() == JobInfo.PRIORITY_MAX) {
-                return BILL_JOB_RUNNING_MAX_EXPEDITED;
-            } else {
-                return BILL_JOB_RUNNING_HIGH_EXPEDITED;
-            }
-        }
-        switch (jobStatus.getEffectivePriority()) {
-            case JobInfo.PRIORITY_MAX:
-                return BILL_JOB_RUNNING_MAX;
-            case JobInfo.PRIORITY_HIGH:
-                return BILL_JOB_RUNNING_HIGH;
-            case JobInfo.PRIORITY_LOW:
-                return BILL_JOB_RUNNING_LOW;
-            case JobInfo.PRIORITY_MIN:
-                return BILL_JOB_RUNNING_MIN;
-            default:
-                Slog.wtf(TAG, "Got unexpected priority: " + jobStatus.getEffectivePriority());
-                // Intentional fallthrough
-            case JobInfo.PRIORITY_DEFAULT:
-                return BILL_JOB_RUNNING_DEFAULT;
-        }
-    }
-
-    @EconomicPolicy.AppAction
-    private static int getRunningActionId(@NonNull JobStatus job) {
-        switch (job.getEffectivePriority()) {
-            case JobInfo.PRIORITY_MAX:
-                return JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING;
-            case JobInfo.PRIORITY_HIGH:
-                return JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING;
-            case JobInfo.PRIORITY_LOW:
-                return JobSchedulerEconomicPolicy.ACTION_JOB_LOW_RUNNING;
-            case JobInfo.PRIORITY_MIN:
-                return JobSchedulerEconomicPolicy.ACTION_JOB_MIN_RUNNING;
-            default:
-                Slog.wtf(TAG, "Unknown priority: " + getPriorityString(job.getEffectivePriority()));
-                // Intentional fallthrough
-            case JobInfo.PRIORITY_DEFAULT:
-                return JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING;
-        }
-    }
-
-    @GuardedBy("mLock")
-    private boolean canAffordBillLocked(@NonNull JobStatus jobStatus, @NonNull ActionBill bill) {
-        if (!mIsEnabled) {
-            return true;
-        }
-        if (mService.getUidBias(jobStatus.getSourceUid()) == JobInfo.BIAS_TOP_APP
-                || isTopStartedJobLocked(jobStatus)) {
-            // Jobs for the top app should always be allowed to run, and any jobs started while
-            // the app is on top shouldn't consume any credits.
-            return true;
-        }
-        final int userId = jobStatus.getSourceUserId();
-        final String pkgName = jobStatus.getSourcePackageName();
-        ArrayMap<ActionBill, Boolean> actionAffordability =
-                mAffordabilityCache.get(userId, pkgName);
-        if (actionAffordability == null) {
-            actionAffordability = new ArrayMap<>();
-            mAffordabilityCache.add(userId, pkgName, actionAffordability);
-        }
-
-        if (actionAffordability.containsKey(bill)) {
-            return actionAffordability.get(bill);
-        }
-
-        final boolean canAfford = mEconomyManagerInternal.canPayFor(userId, pkgName, bill);
-        actionAffordability.put(bill, canAfford);
-        return canAfford;
-    }
-
-    @GuardedBy("mLock")
-    private boolean canAffordExpeditedBillLocked(@NonNull JobStatus jobStatus) {
-        if (!mIsEnabled) {
-            return true;
-        }
-        if (!jobStatus.isRequestedExpeditedJob()) {
-            return false;
-        }
-        if (mService.getUidBias(jobStatus.getSourceUid()) == JobInfo.BIAS_TOP_APP
-                || isTopStartedJobLocked(jobStatus)) {
-            // Jobs for the top app should always be allowed to run, and any jobs started while
-            // the app is on top shouldn't consume any credits.
-            return true;
-        }
-        if (mService.isCurrentlyRunningLocked(jobStatus)) {
-            return canAffordBillLocked(jobStatus, getRunningBill(jobStatus));
-        }
-
-        if (jobStatus.getEffectivePriority() == JobInfo.PRIORITY_MAX) {
-            return canAffordBillLocked(jobStatus, BILL_JOB_START_MAX_EXPEDITED);
-        }
-        return canAffordBillLocked(jobStatus, BILL_JOB_START_HIGH_EXPEDITED);
-    }
-
-    @GuardedBy("mLock")
-    private boolean hasEnoughWealthLocked(@NonNull JobStatus jobStatus) {
-        if (!mIsEnabled) {
-            return true;
-        }
-        if (jobStatus.shouldTreatAsUserInitiatedJob()) {
-            // Always allow user-initiated jobs.
-            return true;
-        }
-        if (mService.getUidBias(jobStatus.getSourceUid()) == JobInfo.BIAS_TOP_APP
-                || isTopStartedJobLocked(jobStatus)) {
-            // Jobs for the top app should always be allowed to run, and any jobs started while
-            // the app is on top shouldn't consume any credits.
-            return true;
-        }
-        if (mService.isCurrentlyRunningLocked(jobStatus)) {
-            return canAffordBillLocked(jobStatus, getRunningBill(jobStatus));
-        }
-
-        final ArraySet<ActionBill> bills = getPossibleStartBills(jobStatus);
-        for (int i = 0; i < bills.size(); ++i) {
-            ActionBill bill = bills.valueAt(i);
-            if (canAffordBillLocked(jobStatus, bill)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * If the satisfaction changes, this will tell connectivity & background jobs controller to
-     * also re-evaluate their state.
-     */
-    private boolean setExpeditedTareApproved(@NonNull JobStatus jobStatus, long nowElapsed,
-            boolean isApproved) {
-        if (jobStatus.setExpeditedJobTareApproved(nowElapsed, isApproved)) {
-            mBackgroundJobsController.evaluateStateLocked(jobStatus);
-            mConnectivityController.evaluateStateLocked(jobStatus);
-            if (isApproved && jobStatus.isReady()) {
-                mStateChangedListener.onRunJobNow(jobStatus);
-            }
-            return true;
-        }
-        return false;
-    }
-
-    @NonNull
-    private String getBillName(@NonNull ActionBill bill) {
-        if (bill.equals(BILL_JOB_START_MAX_EXPEDITED)) {
-            return "EJ_MAX_START_BILL";
-        }
-        if (bill.equals(BILL_JOB_RUNNING_MAX_EXPEDITED)) {
-            return "EJ_MAX_RUNNING_BILL";
-        }
-        if (bill.equals(BILL_JOB_START_HIGH_EXPEDITED)) {
-            return "EJ_HIGH_START_BILL";
-        }
-        if (bill.equals(BILL_JOB_RUNNING_HIGH_EXPEDITED)) {
-            return "EJ_HIGH_RUNNING_BILL";
-        }
-        if (bill.equals(BILL_JOB_START_HIGH)) {
-            return "HIGH_START_BILL";
-        }
-        if (bill.equals(BILL_JOB_RUNNING_HIGH)) {
-            return "HIGH_RUNNING_BILL";
-        }
-        if (bill.equals(BILL_JOB_START_DEFAULT)) {
-            return "DEFAULT_START_BILL";
-        }
-        if (bill.equals(BILL_JOB_RUNNING_DEFAULT)) {
-            return "DEFAULT_RUNNING_BILL";
-        }
-        if (bill.equals(BILL_JOB_START_LOW)) {
-            return "LOW_START_BILL";
-        }
-        if (bill.equals(BILL_JOB_RUNNING_LOW)) {
-            return "LOW_RUNNING_BILL";
-        }
-        if (bill.equals(BILL_JOB_START_MIN)) {
-            return "MIN_START_BILL";
-        }
-        if (bill.equals(BILL_JOB_RUNNING_MIN)) {
-            return "MIN_RUNNING_BILL";
-        }
-        return "UNKNOWN_BILL (" + bill + ")";
-    }
-
-    @Override
-    public void dumpControllerStateLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate) {
-        pw.print("Is enabled: ");
-        pw.println(mIsEnabled);
-
-        pw.println("Affordability cache:");
-        pw.increaseIndent();
-        mAffordabilityCache.forEach((userId, pkgName, billMap) -> {
-            final int numBills = billMap.size();
-            if (numBills > 0) {
-                pw.print(userId);
-                pw.print(":");
-                pw.print(pkgName);
-                pw.println(":");
-
-                pw.increaseIndent();
-                for (int i = 0; i < numBills; ++i) {
-                    pw.print(getBillName(billMap.keyAt(i)));
-                    pw.print(": ");
-                    pw.println(billMap.valueAt(i));
-                }
-                pw.decreaseIndent();
-            }
-        });
-        pw.decreaseIndent();
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Agent.java b/apex/jobscheduler/service/java/com/android/server/tare/Agent.java
deleted file mode 100644
index 5c60562..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/Agent.java
+++ /dev/null
@@ -1,1362 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static android.app.tare.EconomyManager.ENABLED_MODE_OFF;
-import static android.text.format.DateUtils.DAY_IN_MILLIS;
-
-import static com.android.server.tare.EconomicPolicy.REGULATION_BASIC_INCOME;
-import static com.android.server.tare.EconomicPolicy.REGULATION_BG_RESTRICTED;
-import static com.android.server.tare.EconomicPolicy.REGULATION_BG_UNRESTRICTED;
-import static com.android.server.tare.EconomicPolicy.REGULATION_BIRTHRIGHT;
-import static com.android.server.tare.EconomicPolicy.REGULATION_DEMOTION;
-import static com.android.server.tare.EconomicPolicy.REGULATION_PROMOTION;
-import static com.android.server.tare.EconomicPolicy.REGULATION_WEALTH_RECLAMATION;
-import static com.android.server.tare.EconomicPolicy.TYPE_ACTION;
-import static com.android.server.tare.EconomicPolicy.TYPE_REWARD;
-import static com.android.server.tare.EconomicPolicy.eventToString;
-import static com.android.server.tare.EconomicPolicy.getEventType;
-import static com.android.server.tare.TareUtils.appToString;
-import static com.android.server.tare.TareUtils.cakeToString;
-import static com.android.server.tare.TareUtils.getCurrentTimeMillis;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.pm.UserPackage;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.ArraySet;
-import android.util.IndentingPrintWriter;
-import android.util.Log;
-import android.util.Slog;
-import android.util.SparseArrayMap;
-import android.util.SparseSetArray;
-import android.util.TimeUtils;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.LocalServices;
-import com.android.server.pm.UserManagerInternal;
-import com.android.server.usage.AppStandbyInternal;
-import com.android.server.utils.AlarmQueue;
-
-import java.util.List;
-import java.util.Objects;
-import java.util.function.Consumer;
-
-/**
- * Other half of the IRS. The agent handles the nitty gritty details, interacting directly with
- * ledgers, carrying out specific events such as wealth reclamation, granting initial balances or
- * replenishing balances, and tracking ongoing events.
- */
-class Agent {
-    private static final String TAG = "TARE-" + Agent.class.getSimpleName();
-    private static final boolean DEBUG = InternalResourceService.DEBUG
-            || Log.isLoggable(TAG, Log.DEBUG);
-
-    private static final String ALARM_TAG_AFFORDABILITY_CHECK = "*tare.affordability_check*";
-
-    private final Object mLock;
-    private final AgentHandler mHandler;
-    private final Analyst mAnalyst;
-    private final InternalResourceService mIrs;
-    private final Scribe mScribe;
-
-    private final AppStandbyInternal mAppStandbyInternal;
-
-    @GuardedBy("mLock")
-    private final SparseArrayMap<String, SparseArrayMap<String, OngoingEvent>>
-            mCurrentOngoingEvents = new SparseArrayMap<>();
-
-    /**
-     * Set of {@link ActionAffordabilityNote ActionAffordabilityNotes} keyed by userId-pkgName.
-     *
-     * Note: it would be nice/better to sort by base price since that doesn't change and simply
-     * look at the change in the "insertion" of what would be affordable, but since CTP
-     * is factored into the final price, the sorting order (by modified price) could be different
-     * and that method wouldn't work >:(
-     */
-    @GuardedBy("mLock")
-    private final SparseArrayMap<String, ArraySet<ActionAffordabilityNote>>
-            mActionAffordabilityNotes = new SparseArrayMap<>();
-
-    /**
-     * Queue to track and manage when apps will cross the closest affordability threshold (in
-     * both directions).
-     */
-    @GuardedBy("mLock")
-    private final BalanceThresholdAlarmQueue mBalanceThresholdAlarmQueue;
-
-    /**
-     * Check the affordability notes of all apps.
-     */
-    private static final int MSG_CHECK_ALL_AFFORDABILITY = 0;
-    /**
-     * Check the affordability notes of a single app.
-     */
-    private static final int MSG_CHECK_INDIVIDUAL_AFFORDABILITY = 1;
-
-    Agent(@NonNull InternalResourceService irs, @NonNull Scribe scribe, @NonNull Analyst analyst) {
-        mLock = irs.getLock();
-        mIrs = irs;
-        mScribe = scribe;
-        mAnalyst = analyst;
-        mHandler = new AgentHandler(TareHandlerThread.get().getLooper());
-        mAppStandbyInternal = LocalServices.getService(AppStandbyInternal.class);
-        mBalanceThresholdAlarmQueue = new BalanceThresholdAlarmQueue(
-                mIrs.getContext(), TareHandlerThread.get().getLooper());
-    }
-
-    private class TotalDeltaCalculator implements Consumer<OngoingEvent> {
-        private Ledger mLedger;
-        private long mNowElapsed;
-        private long mNow;
-        private long mTotal;
-
-        void reset(@NonNull Ledger ledger, long nowElapsed, long now) {
-            mLedger = ledger;
-            mNowElapsed = nowElapsed;
-            mNow = now;
-            mTotal = 0;
-        }
-
-        @Override
-        public void accept(OngoingEvent ongoingEvent) {
-            mTotal += getActualDeltaLocked(ongoingEvent, mLedger, mNowElapsed, mNow).price;
-        }
-    }
-
-    @GuardedBy("mLock")
-    private final TotalDeltaCalculator mTotalDeltaCalculator = new TotalDeltaCalculator();
-
-    /** Get an app's current balance, factoring in any currently ongoing events. */
-    @GuardedBy("mLock")
-    long getBalanceLocked(final int userId, @NonNull final String pkgName) {
-        final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);
-        long balance = ledger.getCurrentBalance();
-        SparseArrayMap<String, OngoingEvent> ongoingEvents =
-                mCurrentOngoingEvents.get(userId, pkgName);
-        if (ongoingEvents != null) {
-            final long nowElapsed = SystemClock.elapsedRealtime();
-            final long now = getCurrentTimeMillis();
-            mTotalDeltaCalculator.reset(ledger, nowElapsed, now);
-            ongoingEvents.forEach(mTotalDeltaCalculator);
-            balance += mTotalDeltaCalculator.mTotal;
-        }
-        return balance;
-    }
-
-    @GuardedBy("mLock")
-    private boolean isAffordableLocked(long balance, long price, long stockLimitHonoringCtp) {
-        return balance >= price
-                && mScribe.getRemainingConsumableCakesLocked() >= stockLimitHonoringCtp;
-    }
-
-    @GuardedBy("mLock")
-    void noteInstantaneousEventLocked(final int userId, @NonNull final String pkgName,
-            final int eventId, @Nullable String tag) {
-        if (mIrs.isSystem(userId, pkgName)) {
-            // Events are free for the system. Don't bother recording them.
-            return;
-        }
-
-        final long now = getCurrentTimeMillis();
-        final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);
-        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
-
-        final int eventType = getEventType(eventId);
-        switch (eventType) {
-            case TYPE_ACTION:
-                final EconomicPolicy.Cost actionCost =
-                        economicPolicy.getCostOfAction(eventId, userId, pkgName);
-
-                recordTransactionLocked(userId, pkgName, ledger,
-                        new Ledger.Transaction(now, now, eventId, tag,
-                                -actionCost.price, actionCost.costToProduce),
-                        true);
-                break;
-
-            case TYPE_REWARD:
-                final EconomicPolicy.Reward reward = economicPolicy.getReward(eventId);
-                if (reward != null) {
-                    final long rewardSum = ledger.get24HourSum(eventId, now);
-                    final long rewardVal = Math.max(0,
-                            Math.min(reward.maxDailyReward - rewardSum, reward.instantReward));
-                    recordTransactionLocked(userId, pkgName, ledger,
-                            new Ledger.Transaction(now, now, eventId, tag, rewardVal, 0), true);
-                }
-                break;
-
-            default:
-                Slog.w(TAG, "Unsupported event type: " + eventType);
-        }
-        scheduleBalanceCheckLocked(userId, pkgName);
-    }
-
-    @GuardedBy("mLock")
-    void noteOngoingEventLocked(final int userId, @NonNull final String pkgName, final int eventId,
-            @Nullable String tag, final long startElapsed) {
-        noteOngoingEventLocked(userId, pkgName, eventId, tag, startElapsed, true);
-    }
-
-    @GuardedBy("mLock")
-    private void noteOngoingEventLocked(final int userId, @NonNull final String pkgName,
-            final int eventId, @Nullable String tag, final long startElapsed,
-            final boolean updateBalanceCheck) {
-        if (mIrs.isSystem(userId, pkgName)) {
-            // Events are free for the system. Don't bother recording them.
-            return;
-        }
-
-        SparseArrayMap<String, OngoingEvent> ongoingEvents =
-                mCurrentOngoingEvents.get(userId, pkgName);
-        if (ongoingEvents == null) {
-            ongoingEvents = new SparseArrayMap<>();
-            mCurrentOngoingEvents.add(userId, pkgName, ongoingEvents);
-        }
-        OngoingEvent ongoingEvent = ongoingEvents.get(eventId, tag);
-
-        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
-        final int eventType = getEventType(eventId);
-        switch (eventType) {
-            case TYPE_ACTION:
-                final EconomicPolicy.Cost actionCost =
-                        economicPolicy.getCostOfAction(eventId, userId, pkgName);
-
-                if (ongoingEvent == null) {
-                    ongoingEvents.add(eventId, tag,
-                            new OngoingEvent(eventId, tag, startElapsed, actionCost));
-                } else {
-                    ongoingEvent.refCount++;
-                }
-                break;
-
-            case TYPE_REWARD:
-                final EconomicPolicy.Reward reward = economicPolicy.getReward(eventId);
-                if (reward != null) {
-                    if (ongoingEvent == null) {
-                        ongoingEvents.add(eventId, tag, new OngoingEvent(
-                                eventId, tag, startElapsed, reward));
-                    } else {
-                        ongoingEvent.refCount++;
-                    }
-                }
-                break;
-
-            default:
-                Slog.w(TAG, "Unsupported event type: " + eventType);
-        }
-
-        if (updateBalanceCheck) {
-            scheduleBalanceCheckLocked(userId, pkgName);
-        }
-    }
-
-    @GuardedBy("mLock")
-    void onDeviceStateChangedLocked() {
-        onPricingChangedLocked();
-    }
-
-    @GuardedBy("mLock")
-    void onPricingChangedLocked() {
-        onAnythingChangedLocked(true);
-    }
-
-    @GuardedBy("mLock")
-    void onAppStatesChangedLocked(final int userId, @NonNull ArraySet<String> pkgNames) {
-        final long now = getCurrentTimeMillis();
-        final long nowElapsed = SystemClock.elapsedRealtime();
-        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
-
-        for (int i = 0; i < pkgNames.size(); ++i) {
-            final String pkgName = pkgNames.valueAt(i);
-            final boolean isVip = mIrs.isVip(userId, pkgName, nowElapsed);
-            SparseArrayMap<String, OngoingEvent> ongoingEvents =
-                    mCurrentOngoingEvents.get(userId, pkgName);
-            if (ongoingEvents != null) {
-                mOngoingEventUpdater.reset(userId, pkgName, now, nowElapsed);
-                ongoingEvents.forEach(mOngoingEventUpdater);
-                final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes =
-                        mActionAffordabilityNotes.get(userId, pkgName);
-                if (actionAffordabilityNotes != null) {
-                    final int size = actionAffordabilityNotes.size();
-                    final long newBalance =
-                            mScribe.getLedgerLocked(userId, pkgName).getCurrentBalance();
-                    for (int n = 0; n < size; ++n) {
-                        final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n);
-                        note.recalculateCosts(economicPolicy, userId, pkgName);
-                        final boolean isAffordable = isVip
-                                || isAffordableLocked(newBalance,
-                                        note.getCachedModifiedPrice(),
-                                        note.getStockLimitHonoringCtp());
-                        if (note.isCurrentlyAffordable() != isAffordable) {
-                            note.setNewAffordability(isAffordable);
-                            mIrs.postAffordabilityChanged(userId, pkgName, note);
-                        }
-                    }
-                }
-                scheduleBalanceCheckLocked(userId, pkgName);
-            }
-        }
-    }
-
-    @GuardedBy("mLock")
-    void onVipStatusChangedLocked(final int userId, @NonNull String pkgName) {
-        final long now = getCurrentTimeMillis();
-        final long nowElapsed = SystemClock.elapsedRealtime();
-        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
-
-        final boolean isVip = mIrs.isVip(userId, pkgName, nowElapsed);
-        SparseArrayMap<String, OngoingEvent> ongoingEvents =
-                mCurrentOngoingEvents.get(userId, pkgName);
-        if (ongoingEvents != null) {
-            mOngoingEventUpdater.reset(userId, pkgName, now, nowElapsed);
-            ongoingEvents.forEach(mOngoingEventUpdater);
-        }
-        final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes =
-                mActionAffordabilityNotes.get(userId, pkgName);
-        if (actionAffordabilityNotes != null) {
-            final int size = actionAffordabilityNotes.size();
-            final long newBalance =
-                    mScribe.getLedgerLocked(userId, pkgName).getCurrentBalance();
-            for (int n = 0; n < size; ++n) {
-                final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n);
-                note.recalculateCosts(economicPolicy, userId, pkgName);
-                final boolean isAffordable = isVip
-                        || isAffordableLocked(newBalance,
-                        note.getCachedModifiedPrice(), note.getStockLimitHonoringCtp());
-                if (note.isCurrentlyAffordable() != isAffordable) {
-                    note.setNewAffordability(isAffordable);
-                    mIrs.postAffordabilityChanged(userId, pkgName, note);
-                }
-            }
-        }
-        scheduleBalanceCheckLocked(userId, pkgName);
-    }
-
-    @GuardedBy("mLock")
-    void onVipStatusChangedLocked(@NonNull SparseSetArray<String> pkgs) {
-        for (int u = pkgs.size() - 1; u >= 0; --u) {
-            final int userId = pkgs.keyAt(u);
-
-            for (int p = pkgs.sizeAt(u) - 1; p >= 0; --p) {
-                onVipStatusChangedLocked(userId, pkgs.valueAt(u, p));
-            }
-        }
-    }
-
-    @GuardedBy("mLock")
-    private void onAnythingChangedLocked(final boolean updateOngoingEvents) {
-        final long now = getCurrentTimeMillis();
-        final long nowElapsed = SystemClock.elapsedRealtime();
-        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
-
-        for (int uIdx = mCurrentOngoingEvents.numMaps() - 1; uIdx >= 0; --uIdx) {
-            final int userId = mCurrentOngoingEvents.keyAt(uIdx);
-
-            for (int pIdx = mCurrentOngoingEvents.numElementsForKey(userId) - 1; pIdx >= 0;
-                    --pIdx) {
-                final String pkgName = mCurrentOngoingEvents.keyAt(uIdx, pIdx);
-
-                SparseArrayMap<String, OngoingEvent> ongoingEvents =
-                        mCurrentOngoingEvents.valueAt(uIdx, pIdx);
-                if (ongoingEvents != null) {
-                    if (updateOngoingEvents) {
-                        mOngoingEventUpdater.reset(userId, pkgName, now, nowElapsed);
-                        ongoingEvents.forEach(mOngoingEventUpdater);
-                    }
-                    scheduleBalanceCheckLocked(userId, pkgName);
-                }
-            }
-        }
-        for (int uIdx = mActionAffordabilityNotes.numMaps() - 1; uIdx >= 0; --uIdx) {
-            final int userId = mActionAffordabilityNotes.keyAt(uIdx);
-
-            for (int pIdx = mActionAffordabilityNotes.numElementsForKey(userId) - 1; pIdx >= 0;
-                    --pIdx) {
-                final String pkgName = mActionAffordabilityNotes.keyAt(uIdx, pIdx);
-
-                final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes =
-                        mActionAffordabilityNotes.valueAt(uIdx, pIdx);
-
-                if (actionAffordabilityNotes != null) {
-                    final int size = actionAffordabilityNotes.size();
-                    final long newBalance = getBalanceLocked(userId, pkgName);
-                    final boolean isVip = mIrs.isVip(userId, pkgName, nowElapsed);
-                    for (int n = 0; n < size; ++n) {
-                        final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n);
-                        note.recalculateCosts(economicPolicy, userId, pkgName);
-                        final boolean isAffordable = isVip
-                                || isAffordableLocked(newBalance,
-                                        note.getCachedModifiedPrice(),
-                                        note.getStockLimitHonoringCtp());
-                        if (note.isCurrentlyAffordable() != isAffordable) {
-                            note.setNewAffordability(isAffordable);
-                            mIrs.postAffordabilityChanged(userId, pkgName, note);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    @GuardedBy("mLock")
-    void stopOngoingActionLocked(final int userId, @NonNull final String pkgName, final int eventId,
-            @Nullable String tag, final long nowElapsed, final long now) {
-        stopOngoingActionLocked(userId, pkgName, eventId, tag, nowElapsed, now, true, true);
-    }
-
-    /**
-     * @param updateBalanceCheck          Whether to reschedule the affordability/balance
-     *                                    check alarm.
-     * @param notifyOnAffordabilityChange Whether to evaluate the app's ability to afford
-     *                                    registered bills and notify listeners about any changes.
-     */
-    @GuardedBy("mLock")
-    private void stopOngoingActionLocked(final int userId, @NonNull final String pkgName,
-            final int eventId, @Nullable String tag, final long nowElapsed, final long now,
-            final boolean updateBalanceCheck, final boolean notifyOnAffordabilityChange) {
-        if (mIrs.isSystem(userId, pkgName)) {
-            // Events are free for the system. Don't bother recording them.
-            return;
-        }
-
-        final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);
-
-        SparseArrayMap<String, OngoingEvent> ongoingEvents =
-                mCurrentOngoingEvents.get(userId, pkgName);
-        if (ongoingEvents == null) {
-            // This may occur if TARE goes from disabled to enabled while an event is already
-            // occurring.
-            Slog.w(TAG, "No ongoing transactions for " + appToString(userId, pkgName));
-            return;
-        }
-        final OngoingEvent ongoingEvent = ongoingEvents.get(eventId, tag);
-        if (ongoingEvent == null) {
-            // This may occur if TARE goes from disabled to enabled while an event is already
-            // occurring.
-            Slog.w(TAG, "Nonexistent ongoing transaction "
-                    + eventToString(eventId) + (tag == null ? "" : ":" + tag)
-                    + " for " + appToString(userId, pkgName) + " ended");
-            return;
-        }
-        ongoingEvent.refCount--;
-        if (ongoingEvent.refCount <= 0) {
-            final long startElapsed = ongoingEvent.startTimeElapsed;
-            final long startTime = now - (nowElapsed - startElapsed);
-            final EconomicPolicy.Cost actualDelta =
-                    getActualDeltaLocked(ongoingEvent, ledger, nowElapsed, now);
-            recordTransactionLocked(userId, pkgName, ledger,
-                    new Ledger.Transaction(startTime, now, eventId, tag, actualDelta.price,
-                            actualDelta.costToProduce),
-                    notifyOnAffordabilityChange);
-
-            ongoingEvents.delete(eventId, tag);
-        }
-        if (updateBalanceCheck) {
-            scheduleBalanceCheckLocked(userId, pkgName);
-        }
-    }
-
-    @GuardedBy("mLock")
-    @NonNull
-    private EconomicPolicy.Cost getActualDeltaLocked(@NonNull OngoingEvent ongoingEvent,
-            @NonNull Ledger ledger, long nowElapsed, long now) {
-        final long startElapsed = ongoingEvent.startTimeElapsed;
-        final long durationSecs = (nowElapsed - startElapsed) / 1000;
-        final long computedDelta = durationSecs * ongoingEvent.getDeltaPerSec();
-        if (ongoingEvent.reward == null) {
-            return new EconomicPolicy.Cost(
-                    durationSecs * ongoingEvent.getCtpPerSec(), computedDelta);
-        }
-        final long rewardSum = ledger.get24HourSum(ongoingEvent.eventId, now);
-        return new EconomicPolicy.Cost(0,
-                Math.max(0,
-                        Math.min(ongoingEvent.reward.maxDailyReward - rewardSum, computedDelta)));
-    }
-
-    @VisibleForTesting
-    @GuardedBy("mLock")
-    void recordTransactionLocked(final int userId, @NonNull final String pkgName,
-            @NonNull Ledger ledger, @NonNull Ledger.Transaction transaction,
-            final boolean notifyOnAffordabilityChange) {
-        if (!DEBUG && transaction.delta == 0) {
-            // Skip recording transactions with a delta of 0 to save on space.
-            return;
-        }
-        if (mIrs.isSystem(userId, pkgName)) {
-            Slog.wtfStack(TAG,
-                    "Tried to adjust system balance for " + appToString(userId, pkgName));
-            return;
-        }
-        final boolean isVip = mIrs.isVip(userId, pkgName);
-        if (isVip) {
-            // This could happen if the app was made a VIP after it started performing actions.
-            // Continue recording the transaction for debugging purposes, but don't let it change
-            // any numbers.
-            transaction = new Ledger.Transaction(
-                    transaction.startTimeMs, transaction.endTimeMs,
-                    transaction.eventId, transaction.tag, 0 /* delta */, transaction.ctp);
-        }
-        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
-        final long originalBalance = ledger.getCurrentBalance();
-        final long maxBalance = economicPolicy.getMaxSatiatedBalance(userId, pkgName);
-        if (transaction.delta > 0
-                && originalBalance + transaction.delta > maxBalance) {
-            // Set lower bound at 0 so we don't accidentally take away credits when we were trying
-            // to _give_ the app credits.
-            final long newDelta = Math.max(0, maxBalance - originalBalance);
-            Slog.i(TAG, "Would result in becoming too rich. Decreasing transaction "
-                    + eventToString(transaction.eventId)
-                    + (transaction.tag == null ? "" : ":" + transaction.tag)
-                    + " for " + appToString(userId, pkgName)
-                    + " by " + cakeToString(transaction.delta - newDelta));
-            transaction = new Ledger.Transaction(
-                    transaction.startTimeMs, transaction.endTimeMs,
-                    transaction.eventId, transaction.tag, newDelta, transaction.ctp);
-        }
-        ledger.recordTransaction(transaction);
-        mScribe.adjustRemainingConsumableCakesLocked(-transaction.ctp);
-        mAnalyst.noteTransaction(transaction);
-        if (transaction.delta != 0 && notifyOnAffordabilityChange) {
-            final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes =
-                    mActionAffordabilityNotes.get(userId, pkgName);
-            if (actionAffordabilityNotes != null) {
-                final long newBalance = ledger.getCurrentBalance();
-                for (int i = 0; i < actionAffordabilityNotes.size(); ++i) {
-                    final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i);
-                    final boolean isAffordable = isVip
-                            || isAffordableLocked(newBalance,
-                                    note.getCachedModifiedPrice(), note.getStockLimitHonoringCtp());
-                    if (note.isCurrentlyAffordable() != isAffordable) {
-                        note.setNewAffordability(isAffordable);
-                        mIrs.postAffordabilityChanged(userId, pkgName, note);
-                    }
-                }
-            }
-        }
-        if (transaction.ctp != 0) {
-            mHandler.sendEmptyMessage(MSG_CHECK_ALL_AFFORDABILITY);
-            mIrs.maybePerformQuantitativeEasingLocked();
-        }
-    }
-
-    @GuardedBy("mLock")
-    void reclaimAllAssetsLocked(final int userId, @NonNull final String pkgName, int regulationId) {
-        final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);
-        final long curBalance = ledger.getCurrentBalance();
-        if (curBalance <= 0) {
-            return;
-        }
-        if (DEBUG) {
-            Slog.i(TAG, "Reclaiming " + cakeToString(curBalance)
-                    + " from " + appToString(userId, pkgName)
-                    + " because of " + eventToString(regulationId));
-        }
-
-        final long now = getCurrentTimeMillis();
-        recordTransactionLocked(userId, pkgName, ledger,
-                new Ledger.Transaction(now, now, regulationId, null, -curBalance, 0),
-                true);
-    }
-
-    /**
-     * Reclaim a percentage of unused ARCs from every app that hasn't been used recently. The
-     * reclamation will not reduce an app's balance below its minimum balance as dictated by
-     * {@code scaleMinBalance}.
-     *
-     * @param percentage      A value between 0 and 1 to indicate how much of the unused balance
-     *                        should be reclaimed.
-     * @param minUnusedTimeMs The minimum amount of time (in milliseconds) that must have
-     *                        transpired since the last user usage event before we will consider
-     *                        reclaiming ARCs from the app.
-     * @param scaleMinBalance Whether or not to use the scaled minimum app balance. If false,
-     *                        this will use the constant min balance floor given by
-     *                        {@link EconomicPolicy#getMinSatiatedBalance(int, String)}. If true,
-     *                        this will use the scaled balance given by
-     *                        {@link InternalResourceService#getMinBalanceLocked(int, String)}.
-     */
-    @GuardedBy("mLock")
-    void reclaimUnusedAssetsLocked(double percentage, long minUnusedTimeMs,
-            boolean scaleMinBalance) {
-        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
-        final SparseArrayMap<String, Ledger> ledgers = mScribe.getLedgersLocked();
-        final long now = getCurrentTimeMillis();
-        for (int u = 0; u < ledgers.numMaps(); ++u) {
-            final int userId = ledgers.keyAt(u);
-            for (int p = 0; p < ledgers.numElementsForKey(userId); ++p) {
-                final Ledger ledger = ledgers.valueAt(u, p);
-                final long curBalance = ledger.getCurrentBalance();
-                if (curBalance <= 0) {
-                    continue;
-                }
-                final String pkgName = ledgers.keyAt(u, p);
-                // AppStandby only counts elapsed time for things like this
-                // TODO: should we use clock time instead?
-                final long timeSinceLastUsedMs =
-                        mAppStandbyInternal.getTimeSinceLastUsedByUser(pkgName, userId);
-                if (timeSinceLastUsedMs >= minUnusedTimeMs) {
-                    final long minBalance;
-                    if (!scaleMinBalance) {
-                        // Use a constant floor instead of the scaled floor from the IRS.
-                        minBalance = economicPolicy.getMinSatiatedBalance(userId, pkgName);
-                    } else {
-                        minBalance = mIrs.getMinBalanceLocked(userId, pkgName);
-                    }
-                    long toReclaim = (long) (curBalance * percentage);
-                    if (curBalance - toReclaim < minBalance) {
-                        toReclaim = curBalance - minBalance;
-                    }
-                    if (toReclaim > 0) {
-                        if (DEBUG) {
-                            Slog.i(TAG, "Reclaiming unused wealth! Taking "
-                                    + cakeToString(toReclaim)
-                                    + " from " + appToString(userId, pkgName));
-                        }
-
-                        recordTransactionLocked(userId, pkgName, ledger,
-                                new Ledger.Transaction(now, now, REGULATION_WEALTH_RECLAMATION,
-                                        null, -toReclaim, 0),
-                                true);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Reclaim a percentage of unused ARCs from an app that was just removed from an exemption list.
-     * The amount reclaimed will depend on how recently the app was used. The reclamation will not
-     * reduce an app's balance below its current minimum balance.
-     */
-    @GuardedBy("mLock")
-    void onAppUnexemptedLocked(final int userId, @NonNull final String pkgName) {
-        final long curBalance = getBalanceLocked(userId, pkgName);
-        final long minBalance = mIrs.getMinBalanceLocked(userId, pkgName);
-        if (curBalance <= minBalance) {
-            return;
-        }
-        // AppStandby only counts elapsed time for things like this
-        // TODO: should we use clock time instead?
-        final long timeSinceLastUsedMs =
-                mAppStandbyInternal.getTimeSinceLastUsedByUser(pkgName, userId);
-        // The app is no longer exempted. We should take away some of credits so it's more in line
-        // with other non-exempt apps. However, don't take away as many credits if the app was used
-        // recently.
-        final double percentageToReclaim;
-        if (timeSinceLastUsedMs < DAY_IN_MILLIS) {
-            percentageToReclaim = .25;
-        } else if (timeSinceLastUsedMs < 2 * DAY_IN_MILLIS) {
-            percentageToReclaim = .5;
-        } else if (timeSinceLastUsedMs < 3 * DAY_IN_MILLIS) {
-            percentageToReclaim = .75;
-        } else {
-            percentageToReclaim = 1;
-        }
-        final long overage = curBalance - minBalance;
-        final long toReclaim = (long) (overage * percentageToReclaim);
-        if (toReclaim > 0) {
-            if (DEBUG) {
-                Slog.i(TAG, "Reclaiming bonus wealth! Taking " + toReclaim
-                        + " from " + appToString(userId, pkgName));
-            }
-
-            final long now = getCurrentTimeMillis();
-            final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);
-            recordTransactionLocked(userId, pkgName, ledger,
-                    new Ledger.Transaction(now, now, REGULATION_DEMOTION, null, -toReclaim, 0),
-                    true);
-        }
-    }
-
-    /**
-     * Reclaim all ARCs from an app that was just restricted.
-     */
-    @GuardedBy("mLock")
-    void onAppRestrictedLocked(final int userId, @NonNull final String pkgName) {
-        reclaimAllAssetsLocked(userId, pkgName, REGULATION_BG_RESTRICTED);
-    }
-
-    /**
-     * Give an app that was just unrestricted some ARCs.
-     */
-    @GuardedBy("mLock")
-    void onAppUnrestrictedLocked(final int userId, @NonNull final String pkgName) {
-        final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);
-        if (ledger.getCurrentBalance() > 0) {
-            Slog.wtf(TAG, "App " + pkgName + " had credits while it was restricted");
-            // App already got credits somehow. Move along.
-            return;
-        }
-
-        final long now = getCurrentTimeMillis();
-
-        recordTransactionLocked(userId, pkgName, ledger,
-                new Ledger.Transaction(now, now, REGULATION_BG_UNRESTRICTED, null,
-                        mIrs.getMinBalanceLocked(userId, pkgName), 0), true);
-    }
-
-    /** Returns true if an app should be given credits in the general distributions. */
-    private boolean shouldGiveCredits(@NonNull InstalledPackageInfo packageInfo) {
-        // Skip apps that wouldn't be doing any work. Giving them ARCs would be wasteful.
-        if (!packageInfo.hasCode) {
-            return false;
-        }
-        final int userId = UserHandle.getUserId(packageInfo.uid);
-        // No point allocating ARCs to the system. It can do whatever it wants.
-        return !mIrs.isSystem(userId, packageInfo.packageName)
-                && !mIrs.isPackageRestricted(userId, packageInfo.packageName);
-    }
-
-    void onCreditSupplyChanged() {
-        mHandler.sendEmptyMessage(MSG_CHECK_ALL_AFFORDABILITY);
-    }
-
-    @GuardedBy("mLock")
-    void distributeBasicIncomeLocked(int batteryLevel) {
-        final SparseArrayMap<String, InstalledPackageInfo> pkgs = mIrs.getInstalledPackages();
-
-        final long now = getCurrentTimeMillis();
-        for (int uIdx = pkgs.numMaps() - 1; uIdx >= 0; --uIdx) {
-            final int userId = pkgs.keyAt(uIdx);
-
-            for (int pIdx = pkgs.numElementsForKeyAt(uIdx) - 1; pIdx >= 0; --pIdx) {
-                final InstalledPackageInfo pkgInfo = pkgs.valueAt(uIdx, pIdx);
-                if (!shouldGiveCredits(pkgInfo)) {
-                    continue;
-                }
-                final String pkgName = pkgInfo.packageName;
-                final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);
-                final long minBalance = mIrs.getMinBalanceLocked(userId, pkgName);
-                final double perc = batteryLevel / 100d;
-                // TODO: maybe don't give credits to bankrupt apps until battery level >= 50%
-                final long shortfall = minBalance - ledger.getCurrentBalance();
-                if (shortfall > 0) {
-                    recordTransactionLocked(userId, pkgName, ledger,
-                            new Ledger.Transaction(now, now, REGULATION_BASIC_INCOME,
-                                    null, (long) (perc * shortfall), 0), true);
-                }
-            }
-        }
-    }
-
-    /** Give each app an initial balance. */
-    @GuardedBy("mLock")
-    void grantBirthrightsLocked() {
-        UserManagerInternal userManagerInternal =
-                LocalServices.getService(UserManagerInternal.class);
-        final int[] userIds = userManagerInternal.getUserIds();
-        for (int userId : userIds) {
-            grantBirthrightsLocked(userId);
-        }
-    }
-
-    @GuardedBy("mLock")
-    void grantBirthrightsLocked(final int userId) {
-        final List<InstalledPackageInfo> pkgs = mIrs.getInstalledPackages(userId);
-        final long now = getCurrentTimeMillis();
-
-        for (int i = 0; i < pkgs.size(); ++i) {
-            final InstalledPackageInfo packageInfo = pkgs.get(i);
-            if (!shouldGiveCredits(packageInfo)) {
-                continue;
-            }
-            final String pkgName = packageInfo.packageName;
-            final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);
-            if (ledger.getCurrentBalance() > 0) {
-                // App already got credits somehow. Move along.
-                Slog.wtf(TAG, "App " + pkgName + " had credits before economy was set up");
-                continue;
-            }
-
-            recordTransactionLocked(userId, pkgName, ledger,
-                    new Ledger.Transaction(now, now, REGULATION_BIRTHRIGHT, null,
-                            mIrs.getMinBalanceLocked(userId, pkgName), 0),
-                    true);
-        }
-    }
-
-    @GuardedBy("mLock")
-    void grantBirthrightLocked(final int userId, @NonNull final String pkgName) {
-        final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);
-        if (ledger.getCurrentBalance() > 0) {
-            Slog.wtf(TAG, "App " + pkgName + " had credits as soon as it was installed");
-            // App already got credits somehow. Move along.
-            return;
-        }
-
-        final long now = getCurrentTimeMillis();
-
-        recordTransactionLocked(userId, pkgName, ledger,
-                new Ledger.Transaction(now, now, REGULATION_BIRTHRIGHT, null,
-                        mIrs.getMinBalanceLocked(userId, pkgName), 0), true);
-    }
-
-    @GuardedBy("mLock")
-    void onAppExemptedLocked(final int userId, @NonNull final String pkgName) {
-        final long minBalance = mIrs.getMinBalanceLocked(userId, pkgName);
-        final long missing = minBalance - getBalanceLocked(userId, pkgName);
-        if (missing <= 0) {
-            return;
-        }
-
-        final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);
-        final long now = getCurrentTimeMillis();
-
-        recordTransactionLocked(userId, pkgName, ledger,
-                new Ledger.Transaction(now, now, REGULATION_PROMOTION, null, missing, 0), true);
-    }
-
-    @GuardedBy("mLock")
-    void onPackageRemovedLocked(final int userId, @NonNull final String pkgName) {
-        mScribe.discardLedgerLocked(userId, pkgName);
-        mCurrentOngoingEvents.delete(userId, pkgName);
-        mBalanceThresholdAlarmQueue.removeAlarmForKey(UserPackage.of(userId, pkgName));
-    }
-
-    @GuardedBy("mLock")
-    void onUserRemovedLocked(final int userId) {
-        mCurrentOngoingEvents.delete(userId);
-        mBalanceThresholdAlarmQueue.removeAlarmsForUserId(userId);
-    }
-
-    @VisibleForTesting
-    static class TrendCalculator implements Consumer<OngoingEvent> {
-        static final long WILL_NOT_CROSS_THRESHOLD = -1;
-
-        private long mCurBalance;
-        private long mRemainingConsumableCredits;
-        /**
-         * The maximum change in credits per second towards the upper threshold
-         * {@link #mUpperThreshold}. A value of 0 means the current ongoing events will never
-         * result in the app crossing the upper threshold.
-         */
-        private long mMaxDeltaPerSecToUpperThreshold;
-        /**
-         * The maximum change in credits per second towards the lower threshold
-         * {@link #mLowerThreshold}. A value of 0 means the current ongoing events will never
-         * result in the app crossing the lower threshold.
-         */
-        private long mMaxDeltaPerSecToLowerThreshold;
-        /**
-         * The maximum change in credits per second towards the highest CTP threshold below the
-         * remaining consumable credits (cached in {@link #mCtpThreshold}). A value of 0 means
-         * the current ongoing events will never result in the app crossing the lower threshold.
-         */
-        private long mMaxDeltaPerSecToCtpThreshold;
-        private long mUpperThreshold;
-        private long mLowerThreshold;
-        private long mCtpThreshold;
-
-        void reset(long curBalance, long remainingConsumableCredits,
-                @Nullable ArraySet<ActionAffordabilityNote> actionAffordabilityNotes) {
-            mCurBalance = curBalance;
-            mRemainingConsumableCredits = remainingConsumableCredits;
-            mMaxDeltaPerSecToUpperThreshold = mMaxDeltaPerSecToLowerThreshold = 0;
-            mMaxDeltaPerSecToCtpThreshold = 0;
-            mUpperThreshold = Long.MIN_VALUE;
-            mLowerThreshold = Long.MAX_VALUE;
-            mCtpThreshold = 0;
-            if (actionAffordabilityNotes != null) {
-                for (int i = 0; i < actionAffordabilityNotes.size(); ++i) {
-                    final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i);
-                    final long price = note.getCachedModifiedPrice();
-                    if (price <= mCurBalance) {
-                        mLowerThreshold = (mLowerThreshold == Long.MAX_VALUE)
-                                ? price : Math.max(mLowerThreshold, price);
-                    } else {
-                        mUpperThreshold = (mUpperThreshold == Long.MIN_VALUE)
-                                ? price : Math.min(mUpperThreshold, price);
-                    }
-                    final long ctp = note.getStockLimitHonoringCtp();
-                    if (ctp <= mRemainingConsumableCredits) {
-                        mCtpThreshold = Math.max(mCtpThreshold, ctp);
-                    }
-                }
-            }
-        }
-
-        /**
-         * Returns the amount of time (in millisecond) it will take for the app to cross the next
-         * lowest action affordability note (compared to its current balance) based on current
-         * ongoing events.
-         * Returns {@link #WILL_NOT_CROSS_THRESHOLD} if the app will never cross the lowest
-         * threshold.
-         */
-        long getTimeToCrossLowerThresholdMs() {
-            if (mMaxDeltaPerSecToLowerThreshold == 0 && mMaxDeltaPerSecToCtpThreshold == 0) {
-                // Will never cross lower threshold based on current events.
-                return WILL_NOT_CROSS_THRESHOLD;
-            }
-            long minSeconds = Long.MAX_VALUE;
-            if (mMaxDeltaPerSecToLowerThreshold != 0) {
-                // deltaPerSec is a negative value, so do threshold-balance to cancel out the
-                // negative.
-                minSeconds = (mLowerThreshold - mCurBalance) / mMaxDeltaPerSecToLowerThreshold;
-            }
-            if (mMaxDeltaPerSecToCtpThreshold != 0) {
-                minSeconds = Math.min(minSeconds,
-                        // deltaPerSec is a negative value, so do threshold-balance to cancel
-                        // out the negative.
-                        (mCtpThreshold - mRemainingConsumableCredits)
-                                / mMaxDeltaPerSecToCtpThreshold);
-            }
-            return minSeconds * 1000;
-        }
-
-        /**
-         * Returns the amount of time (in millisecond) it will take for the app to cross the next
-         * highest action affordability note (compared to its current balance) based on current
-         * ongoing events.
-         * Returns {@link #WILL_NOT_CROSS_THRESHOLD} if the app will never cross the upper
-         * threshold.
-         */
-        long getTimeToCrossUpperThresholdMs() {
-            if (mMaxDeltaPerSecToUpperThreshold == 0) {
-                // Will never cross upper threshold based on current events.
-                return WILL_NOT_CROSS_THRESHOLD;
-            }
-            final long minSeconds =
-                    (mUpperThreshold - mCurBalance) / mMaxDeltaPerSecToUpperThreshold;
-            return minSeconds * 1000;
-        }
-
-        @Override
-        public void accept(OngoingEvent ongoingEvent) {
-            final long deltaPerSec = ongoingEvent.getDeltaPerSec();
-            if (mCurBalance >= mLowerThreshold && deltaPerSec < 0) {
-                mMaxDeltaPerSecToLowerThreshold += deltaPerSec;
-            } else if (mCurBalance < mUpperThreshold && deltaPerSec > 0) {
-                mMaxDeltaPerSecToUpperThreshold += deltaPerSec;
-            }
-            final long ctpPerSec = ongoingEvent.getCtpPerSec();
-            if (mRemainingConsumableCredits >= mCtpThreshold && deltaPerSec < 0) {
-                mMaxDeltaPerSecToCtpThreshold -= ctpPerSec;
-            }
-        }
-    }
-
-    @GuardedBy("mLock")
-    private final TrendCalculator mTrendCalculator = new TrendCalculator();
-
-    @GuardedBy("mLock")
-    private void scheduleBalanceCheckLocked(final int userId, @NonNull final String pkgName) {
-        SparseArrayMap<String, OngoingEvent> ongoingEvents =
-                mCurrentOngoingEvents.get(userId, pkgName);
-        if (ongoingEvents == null || mIrs.isVip(userId, pkgName)) {
-            // No ongoing transactions. No reason to schedule
-            mBalanceThresholdAlarmQueue.removeAlarmForKey(UserPackage.of(userId, pkgName));
-            return;
-        }
-        mTrendCalculator.reset(getBalanceLocked(userId, pkgName),
-                mScribe.getRemainingConsumableCakesLocked(),
-                mActionAffordabilityNotes.get(userId, pkgName));
-        ongoingEvents.forEach(mTrendCalculator);
-        final long lowerTimeMs = mTrendCalculator.getTimeToCrossLowerThresholdMs();
-        final long upperTimeMs = mTrendCalculator.getTimeToCrossUpperThresholdMs();
-        final long timeToThresholdMs;
-        if (lowerTimeMs == TrendCalculator.WILL_NOT_CROSS_THRESHOLD) {
-            if (upperTimeMs == TrendCalculator.WILL_NOT_CROSS_THRESHOLD) {
-                // Will never cross a threshold based on current events.
-                mBalanceThresholdAlarmQueue.removeAlarmForKey(UserPackage.of(userId, pkgName));
-                return;
-            }
-            timeToThresholdMs = upperTimeMs;
-        } else {
-            timeToThresholdMs = (upperTimeMs == TrendCalculator.WILL_NOT_CROSS_THRESHOLD)
-                    ? lowerTimeMs : Math.min(lowerTimeMs, upperTimeMs);
-        }
-        mBalanceThresholdAlarmQueue.addAlarm(UserPackage.of(userId, pkgName),
-                SystemClock.elapsedRealtime() + timeToThresholdMs);
-    }
-
-    @GuardedBy("mLock")
-    void tearDownLocked() {
-        mCurrentOngoingEvents.clear();
-        mBalanceThresholdAlarmQueue.removeAllAlarms();
-        mHandler.removeAllMessages();
-    }
-
-    @VisibleForTesting
-    static class OngoingEvent {
-        public final long startTimeElapsed;
-        public final int eventId;
-        @Nullable
-        public final String tag;
-        @Nullable
-        public final EconomicPolicy.Reward reward;
-        @Nullable
-        public final EconomicPolicy.Cost actionCost;
-        public int refCount;
-
-        OngoingEvent(int eventId, @Nullable String tag, long startTimeElapsed,
-                @NonNull EconomicPolicy.Reward reward) {
-            this.startTimeElapsed = startTimeElapsed;
-            this.eventId = eventId;
-            this.tag = tag;
-            this.reward = reward;
-            this.actionCost = null;
-            refCount = 1;
-        }
-
-        OngoingEvent(int eventId, @Nullable String tag, long startTimeElapsed,
-                @NonNull EconomicPolicy.Cost actionCost) {
-            this.startTimeElapsed = startTimeElapsed;
-            this.eventId = eventId;
-            this.tag = tag;
-            this.reward = null;
-            this.actionCost = actionCost;
-            refCount = 1;
-        }
-
-        long getDeltaPerSec() {
-            if (actionCost != null) {
-                return -actionCost.price;
-            }
-            if (reward != null) {
-                return reward.ongoingRewardPerSecond;
-            }
-            Slog.wtfStack(TAG, "No action or reward in ongoing event?!??!");
-            return 0;
-        }
-
-        long getCtpPerSec() {
-            if (actionCost != null) {
-                return actionCost.costToProduce;
-            }
-            return 0;
-        }
-    }
-
-    private class OngoingEventUpdater implements Consumer<OngoingEvent> {
-        private int mUserId;
-        private String mPkgName;
-        private long mNow;
-        private long mNowElapsed;
-
-        private void reset(int userId, String pkgName, long now, long nowElapsed) {
-            mUserId = userId;
-            mPkgName = pkgName;
-            mNow = now;
-            mNowElapsed = nowElapsed;
-        }
-
-        @Override
-        public void accept(OngoingEvent ongoingEvent) {
-            // Disable balance check & affordability notifications here because
-            // we're in the middle of updating ongoing action costs/prices and
-            // sending out notifications or rescheduling the balance check alarm
-            // would be a waste since we'll have to redo them again after all of
-            // our internal state is updated.
-            final boolean updateBalanceCheck = false;
-            stopOngoingActionLocked(mUserId, mPkgName, ongoingEvent.eventId, ongoingEvent.tag,
-                    mNowElapsed, mNow, updateBalanceCheck, /* notifyOnAffordabilityChange */ false);
-            noteOngoingEventLocked(mUserId, mPkgName, ongoingEvent.eventId, ongoingEvent.tag,
-                    mNowElapsed, updateBalanceCheck);
-        }
-    }
-
-    private final OngoingEventUpdater mOngoingEventUpdater = new OngoingEventUpdater();
-
-    /** Track when apps will cross the closest affordability threshold (in both directions). */
-    private class BalanceThresholdAlarmQueue extends AlarmQueue<UserPackage> {
-        private BalanceThresholdAlarmQueue(Context context, Looper looper) {
-            super(context, looper, ALARM_TAG_AFFORDABILITY_CHECK, "Affordability check", true,
-                    15_000L);
-        }
-
-        @Override
-        protected boolean isForUser(@NonNull UserPackage key, int userId) {
-            return key.userId == userId;
-        }
-
-        @Override
-        protected void processExpiredAlarms(@NonNull ArraySet<UserPackage> expired) {
-            for (int i = 0; i < expired.size(); ++i) {
-                UserPackage p = expired.valueAt(i);
-                mHandler.obtainMessage(
-                        MSG_CHECK_INDIVIDUAL_AFFORDABILITY, p.userId, 0, p.packageName)
-                        .sendToTarget();
-            }
-        }
-    }
-
-    @GuardedBy("mLock")
-    public void registerAffordabilityChangeListenerLocked(int userId, @NonNull String pkgName,
-            @NonNull EconomyManagerInternal.AffordabilityChangeListener listener,
-            @NonNull EconomyManagerInternal.ActionBill bill) {
-        ArraySet<ActionAffordabilityNote> actionAffordabilityNotes =
-                mActionAffordabilityNotes.get(userId, pkgName);
-        if (actionAffordabilityNotes == null) {
-            actionAffordabilityNotes = new ArraySet<>();
-            mActionAffordabilityNotes.add(userId, pkgName, actionAffordabilityNotes);
-        }
-        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
-        final ActionAffordabilityNote note =
-                new ActionAffordabilityNote(bill, listener, economicPolicy);
-        if (actionAffordabilityNotes.add(note)) {
-            if (mIrs.getEnabledMode() == ENABLED_MODE_OFF) {
-                // When TARE isn't enabled, we always say something is affordable. We also don't
-                // want to silently drop affordability change listeners in case TARE becomes enabled
-                // because then clients will be in an ambiguous state.
-                note.setNewAffordability(true);
-                return;
-            }
-            final boolean isVip = mIrs.isVip(userId, pkgName);
-            note.recalculateCosts(economicPolicy, userId, pkgName);
-            note.setNewAffordability(isVip
-                    || isAffordableLocked(getBalanceLocked(userId, pkgName),
-                            note.getCachedModifiedPrice(), note.getStockLimitHonoringCtp()));
-            mIrs.postAffordabilityChanged(userId, pkgName, note);
-            // Update ongoing alarm
-            scheduleBalanceCheckLocked(userId, pkgName);
-        }
-    }
-
-    @GuardedBy("mLock")
-    public void unregisterAffordabilityChangeListenerLocked(int userId, @NonNull String pkgName,
-            @NonNull EconomyManagerInternal.AffordabilityChangeListener listener,
-            @NonNull EconomyManagerInternal.ActionBill bill) {
-        final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes =
-                mActionAffordabilityNotes.get(userId, pkgName);
-        if (actionAffordabilityNotes != null) {
-            final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
-            final ActionAffordabilityNote note =
-                    new ActionAffordabilityNote(bill, listener, economicPolicy);
-            if (actionAffordabilityNotes.remove(note)) {
-                // Update ongoing alarm
-                scheduleBalanceCheckLocked(userId, pkgName);
-            }
-        }
-    }
-
-    static final class ActionAffordabilityNote {
-        private final EconomyManagerInternal.ActionBill mActionBill;
-        private final EconomyManagerInternal.AffordabilityChangeListener mListener;
-        private long mStockLimitHonoringCtp;
-        private long mModifiedPrice;
-        private boolean mIsAffordable;
-
-        @VisibleForTesting
-        ActionAffordabilityNote(@NonNull EconomyManagerInternal.ActionBill bill,
-                @NonNull EconomyManagerInternal.AffordabilityChangeListener listener,
-                @NonNull EconomicPolicy economicPolicy) {
-            mActionBill = bill;
-            final List<EconomyManagerInternal.AnticipatedAction> anticipatedActions =
-                    bill.getAnticipatedActions();
-            for (int i = 0; i < anticipatedActions.size(); ++i) {
-                final EconomyManagerInternal.AnticipatedAction aa = anticipatedActions.get(i);
-                final EconomicPolicy.Action action = economicPolicy.getAction(aa.actionId);
-                if (action == null) {
-                    if ((aa.actionId & EconomicPolicy.ALL_POLICIES) == 0) {
-                        throw new IllegalArgumentException("Invalid action id: " + aa.actionId);
-                    } else {
-                        Slog.w(TAG, "Tracking disabled policy's action? " + aa.actionId);
-                    }
-                }
-            }
-            mListener = listener;
-        }
-
-        @NonNull
-        EconomyManagerInternal.ActionBill getActionBill() {
-            return mActionBill;
-        }
-
-        @NonNull
-        EconomyManagerInternal.AffordabilityChangeListener getListener() {
-            return mListener;
-        }
-
-        private long getCachedModifiedPrice() {
-            return mModifiedPrice;
-        }
-
-        /** Returns the cumulative CTP of actions in this note that respect the stock limit. */
-        private long getStockLimitHonoringCtp() {
-            return mStockLimitHonoringCtp;
-        }
-
-        @VisibleForTesting
-        void recalculateCosts(@NonNull EconomicPolicy economicPolicy,
-                int userId, @NonNull String pkgName) {
-            long modifiedPrice = 0;
-            long stockLimitHonoringCtp = 0;
-            final List<EconomyManagerInternal.AnticipatedAction> anticipatedActions =
-                    mActionBill.getAnticipatedActions();
-            for (int i = 0; i < anticipatedActions.size(); ++i) {
-                final EconomyManagerInternal.AnticipatedAction aa = anticipatedActions.get(i);
-                final EconomicPolicy.Action action = economicPolicy.getAction(aa.actionId);
-
-                final EconomicPolicy.Cost actionCost =
-                        economicPolicy.getCostOfAction(aa.actionId, userId, pkgName);
-                modifiedPrice += actionCost.price * aa.numInstantaneousCalls
-                        + actionCost.price * (aa.ongoingDurationMs / 1000);
-                if (action.respectsStockLimit) {
-                    stockLimitHonoringCtp +=
-                            actionCost.costToProduce * aa.numInstantaneousCalls
-                                    + actionCost.costToProduce * (aa.ongoingDurationMs / 1000);
-                }
-            }
-            mModifiedPrice = modifiedPrice;
-            mStockLimitHonoringCtp = stockLimitHonoringCtp;
-        }
-
-        boolean isCurrentlyAffordable() {
-            return mIsAffordable;
-        }
-
-        private void setNewAffordability(boolean isAffordable) {
-            mIsAffordable = isAffordable;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (!(o instanceof ActionAffordabilityNote)) return false;
-            ActionAffordabilityNote other = (ActionAffordabilityNote) o;
-            return mActionBill.equals(other.mActionBill)
-                    && mListener.equals(other.mListener);
-        }
-
-        @Override
-        public int hashCode() {
-            int hash = 0;
-            hash = 31 * hash + Objects.hash(mListener);
-            hash = 31 * hash + mActionBill.hashCode();
-            return hash;
-        }
-    }
-
-    private final class AgentHandler extends Handler {
-        AgentHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_CHECK_ALL_AFFORDABILITY: {
-                    synchronized (mLock) {
-                        removeMessages(MSG_CHECK_ALL_AFFORDABILITY);
-                        onAnythingChangedLocked(false);
-                    }
-                }
-                break;
-
-                case MSG_CHECK_INDIVIDUAL_AFFORDABILITY: {
-                    final int userId = msg.arg1;
-                    final String pkgName = (String) msg.obj;
-                    synchronized (mLock) {
-                        final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes =
-                                mActionAffordabilityNotes.get(userId, pkgName);
-                        if (actionAffordabilityNotes != null
-                                && actionAffordabilityNotes.size() > 0) {
-                            final long newBalance = getBalanceLocked(userId, pkgName);
-                            final boolean isVip = mIrs.isVip(userId, pkgName);
-
-                            for (int i = 0; i < actionAffordabilityNotes.size(); ++i) {
-                                final ActionAffordabilityNote note =
-                                        actionAffordabilityNotes.valueAt(i);
-                                final boolean isAffordable = isVip || isAffordableLocked(
-                                        newBalance, note.getCachedModifiedPrice(),
-                                        note.getStockLimitHonoringCtp());
-                                if (note.isCurrentlyAffordable() != isAffordable) {
-                                    note.setNewAffordability(isAffordable);
-                                    mIrs.postAffordabilityChanged(userId, pkgName, note);
-                                }
-                            }
-                        }
-                        scheduleBalanceCheckLocked(userId, pkgName);
-                    }
-                }
-                break;
-            }
-        }
-
-        void removeAllMessages() {
-            removeMessages(MSG_CHECK_ALL_AFFORDABILITY);
-            removeMessages(MSG_CHECK_INDIVIDUAL_AFFORDABILITY);
-        }
-    }
-
-    @GuardedBy("mLock")
-    void dumpLocked(IndentingPrintWriter pw) {
-        mBalanceThresholdAlarmQueue.dump(pw);
-
-        pw.println();
-        pw.println("Ongoing events:");
-        pw.increaseIndent();
-        boolean printedEvents = false;
-        final long nowElapsed = SystemClock.elapsedRealtime();
-        for (int u = mCurrentOngoingEvents.numMaps() - 1; u >= 0; --u) {
-            final int userId = mCurrentOngoingEvents.keyAt(u);
-            for (int p = mCurrentOngoingEvents.numElementsForKey(userId) - 1; p >= 0; --p) {
-                final String pkgName = mCurrentOngoingEvents.keyAt(u, p);
-                final SparseArrayMap<String, OngoingEvent> ongoingEvents =
-                        mCurrentOngoingEvents.get(userId, pkgName);
-
-                boolean printedApp = false;
-
-                for (int e = ongoingEvents.numMaps() - 1; e >= 0; --e) {
-                    final int eventId = ongoingEvents.keyAt(e);
-                    for (int t = ongoingEvents.numElementsForKey(eventId) - 1; t >= 0; --t) {
-                        if (!printedApp) {
-                            printedApp = true;
-                            pw.println(appToString(userId, pkgName));
-                            pw.increaseIndent();
-                        }
-                        printedEvents = true;
-
-                        OngoingEvent ongoingEvent = ongoingEvents.valueAt(e, t);
-
-                        pw.print(EconomicPolicy.eventToString(ongoingEvent.eventId));
-                        if (ongoingEvent.tag != null) {
-                            pw.print("(");
-                            pw.print(ongoingEvent.tag);
-                            pw.print(")");
-                        }
-                        pw.print(" runtime=");
-                        TimeUtils.formatDuration(nowElapsed - ongoingEvent.startTimeElapsed, pw);
-                        pw.print(" delta/sec=");
-                        pw.print(cakeToString(ongoingEvent.getDeltaPerSec()));
-                        final long ctp = ongoingEvent.getCtpPerSec();
-                        if (ctp != 0) {
-                            pw.print(" ctp/sec=");
-                            pw.print(cakeToString(ongoingEvent.getCtpPerSec()));
-                        }
-                        pw.print(" refCount=");
-                        pw.print(ongoingEvent.refCount);
-                        pw.println();
-                    }
-                }
-
-                if (printedApp) {
-                    pw.decreaseIndent();
-                }
-            }
-        }
-        if (!printedEvents) {
-            pw.print("N/A");
-        }
-        pw.decreaseIndent();
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
deleted file mode 100644
index 8381d1a..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_MAX_CONSUMPTION_LIMIT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_CONSUMPTION_LIMIT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP;
-import static android.app.tare.EconomyManager.KEY_AM_INITIAL_CONSUMPTION_LIMIT;
-import static android.app.tare.EconomyManager.KEY_AM_MAX_CONSUMPTION_LIMIT;
-import static android.app.tare.EconomyManager.KEY_AM_MAX_SATIATED_BALANCE;
-import static android.app.tare.EconomyManager.KEY_AM_MIN_CONSUMPTION_LIMIT;
-import static android.app.tare.EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED;
-import static android.app.tare.EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP;
-import static android.app.tare.EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_MAX;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_MAX;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_OTHER_USER_INTERACTION_MAX;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_OTHER_USER_INTERACTION_ONGOING;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_INSTANT;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_MAX;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_TOP_ACTIVITY_ONGOING;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_WIDGET_INTERACTION_MAX;
-import static android.app.tare.EconomyManager.KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING;
-import static android.app.tare.EconomyManager.arcToCake;
-import static android.provider.Settings.Global.TARE_ALARM_MANAGER_CONSTANTS;
-
-import static com.android.server.tare.Modifier.COST_MODIFIER_CHARGING;
-import static com.android.server.tare.Modifier.COST_MODIFIER_DEVICE_IDLE;
-import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE;
-import static com.android.server.tare.Modifier.COST_MODIFIER_PROCESS_STATE;
-import static com.android.server.tare.TareUtils.cakeToString;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.provider.DeviceConfig;
-import android.util.IndentingPrintWriter;
-import android.util.Slog;
-import android.util.SparseArray;
-
-/**
- * Policy defining pricing information and daily ARC requirements and suggestions for
- * AlarmManager.
- */
-public class AlarmManagerEconomicPolicy extends EconomicPolicy {
-    private static final String TAG = "TARE- " + AlarmManagerEconomicPolicy.class.getSimpleName();
-
-    public static final int ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE =
-            TYPE_ACTION | POLICY_ALARM | 0;
-    public static final int ACTION_ALARM_WAKEUP_EXACT =
-            TYPE_ACTION | POLICY_ALARM | 1;
-    public static final int ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE =
-            TYPE_ACTION | POLICY_ALARM | 2;
-    public static final int ACTION_ALARM_WAKEUP_INEXACT =
-            TYPE_ACTION | POLICY_ALARM | 3;
-    public static final int ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE =
-            TYPE_ACTION | POLICY_ALARM | 4;
-    public static final int ACTION_ALARM_NONWAKEUP_EXACT =
-            TYPE_ACTION | POLICY_ALARM | 5;
-    public static final int ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE =
-            TYPE_ACTION | POLICY_ALARM | 6;
-    public static final int ACTION_ALARM_NONWAKEUP_INEXACT =
-            TYPE_ACTION | POLICY_ALARM | 7;
-    public static final int ACTION_ALARM_CLOCK =
-            TYPE_ACTION | POLICY_ALARM | 8;
-
-    private static final int[] COST_MODIFIERS = new int[]{
-            COST_MODIFIER_CHARGING,
-            COST_MODIFIER_DEVICE_IDLE,
-            COST_MODIFIER_POWER_SAVE_MODE,
-            COST_MODIFIER_PROCESS_STATE
-    };
-
-    private long mMinSatiatedBalanceExempted;
-    private long mMinSatiatedBalanceHeadlessSystemApp;
-    private long mMinSatiatedBalanceOther;
-    private long mMaxSatiatedBalance;
-    private long mInitialSatiatedConsumptionLimit;
-    private long mMinSatiatedConsumptionLimit;
-    private long mMaxSatiatedConsumptionLimit;
-
-    private final Injector mInjector;
-
-    private final SparseArray<Action> mActions = new SparseArray<>();
-    private final SparseArray<Reward> mRewards = new SparseArray<>();
-
-    AlarmManagerEconomicPolicy(InternalResourceService irs, Injector injector) {
-        super(irs);
-        mInjector = injector;
-        loadConstants("", null);
-    }
-
-    @Override
-    void setup(@NonNull DeviceConfig.Properties properties) {
-        super.setup(properties);
-        ContentResolver resolver = mIrs.getContext().getContentResolver();
-        loadConstants(mInjector.getSettingsGlobalString(resolver, TARE_ALARM_MANAGER_CONSTANTS),
-                properties);
-    }
-
-    @Override
-    long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) {
-        if (mIrs.isPackageRestricted(userId, pkgName)) {
-            return 0;
-        }
-        if (mIrs.isPackageExempted(userId, pkgName)) {
-            return mMinSatiatedBalanceExempted;
-        }
-        if (mIrs.isHeadlessSystemApp(userId, pkgName)) {
-            return mMinSatiatedBalanceHeadlessSystemApp;
-        }
-        // TODO: take other exemptions into account
-        return mMinSatiatedBalanceOther;
-    }
-
-    @Override
-    long getMaxSatiatedBalance(int userId, @NonNull String pkgName) {
-        if (mIrs.isPackageRestricted(userId, pkgName)) {
-            return 0;
-        }
-        // TODO(230501287): adjust balance based on whether the app has the SCHEDULE_EXACT_ALARM
-        // permission granted. Apps without the permission granted shouldn't need a high balance
-        // since they won't be able to use exact alarms. Apps with the permission granted could
-        // have a higher balance, or perhaps just those with the USE_EXACT_ALARM permission since
-        // that is limited to specific use cases.
-        return mMaxSatiatedBalance;
-    }
-
-    @Override
-    long getInitialSatiatedConsumptionLimit() {
-        return mInitialSatiatedConsumptionLimit;
-    }
-
-    @Override
-    long getMinSatiatedConsumptionLimit() {
-        return mMinSatiatedConsumptionLimit;
-    }
-
-    @Override
-    long getMaxSatiatedConsumptionLimit() {
-        return mMaxSatiatedConsumptionLimit;
-    }
-
-    @NonNull
-    @Override
-    int[] getCostModifiers() {
-        return COST_MODIFIERS;
-    }
-
-    @Nullable
-    @Override
-    Action getAction(@AppAction int actionId) {
-        return mActions.get(actionId);
-    }
-
-    @Nullable
-    @Override
-    Reward getReward(@UtilityReward int rewardId) {
-        return mRewards.get(rewardId);
-    }
-
-    private void loadConstants(String policyValuesString,
-            @Nullable DeviceConfig.Properties properties) {
-        mActions.clear();
-        mRewards.clear();
-
-        try {
-            mUserSettingDeviceConfigMediator.setSettingsString(policyValuesString);
-            mUserSettingDeviceConfigMediator.setDeviceConfigProperties(properties);
-        } catch (IllegalArgumentException e) {
-            Slog.e(TAG, "Global setting key incorrect: ", e);
-        }
-
-        mMinSatiatedBalanceOther = getConstantAsCake(
-            KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP, DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES);
-        mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(
-                KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
-                DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
-                mMinSatiatedBalanceOther);
-        mMinSatiatedBalanceExempted = getConstantAsCake(
-                KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED,
-                DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
-                mMinSatiatedBalanceHeadlessSystemApp);
-        mMaxSatiatedBalance = getConstantAsCake(
-            KEY_AM_MAX_SATIATED_BALANCE, DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
-            Math.max(arcToCake(1), mMinSatiatedBalanceExempted));
-        mMinSatiatedConsumptionLimit = getConstantAsCake(
-                KEY_AM_MIN_CONSUMPTION_LIMIT, DEFAULT_AM_MIN_CONSUMPTION_LIMIT_CAKES,
-                arcToCake(1));
-        mInitialSatiatedConsumptionLimit = getConstantAsCake(
-                KEY_AM_INITIAL_CONSUMPTION_LIMIT, DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES,
-                mMinSatiatedConsumptionLimit);
-        mMaxSatiatedConsumptionLimit = getConstantAsCake(
-                KEY_AM_MAX_CONSUMPTION_LIMIT, DEFAULT_AM_MAX_CONSUMPTION_LIMIT_CAKES,
-                mInitialSatiatedConsumptionLimit);
-
-        final long exactAllowWhileIdleWakeupBasePrice = getConstantAsCake(
-                KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE,
-                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE_CAKES);
-
-        // Apps must hold the SCHEDULE_EXACT_ALARM or USE_EXACT_ALARMS permission in order to use
-        // exact alarms. Since the user has the option of granting/revoking the permission, we can
-        // be a little lenient on the action cost checks and only stop the action if the app has
-        // run out of credits, and not when the system has run out of stock.
-        mActions.put(ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE,
-                new Action(ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE,
-                        getConstantAsCake(
-                                KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP_CAKES),
-                        exactAllowWhileIdleWakeupBasePrice,
-                        /* respectsStockLimit */ false));
-        mActions.put(ACTION_ALARM_WAKEUP_EXACT,
-                new Action(ACTION_ALARM_WAKEUP_EXACT,
-                        getConstantAsCake(
-                                KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP_CAKES),
-                        getConstantAsCake(
-                                KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE,
-                                DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE_CAKES),
-                        /* respectsStockLimit */ false));
-
-        final long inexactAllowWhileIdleWakeupBasePrice =
-                getConstantAsCake(
-                        KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE,
-                        DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE_CAKES);
-
-        mActions.put(ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE,
-                new Action(ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE,
-                        getConstantAsCake(
-                                KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP_CAKES),
-                        inexactAllowWhileIdleWakeupBasePrice,
-                        /* respectsStockLimit */ false));
-        mActions.put(ACTION_ALARM_WAKEUP_INEXACT,
-                new Action(ACTION_ALARM_WAKEUP_INEXACT,
-                        getConstantAsCake(
-                                KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP_CAKES),
-                        getConstantAsCake(
-                                KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE,
-                                DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE_CAKES),
-                        /* respectsStockLimit */ false));
-
-        final long exactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(
-                KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE,
-                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES);
-        mActions.put(ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE,
-                new Action(ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE,
-                        getConstantAsCake(
-                                KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP_CAKES),
-                        exactAllowWhileIdleNonWakeupBasePrice,
-                        /* respectsStockLimit */ false));
-
-        mActions.put(ACTION_ALARM_NONWAKEUP_EXACT,
-                new Action(ACTION_ALARM_NONWAKEUP_EXACT,
-                        getConstantAsCake(
-                                KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP_CAKES),
-                        getConstantAsCake(
-                                KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE,
-                                DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE_CAKES),
-                        /* respectsStockLimit */ false));
-
-        final long inexactAllowWhileIdleNonWakeupBasePrice = getConstantAsCake(
-                KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE,
-                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE_CAKES);
-        final long inexactAllowWhileIdleNonWakeupCtp = getConstantAsCake(
-                KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP,
-                DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP_CAKES);
-        mActions.put(ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE,
-                new Action(ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE,
-                        inexactAllowWhileIdleNonWakeupCtp,
-                        inexactAllowWhileIdleNonWakeupBasePrice));
-
-        mActions.put(ACTION_ALARM_NONWAKEUP_INEXACT,
-                new Action(ACTION_ALARM_NONWAKEUP_INEXACT,
-                        getConstantAsCake(
-                                KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP,
-                                DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP_CAKES),
-                        getConstantAsCake(
-                                KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE,
-                                DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE_CAKES)));
-        mActions.put(ACTION_ALARM_CLOCK,
-                new Action(ACTION_ALARM_CLOCK,
-                        getConstantAsCake(
-                                KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP,
-                                DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP_CAKES),
-                        getConstantAsCake(
-                                KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE,
-                                DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE_CAKES),
-                        /* respectsStockLimit */ false));
-
-        mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY,
-                getConstantAsCake(
-                        KEY_AM_REWARD_TOP_ACTIVITY_INSTANT,
-                        DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT_CAKES),
-                getConstantAsCake(
-                        KEY_AM_REWARD_TOP_ACTIVITY_ONGOING,
-                        DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING_CAKES),
-                getConstantAsCake(
-                        KEY_AM_REWARD_TOP_ACTIVITY_MAX,
-                        DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX_CAKES)));
-        mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN,
-                getConstantAsCake(
-                        KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT,
-                        DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES),
-                getConstantAsCake(
-                        KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING,
-                        DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES),
-                getConstantAsCake(
-                        KEY_AM_REWARD_NOTIFICATION_SEEN_MAX,
-                        DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX_CAKES)));
-        mRewards.put(REWARD_NOTIFICATION_INTERACTION,
-                new Reward(REWARD_NOTIFICATION_INTERACTION,
-                        getConstantAsCake(
-                                KEY_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT,
-                                DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES),
-                        getConstantAsCake(
-                                KEY_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING,
-                                DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES),
-                        getConstantAsCake(
-                                KEY_AM_REWARD_NOTIFICATION_INTERACTION_MAX,
-                                DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES)));
-        mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION,
-                getConstantAsCake(
-                        KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT,
-                        DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT_CAKES),
-                getConstantAsCake(
-                        KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING,
-                        DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING_CAKES),
-                getConstantAsCake(
-                        KEY_AM_REWARD_WIDGET_INTERACTION_MAX,
-                        DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX_CAKES)));
-        mRewards.put(REWARD_OTHER_USER_INTERACTION,
-                new Reward(REWARD_OTHER_USER_INTERACTION,
-                        getConstantAsCake(
-                                KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT,
-                                DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES),
-                        getConstantAsCake(
-                                KEY_AM_REWARD_OTHER_USER_INTERACTION_ONGOING,
-                                DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES),
-                        getConstantAsCake(
-                                KEY_AM_REWARD_OTHER_USER_INTERACTION_MAX,
-                                DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX_CAKES)));
-    }
-
-    @Override
-    void dump(IndentingPrintWriter pw) {
-        pw.println("Min satiated balances:");
-        pw.increaseIndent();
-        pw.print("Exempted", cakeToString(mMinSatiatedBalanceExempted)).println();
-        pw.print("Other", cakeToString(mMinSatiatedBalanceOther)).println();
-        pw.decreaseIndent();
-        pw.print("Max satiated balance", cakeToString(mMaxSatiatedBalance)).println();
-        pw.print("Consumption limits: [");
-        pw.print(cakeToString(mMinSatiatedConsumptionLimit));
-        pw.print(", ");
-        pw.print(cakeToString(mInitialSatiatedConsumptionLimit));
-        pw.print(", ");
-        pw.print(cakeToString(mMaxSatiatedConsumptionLimit));
-        pw.println("]");
-
-        pw.println();
-        pw.println("Actions:");
-        pw.increaseIndent();
-        for (int i = 0; i < mActions.size(); ++i) {
-            dumpAction(pw, mActions.valueAt(i));
-        }
-        pw.decreaseIndent();
-
-        pw.println();
-        pw.println("Rewards:");
-        pw.increaseIndent();
-        for (int i = 0; i < mRewards.size(); ++i) {
-            dumpReward(pw, mRewards.valueAt(i));
-        }
-        pw.decreaseIndent();
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Analyst.java b/apex/jobscheduler/service/java/com/android/server/tare/Analyst.java
deleted file mode 100644
index 06333f1..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/Analyst.java
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
-
-import static com.android.server.tare.EconomicPolicy.TYPE_ACTION;
-import static com.android.server.tare.EconomicPolicy.TYPE_REGULATION;
-import static com.android.server.tare.EconomicPolicy.TYPE_REWARD;
-import static com.android.server.tare.EconomicPolicy.getEventType;
-import static com.android.server.tare.TareUtils.cakeToString;
-
-import android.annotation.NonNull;
-import android.os.BatteryManagerInternal;
-import android.os.RemoteException;
-import android.util.IndentingPrintWriter;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.IBatteryStats;
-import com.android.server.LocalServices;
-import com.android.server.am.BatteryStatsService;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Responsible for maintaining statistics and analysis of TARE's performance.
- */
-public class Analyst {
-    private static final String TAG = "TARE-" + Analyst.class.getSimpleName();
-    private static final boolean DEBUG = InternalResourceService.DEBUG
-            || Log.isLoggable(TAG, Log.DEBUG);
-
-    private static final int NUM_PERIODS_TO_RETAIN = 8;
-    @VisibleForTesting
-    static final long MIN_REPORT_DURATION_FOR_RESET = 24 * HOUR_IN_MILLIS;
-
-    static final class Report {
-        /** How much the battery was discharged over the tracked period. */
-        public int cumulativeBatteryDischarge = 0;
-        public int currentBatteryLevel = 0;
-        /**
-         * Profit from performing actions. This excludes special circumstances where we charge the
-         * app
-         * less than the action's CTP.
-         */
-        public long cumulativeProfit = 0;
-        public int numProfitableActions = 0;
-        /**
-         * Losses from performing actions for special circumstances (eg. for a TOP app) where we
-         * charge
-         * the app less than the action's CTP.
-         */
-        public long cumulativeLoss = 0;
-        public int numUnprofitableActions = 0;
-        /**
-         * The total number of rewards given to apps over this period.
-         */
-        public long cumulativeRewards = 0;
-        public int numRewards = 0;
-        /**
-         * Regulations that increased an app's balance.
-         */
-        public long cumulativePositiveRegulations = 0;
-        public int numPositiveRegulations = 0;
-        /**
-         * Regulations that decreased an app's balance.
-         */
-        public long cumulativeNegativeRegulations = 0;
-        public int numNegativeRegulations = 0;
-
-        /**
-         * The approximate amount of time the screen has been off while on battery while this
-         * report has been active.
-         */
-        public long screenOffDurationMs = 0;
-        /**
-         * The approximate amount of battery discharge while this report has been active.
-         */
-        public long screenOffDischargeMah = 0;
-        /** The offset used to get the delta when polling the screen off time from BatteryStats. */
-        private long bsScreenOffRealtimeBase = 0;
-        /**
-         * The offset used to get the delta when polling the screen off discharge from BatteryStats.
-         */
-        private long bsScreenOffDischargeMahBase = 0;
-
-        private void clear() {
-            cumulativeBatteryDischarge = 0;
-            currentBatteryLevel = 0;
-            cumulativeProfit = 0;
-            numProfitableActions = 0;
-            cumulativeLoss = 0;
-            numUnprofitableActions = 0;
-            cumulativeRewards = 0;
-            numRewards = 0;
-            cumulativePositiveRegulations = 0;
-            numPositiveRegulations = 0;
-            cumulativeNegativeRegulations = 0;
-            numNegativeRegulations = 0;
-            screenOffDurationMs = 0;
-            screenOffDischargeMah = 0;
-            bsScreenOffRealtimeBase = 0;
-            bsScreenOffDischargeMahBase = 0;
-        }
-    }
-
-    private final IBatteryStats mIBatteryStats;
-
-    private int mPeriodIndex = 0;
-    /** How much the battery was discharged over the tracked period. */
-    private final Report[] mReports = new Report[NUM_PERIODS_TO_RETAIN];
-
-    Analyst() {
-        this(BatteryStatsService.getService());
-    }
-
-    @VisibleForTesting Analyst(IBatteryStats iBatteryStats) {
-        mIBatteryStats = iBatteryStats;
-    }
-
-    /** Returns the list of most recent reports, with the oldest report first. */
-    @NonNull
-    List<Report> getReports() {
-        final List<Report> list = new ArrayList<>(NUM_PERIODS_TO_RETAIN);
-        for (int i = 1; i <= NUM_PERIODS_TO_RETAIN; ++i) {
-            final int idx = (mPeriodIndex + i) % NUM_PERIODS_TO_RETAIN;
-            final Report report = mReports[idx];
-            if (report != null) {
-                list.add(report);
-            }
-        }
-        return list;
-    }
-
-    long getBatteryScreenOffDischargeMah() {
-        long discharge = 0;
-        for (Report report : mReports) {
-            if (report == null) {
-                continue;
-            }
-            discharge += report.screenOffDischargeMah;
-        }
-        return discharge;
-    }
-
-    long getBatteryScreenOffDurationMs() {
-        long duration = 0;
-        for (Report report : mReports) {
-            if (report == null) {
-                continue;
-            }
-            duration += report.screenOffDurationMs;
-        }
-        return duration;
-    }
-
-    /**
-     * Tracks the given reports instead of whatever is currently saved. Reports should be ordered
-     * oldest to most recent.
-     */
-    void loadReports(@NonNull List<Report> reports) {
-        final int numReports = reports.size();
-        mPeriodIndex = Math.max(0, Math.min(NUM_PERIODS_TO_RETAIN, numReports) - 1);
-        for (int i = 0; i < NUM_PERIODS_TO_RETAIN; ++i) {
-            if (i < numReports) {
-                mReports[i] = reports.get(i);
-            } else {
-                mReports[i] = null;
-            }
-        }
-        final Report latest = mReports[mPeriodIndex];
-        if (latest != null) {
-            latest.bsScreenOffRealtimeBase = getLatestBatteryScreenOffRealtimeMs();
-            latest.bsScreenOffDischargeMahBase = getLatestScreenOffDischargeMah();
-        }
-    }
-
-    void noteBatteryLevelChange(int newBatteryLevel) {
-        final boolean deviceDischargedEnough = mReports[mPeriodIndex] != null
-                && newBatteryLevel >= 90
-                // Battery level is increasing, so device is charging.
-                && mReports[mPeriodIndex].currentBatteryLevel < newBatteryLevel
-                && mReports[mPeriodIndex].cumulativeBatteryDischarge >= 25;
-        final boolean reportLongEnough = mReports[mPeriodIndex] != null
-                // Battery level is increasing, so device is charging.
-                && mReports[mPeriodIndex].currentBatteryLevel < newBatteryLevel
-                && mReports[mPeriodIndex].screenOffDurationMs >= MIN_REPORT_DURATION_FOR_RESET;
-        final boolean shouldStartNewReport = deviceDischargedEnough || reportLongEnough;
-        if (shouldStartNewReport) {
-            mPeriodIndex = (mPeriodIndex + 1) % NUM_PERIODS_TO_RETAIN;
-            if (mReports[mPeriodIndex] != null) {
-                final Report report = mReports[mPeriodIndex];
-                report.clear();
-                report.currentBatteryLevel = newBatteryLevel;
-                report.bsScreenOffRealtimeBase = getLatestBatteryScreenOffRealtimeMs();
-                report.bsScreenOffDischargeMahBase = getLatestScreenOffDischargeMah();
-                return;
-            }
-        }
-
-        if (mReports[mPeriodIndex] == null) {
-            Report report = initializeReport();
-            mReports[mPeriodIndex] = report;
-            report.currentBatteryLevel = newBatteryLevel;
-            return;
-        }
-
-        final Report report = mReports[mPeriodIndex];
-        if (newBatteryLevel < report.currentBatteryLevel) {
-            report.cumulativeBatteryDischarge += (report.currentBatteryLevel - newBatteryLevel);
-
-            final long latestScreenOffRealtime = getLatestBatteryScreenOffRealtimeMs();
-            final long latestScreenOffDischargeMah = getLatestScreenOffDischargeMah();
-            if (report.bsScreenOffRealtimeBase > latestScreenOffRealtime) {
-                // BatteryStats reset
-                report.bsScreenOffRealtimeBase = 0;
-                report.bsScreenOffDischargeMahBase = 0;
-            }
-            report.screenOffDurationMs +=
-                    (latestScreenOffRealtime - report.bsScreenOffRealtimeBase);
-            report.screenOffDischargeMah +=
-                    (latestScreenOffDischargeMah - report.bsScreenOffDischargeMahBase);
-            report.bsScreenOffRealtimeBase = latestScreenOffRealtime;
-            report.bsScreenOffDischargeMahBase = latestScreenOffDischargeMah;
-        }
-        report.currentBatteryLevel = newBatteryLevel;
-    }
-
-    void noteTransaction(@NonNull Ledger.Transaction transaction) {
-        if (mReports[mPeriodIndex] == null) {
-            mReports[mPeriodIndex] = initializeReport();
-        }
-        final Report report = mReports[mPeriodIndex];
-        switch (getEventType(transaction.eventId)) {
-            case TYPE_ACTION:
-                // For now, assume all instances where price < CTP is a special instance.
-                // TODO: add an explicit signal for special circumstances
-                if (-transaction.delta > transaction.ctp) {
-                    report.cumulativeProfit += (-transaction.delta - transaction.ctp);
-                    report.numProfitableActions++;
-                } else if (-transaction.delta < transaction.ctp) {
-                    report.cumulativeLoss += (transaction.ctp + transaction.delta);
-                    report.numUnprofitableActions++;
-                }
-                break;
-            case TYPE_REGULATION:
-                if (transaction.delta > 0) {
-                    report.cumulativePositiveRegulations += transaction.delta;
-                    report.numPositiveRegulations++;
-                } else if (transaction.delta < 0) {
-                    report.cumulativeNegativeRegulations -= transaction.delta;
-                    report.numNegativeRegulations++;
-                }
-                break;
-            case TYPE_REWARD:
-                if (transaction.delta != 0) {
-                    report.cumulativeRewards += transaction.delta;
-                    report.numRewards++;
-                }
-                break;
-        }
-    }
-
-    void tearDown() {
-        for (int i = 0; i < mReports.length; ++i) {
-            mReports[i] = null;
-        }
-        mPeriodIndex = 0;
-    }
-
-    private long getLatestBatteryScreenOffRealtimeMs() {
-        try {
-            return mIBatteryStats.computeBatteryScreenOffRealtimeMs();
-        } catch (RemoteException e) {
-            // Shouldn't happen
-            return 0;
-        }
-    }
-
-    private long getLatestScreenOffDischargeMah() {
-        try {
-            return mIBatteryStats.getScreenOffDischargeMah();
-        } catch (RemoteException e) {
-            // Shouldn't happen
-            return 0;
-        }
-    }
-
-    @NonNull
-    private Report initializeReport() {
-        final Report report = new Report();
-        report.bsScreenOffRealtimeBase = getLatestBatteryScreenOffRealtimeMs();
-        report.bsScreenOffDischargeMahBase = getLatestScreenOffDischargeMah();
-        return report;
-    }
-
-    @NonNull
-    private String padStringWithSpaces(@NonNull String text, int targetLength) {
-        // Make sure to have at least one space on either side.
-        final int padding = Math.max(2, targetLength - text.length()) >>> 1;
-        return " ".repeat(padding) + text + " ".repeat(padding);
-    }
-
-    void dump(IndentingPrintWriter pw) {
-        final BatteryManagerInternal bmi = LocalServices.getService(BatteryManagerInternal.class);
-        final long batteryCapacityMah = bmi.getBatteryFullCharge() / 1000;
-        pw.println("Reports:");
-        pw.increaseIndent();
-        pw.print("      Total Discharge");
-        final int statColsLength = 47;
-        pw.print(padStringWithSpaces("Profit (avg/action : avg/discharge)", statColsLength));
-        pw.print(padStringWithSpaces("Loss (avg/action : avg/discharge)", statColsLength));
-        pw.print(padStringWithSpaces("Rewards (avg/reward : avg/discharge)", statColsLength));
-        pw.print(padStringWithSpaces("+Regs (avg/reg : avg/discharge)", statColsLength));
-        pw.print(padStringWithSpaces("-Regs (avg/reg : avg/discharge)", statColsLength));
-        pw.print(padStringWithSpaces("Bg drain estimate", statColsLength));
-        pw.println();
-        for (int r = 0; r < NUM_PERIODS_TO_RETAIN; ++r) {
-            final int idx = (mPeriodIndex - r + NUM_PERIODS_TO_RETAIN) % NUM_PERIODS_TO_RETAIN;
-            final Report report = mReports[idx];
-            if (report == null) {
-                continue;
-            }
-            pw.print("t-");
-            pw.print(r);
-            pw.print(":  ");
-            pw.print(padStringWithSpaces(Integer.toString(report.cumulativeBatteryDischarge), 15));
-            if (report.numProfitableActions > 0) {
-                final String perDischarge = report.cumulativeBatteryDischarge > 0
-                        ? cakeToString(report.cumulativeProfit / report.cumulativeBatteryDischarge)
-                        : "N/A";
-                pw.print(padStringWithSpaces(String.format("%s (%s : %s)",
-                                cakeToString(report.cumulativeProfit),
-                                cakeToString(report.cumulativeProfit / report.numProfitableActions),
-                                perDischarge),
-                        statColsLength));
-            } else {
-                pw.print(padStringWithSpaces("N/A", statColsLength));
-            }
-            if (report.numUnprofitableActions > 0) {
-                final String perDischarge = report.cumulativeBatteryDischarge > 0
-                        ? cakeToString(report.cumulativeLoss / report.cumulativeBatteryDischarge)
-                        : "N/A";
-                pw.print(padStringWithSpaces(String.format("%s (%s : %s)",
-                                cakeToString(report.cumulativeLoss),
-                                cakeToString(report.cumulativeLoss / report.numUnprofitableActions),
-                                perDischarge),
-                        statColsLength));
-            } else {
-                pw.print(padStringWithSpaces("N/A", statColsLength));
-            }
-            if (report.numRewards > 0) {
-                final String perDischarge = report.cumulativeBatteryDischarge > 0
-                        ? cakeToString(report.cumulativeRewards / report.cumulativeBatteryDischarge)
-                        : "N/A";
-                pw.print(padStringWithSpaces(String.format("%s (%s : %s)",
-                                cakeToString(report.cumulativeRewards),
-                                cakeToString(report.cumulativeRewards / report.numRewards),
-                                perDischarge),
-                        statColsLength));
-            } else {
-                pw.print(padStringWithSpaces("N/A", statColsLength));
-            }
-            if (report.numPositiveRegulations > 0) {
-                final String perDischarge = report.cumulativeBatteryDischarge > 0
-                        ? cakeToString(
-                        report.cumulativePositiveRegulations / report.cumulativeBatteryDischarge)
-                        : "N/A";
-                pw.print(padStringWithSpaces(String.format("%s (%s : %s)",
-                                cakeToString(report.cumulativePositiveRegulations),
-                                cakeToString(report.cumulativePositiveRegulations
-                                        / report.numPositiveRegulations),
-                                perDischarge),
-                        statColsLength));
-            } else {
-                pw.print(padStringWithSpaces("N/A", statColsLength));
-            }
-            if (report.numNegativeRegulations > 0) {
-                final String perDischarge = report.cumulativeBatteryDischarge > 0
-                        ? cakeToString(
-                        report.cumulativeNegativeRegulations / report.cumulativeBatteryDischarge)
-                        : "N/A";
-                pw.print(padStringWithSpaces(String.format("%s (%s : %s)",
-                                cakeToString(report.cumulativeNegativeRegulations),
-                                cakeToString(report.cumulativeNegativeRegulations
-                                        / report.numNegativeRegulations),
-                                perDischarge),
-                        statColsLength));
-            } else {
-                pw.print(padStringWithSpaces("N/A", statColsLength));
-            }
-            if (report.screenOffDurationMs > 0) {
-                pw.print(padStringWithSpaces(String.format("%d mAh (%.2f%%/hr)",
-                                report.screenOffDischargeMah,
-                                100.0 * report.screenOffDischargeMah * HOUR_IN_MILLIS
-                                        / (batteryCapacityMah * report.screenOffDurationMs)),
-                        statColsLength));
-            } else {
-                pw.print(padStringWithSpaces("N/A", statColsLength));
-            }
-            pw.println();
-        }
-        pw.decreaseIndent();
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/ChargingModifier.java b/apex/jobscheduler/service/java/com/android/server/tare/ChargingModifier.java
deleted file mode 100644
index 2b48d49..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/ChargingModifier.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.BatteryManager;
-import android.os.SystemClock;
-import android.util.IndentingPrintWriter;
-import android.util.Log;
-import android.util.Slog;
-
-/** Modifier that makes things free when the device is charging. */
-class ChargingModifier extends Modifier {
-    private static final String TAG = "TARE-" + ChargingModifier.class.getSimpleName();
-    private static final boolean DEBUG = InternalResourceService.DEBUG
-            || Log.isLoggable(TAG, Log.DEBUG);
-
-    private final InternalResourceService mIrs;
-    private final ChargingTracker mChargingTracker;
-
-    ChargingModifier(@NonNull InternalResourceService irs) {
-        super();
-        mIrs = irs;
-        mChargingTracker = new ChargingTracker();
-    }
-
-    @Override
-    public void setup() {
-        mChargingTracker.startTracking(mIrs.getContext());
-    }
-
-    @Override
-    public void tearDown() {
-        mChargingTracker.stopTracking(mIrs.getContext());
-    }
-
-    @Override
-    long getModifiedCostToProduce(long ctp) {
-        return modifyValue(ctp);
-    }
-
-    @Override
-    long getModifiedPrice(long price) {
-        return modifyValue(price);
-    }
-
-    private long modifyValue(long val) {
-        if (mChargingTracker.mCharging) {
-            return 0;
-        }
-        return val;
-    }
-
-    @Override
-    void dump(IndentingPrintWriter pw) {
-        pw.print("charging=");
-        pw.println(mChargingTracker.mCharging);
-    }
-
-    private final class ChargingTracker extends BroadcastReceiver {
-        private boolean mIsSetup = false;
-
-        /**
-         * Track whether we're "charging", where charging means that we're ready to commit to
-         * doing work.
-         */
-        private volatile boolean mCharging;
-
-        public void startTracking(@NonNull Context context) {
-            if (mIsSetup) {
-                return;
-            }
-
-            final IntentFilter filter = new IntentFilter();
-            filter.addAction(BatteryManager.ACTION_CHARGING);
-            filter.addAction(BatteryManager.ACTION_DISCHARGING);
-            context.registerReceiver(this, filter);
-
-            // Initialise tracker state.
-            final BatteryManager batteryManager = context.getSystemService(BatteryManager.class);
-            mCharging = batteryManager.isCharging();
-
-            mIsSetup = true;
-        }
-
-        public void stopTracking(@NonNull Context context) {
-            if (!mIsSetup) {
-                return;
-            }
-
-            context.unregisterReceiver(this);
-            mIsSetup = false;
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (BatteryManager.ACTION_CHARGING.equals(action)) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Received charging intent, fired @ "
-                            + SystemClock.elapsedRealtime());
-                }
-                if (!mCharging) {
-                    mCharging = true;
-                    mIrs.onDeviceStateChanged();
-                }
-            } else if (BatteryManager.ACTION_DISCHARGING.equals(action)) {
-                if (DEBUG) {
-                    Slog.d(TAG, "Disconnected from power.");
-                }
-                if (mCharging) {
-                    mCharging = false;
-                    mIrs.onDeviceStateChanged();
-                }
-            }
-        }
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/CompleteEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/CompleteEconomicPolicy.java
deleted file mode 100644
index 7a96076..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/CompleteEconomicPolicy.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.tare.EconomyManager;
-import android.provider.DeviceConfig;
-import android.util.ArraySet;
-import android.util.IndentingPrintWriter;
-import android.util.Slog;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
-
-import libcore.util.EmptyArray;
-
-/** Combines all enabled policies into one. */
-public class CompleteEconomicPolicy extends EconomicPolicy {
-    private static final String TAG = "TARE-" + CompleteEconomicPolicy.class.getSimpleName();
-
-    private final CompleteInjector mInjector;
-    private final ArraySet<EconomicPolicy> mEnabledEconomicPolicies = new ArraySet<>();
-    /** Lazily populated set of actions covered by this policy. */
-    private final SparseArray<Action> mActions = new SparseArray<>();
-    /** Lazily populated set of rewards covered by this policy. */
-    private final SparseArray<Reward> mRewards = new SparseArray<>();
-    private int mEnabledEconomicPolicyIds = 0;
-    private int[] mCostModifiers = EmptyArray.INT;
-    private long mInitialConsumptionLimit;
-    private long mMinConsumptionLimit;
-    private long mMaxConsumptionLimit;
-
-    CompleteEconomicPolicy(@NonNull InternalResourceService irs) {
-        this(irs, new CompleteInjector());
-    }
-
-    @VisibleForTesting
-    CompleteEconomicPolicy(@NonNull InternalResourceService irs,
-            @NonNull CompleteInjector injector) {
-        super(irs);
-        mInjector = injector;
-
-        if (mInjector.isPolicyEnabled(POLICY_ALARM, null)) {
-            mEnabledEconomicPolicyIds |= POLICY_ALARM;
-            mEnabledEconomicPolicies.add(new AlarmManagerEconomicPolicy(mIrs, mInjector));
-        }
-        if (mInjector.isPolicyEnabled(POLICY_JOB, null)) {
-            mEnabledEconomicPolicyIds |= POLICY_JOB;
-            mEnabledEconomicPolicies.add(new JobSchedulerEconomicPolicy(mIrs, mInjector));
-        }
-    }
-
-    @Override
-    void setup(@NonNull DeviceConfig.Properties properties) {
-        super.setup(properties);
-
-        mActions.clear();
-        mRewards.clear();
-
-        mEnabledEconomicPolicies.clear();
-        mEnabledEconomicPolicyIds = 0;
-        if (mInjector.isPolicyEnabled(POLICY_ALARM, properties)) {
-            mEnabledEconomicPolicyIds |= POLICY_ALARM;
-            mEnabledEconomicPolicies.add(new AlarmManagerEconomicPolicy(mIrs, mInjector));
-        }
-        if (mInjector.isPolicyEnabled(POLICY_JOB, properties)) {
-            mEnabledEconomicPolicyIds |= POLICY_JOB;
-            mEnabledEconomicPolicies.add(new JobSchedulerEconomicPolicy(mIrs, mInjector));
-        }
-
-        ArraySet<Integer> costModifiers = new ArraySet<>();
-        for (int i = 0; i < mEnabledEconomicPolicies.size(); ++i) {
-            final int[] sm = mEnabledEconomicPolicies.valueAt(i).getCostModifiers();
-            for (int s : sm) {
-                costModifiers.add(s);
-            }
-        }
-        mCostModifiers = ArrayUtils.convertToIntArray(costModifiers);
-
-        for (int i = 0; i < mEnabledEconomicPolicies.size(); ++i) {
-            mEnabledEconomicPolicies.valueAt(i).setup(properties);
-        }
-        updateLimits();
-    }
-
-    private void updateLimits() {
-        long initialConsumptionLimit = 0;
-        long minConsumptionLimit = 0;
-        long maxConsumptionLimit = 0;
-        for (int i = 0; i < mEnabledEconomicPolicies.size(); ++i) {
-            final EconomicPolicy economicPolicy = mEnabledEconomicPolicies.valueAt(i);
-            initialConsumptionLimit += economicPolicy.getInitialSatiatedConsumptionLimit();
-            minConsumptionLimit += economicPolicy.getMinSatiatedConsumptionLimit();
-            maxConsumptionLimit += economicPolicy.getMaxSatiatedConsumptionLimit();
-        }
-        mInitialConsumptionLimit = initialConsumptionLimit;
-        mMinConsumptionLimit = minConsumptionLimit;
-        mMaxConsumptionLimit = maxConsumptionLimit;
-    }
-
-    @Override
-    long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) {
-        long min = 0;
-        for (int i = 0; i < mEnabledEconomicPolicies.size(); ++i) {
-            min += mEnabledEconomicPolicies.valueAt(i).getMinSatiatedBalance(userId, pkgName);
-        }
-        return min;
-    }
-
-    @Override
-    long getMaxSatiatedBalance(int userId, @NonNull String pkgName) {
-        long max = 0;
-        for (int i = 0; i < mEnabledEconomicPolicies.size(); ++i) {
-            max += mEnabledEconomicPolicies.valueAt(i).getMaxSatiatedBalance(userId, pkgName);
-        }
-        return max;
-    }
-
-    @Override
-    long getInitialSatiatedConsumptionLimit() {
-        return mInitialConsumptionLimit;
-    }
-
-    @Override
-    long getMinSatiatedConsumptionLimit() {
-        return mMinConsumptionLimit;
-    }
-
-    @Override
-    long getMaxSatiatedConsumptionLimit() {
-        return mMaxConsumptionLimit;
-    }
-
-    @NonNull
-    @Override
-    int[] getCostModifiers() {
-        return mCostModifiers == null ? EmptyArray.INT : mCostModifiers;
-    }
-
-    @Nullable
-    @Override
-    Action getAction(@AppAction int actionId) {
-        if (mActions.contains(actionId)) {
-            return mActions.get(actionId);
-        }
-
-        long ctp = 0, price = 0;
-        boolean exists = false;
-        for (int i = 0; i < mEnabledEconomicPolicies.size(); ++i) {
-            Action a = mEnabledEconomicPolicies.valueAt(i).getAction(actionId);
-            if (a != null) {
-                exists = true;
-                ctp += a.costToProduce;
-                price += a.basePrice;
-            }
-        }
-        final Action action = exists ? new Action(actionId, ctp, price) : null;
-        mActions.put(actionId, action);
-        return action;
-    }
-
-    @Nullable
-    @Override
-    Reward getReward(@UtilityReward int rewardId) {
-        if (mRewards.contains(rewardId)) {
-            return mRewards.get(rewardId);
-        }
-
-        long instantReward = 0, ongoingReward = 0, maxReward = 0;
-        boolean exists = false;
-        for (int i = 0; i < mEnabledEconomicPolicies.size(); ++i) {
-            Reward r = mEnabledEconomicPolicies.valueAt(i).getReward(rewardId);
-            if (r != null) {
-                exists = true;
-                instantReward += r.instantReward;
-                ongoingReward += r.ongoingRewardPerSecond;
-                maxReward += r.maxDailyReward;
-            }
-        }
-        final Reward reward = exists
-                ? new Reward(rewardId, instantReward, ongoingReward, maxReward) : null;
-        mRewards.put(rewardId, reward);
-        return reward;
-    }
-
-    boolean isPolicyEnabled(@Policy int policyId) {
-        return (mEnabledEconomicPolicyIds & policyId) == policyId;
-    }
-
-    int getEnabledPolicyIds() {
-        return mEnabledEconomicPolicyIds;
-    }
-
-    @VisibleForTesting
-    static class CompleteInjector extends Injector {
-
-        boolean isPolicyEnabled(int policy, @Nullable DeviceConfig.Properties properties) {
-            final String key;
-            final boolean defaultEnable;
-            switch (policy) {
-                case POLICY_ALARM:
-                    key = EconomyManager.KEY_ENABLE_POLICY_ALARM;
-                    defaultEnable = EconomyManager.DEFAULT_ENABLE_POLICY_ALARM;
-                    break;
-                case POLICY_JOB:
-                    key = EconomyManager.KEY_ENABLE_POLICY_JOB_SCHEDULER;
-                    defaultEnable = EconomyManager.DEFAULT_ENABLE_POLICY_JOB_SCHEDULER;
-                    break;
-                default:
-                    Slog.wtf(TAG, "Unknown policy: " + policy);
-                    return false;
-            }
-            if (properties == null) {
-                return defaultEnable;
-            }
-            return properties.getBoolean(key, defaultEnable);
-        }
-    }
-
-    @Override
-    void dump(IndentingPrintWriter pw) {
-        dumpActiveModifiers(pw);
-
-        pw.println();
-        pw.println(getClass().getSimpleName() + ":");
-        pw.increaseIndent();
-
-        pw.println("Cached actions:");
-        pw.increaseIndent();
-        for (int i = 0; i < mActions.size(); ++i) {
-            final Action action = mActions.valueAt(i);
-            if (action != null) {
-                dumpAction(pw, action);
-            }
-        }
-        pw.decreaseIndent();
-
-        pw.println();
-        pw.println("Cached rewards:");
-        pw.increaseIndent();
-        for (int i = 0; i < mRewards.size(); ++i) {
-            final Reward reward = mRewards.valueAt(i);
-            if (reward != null) {
-                dumpReward(pw, reward);
-            }
-        }
-        pw.decreaseIndent();
-
-        for (int i = 0; i < mEnabledEconomicPolicies.size(); i++) {
-            final EconomicPolicy economicPolicy = mEnabledEconomicPolicies.valueAt(i);
-            pw.println();
-            pw.print("(Includes) ");
-            pw.println(economicPolicy.getClass().getSimpleName() + ":");
-            pw.increaseIndent();
-            economicPolicy.dump(pw);
-            pw.decreaseIndent();
-        }
-        pw.decreaseIndent();
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java b/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java
deleted file mode 100644
index 47ff307..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/DeviceIdleModifier.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.PowerManager;
-import android.util.IndentingPrintWriter;
-import android.util.Log;
-
-/** Modifier that makes things more expensive in light and deep doze. */
-class DeviceIdleModifier extends Modifier {
-    private static final String TAG = "TARE-" + DeviceIdleModifier.class.getSimpleName();
-    private static final boolean DEBUG = InternalResourceService.DEBUG
-            || Log.isLoggable(TAG, Log.DEBUG);
-
-    private final InternalResourceService mIrs;
-    private final PowerManager mPowerManager;
-    private final DeviceIdleTracker mDeviceIdleTracker;
-
-    DeviceIdleModifier(@NonNull InternalResourceService irs) {
-        super();
-        mIrs = irs;
-        mPowerManager = irs.getContext().getSystemService(PowerManager.class);
-        mDeviceIdleTracker = new DeviceIdleTracker();
-    }
-
-    @Override
-    public void setup() {
-        mDeviceIdleTracker.startTracking(mIrs.getContext());
-    }
-
-    @Override
-    public void tearDown() {
-        mDeviceIdleTracker.stopTracking(mIrs.getContext());
-    }
-
-    @Override
-    long getModifiedCostToProduce(long ctp) {
-        if (mDeviceIdleTracker.mDeviceIdle) {
-            return (long) (1.2 * ctp);
-        }
-        if (mDeviceIdleTracker.mDeviceLightIdle) {
-            return (long) (1.1 * ctp);
-        }
-        return ctp;
-    }
-
-    @Override
-    void dump(IndentingPrintWriter pw) {
-        pw.print("idle=");
-        pw.println(mDeviceIdleTracker.mDeviceIdle);
-        pw.print("lightIdle=");
-        pw.println(mDeviceIdleTracker.mDeviceLightIdle);
-    }
-
-    private final class DeviceIdleTracker extends BroadcastReceiver {
-        private boolean mIsSetup = false;
-
-        private volatile boolean mDeviceIdle;
-        private volatile boolean mDeviceLightIdle;
-
-        DeviceIdleTracker() {
-        }
-
-        void startTracking(@NonNull Context context) {
-            if (mIsSetup) {
-                return;
-            }
-
-            IntentFilter filter = new IntentFilter();
-            filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
-            filter.addAction(PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED);
-            context.registerReceiver(this, filter);
-
-            // Initialise tracker state.
-            mDeviceIdle = mPowerManager.isDeviceIdleMode();
-            mDeviceLightIdle = mPowerManager.isLightDeviceIdleMode();
-
-            mIsSetup = true;
-        }
-
-        void stopTracking(@NonNull Context context) {
-            if (!mIsSetup) {
-                return;
-            }
-
-            context.unregisterReceiver(this);
-            mIsSetup = false;
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action)) {
-                if (mDeviceIdle != mPowerManager.isDeviceIdleMode()) {
-                    mDeviceIdle = mPowerManager.isDeviceIdleMode();
-                    mIrs.onDeviceStateChanged();
-                }
-            } else if (PowerManager.ACTION_LIGHT_DEVICE_IDLE_MODE_CHANGED.equals(action)) {
-                if (mDeviceLightIdle != mPowerManager.isLightDeviceIdleMode()) {
-                    mDeviceLightIdle = mPowerManager.isLightDeviceIdleMode();
-                    mIrs.onDeviceStateChanged();
-                }
-            }
-        }
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
deleted file mode 100644
index 61096b9..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static android.app.tare.EconomyManager.parseCreditValue;
-
-import static com.android.server.tare.Modifier.COST_MODIFIER_CHARGING;
-import static com.android.server.tare.Modifier.COST_MODIFIER_DEVICE_IDLE;
-import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE;
-import static com.android.server.tare.Modifier.COST_MODIFIER_PROCESS_STATE;
-import static com.android.server.tare.Modifier.NUM_COST_MODIFIERS;
-import static com.android.server.tare.TareUtils.cakeToString;
-
-import android.annotation.CallSuper;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
-import android.util.IndentingPrintWriter;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.utils.UserSettingDeviceConfigMediator;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * An EconomicPolicy includes pricing information and daily ARC requirements and suggestions.
- * Policies are defined per participating system service. This allows each service’s EconomicPolicy
- * to be isolated while allowing the core economic system to scale across policies to achieve a
- * logical system-wide value system.
- */
-public abstract class EconomicPolicy {
-    private static final String TAG = "TARE-" + EconomicPolicy.class.getSimpleName();
-
-    private static final int SHIFT_TYPE = 30;
-    static final int MASK_TYPE = 0b11 << SHIFT_TYPE;
-    static final int TYPE_REGULATION = 0 << SHIFT_TYPE;
-    static final int TYPE_ACTION = 1 << SHIFT_TYPE;
-    static final int TYPE_REWARD = 2 << SHIFT_TYPE;
-
-    private static final int SHIFT_POLICY = 28;
-    static final int MASK_POLICY = 0b11 << SHIFT_POLICY;
-    static final int ALL_POLICIES = MASK_POLICY;
-    // Reserve 0 for the base/common policy.
-    public static final int POLICY_ALARM = 1 << SHIFT_POLICY;
-    public static final int POLICY_JOB = 2 << SHIFT_POLICY;
-
-    static final int MASK_EVENT = -1 ^ (MASK_TYPE | MASK_POLICY);
-
-    static final int REGULATION_BASIC_INCOME = TYPE_REGULATION | 0;
-    static final int REGULATION_BIRTHRIGHT = TYPE_REGULATION | 1;
-    static final int REGULATION_WEALTH_RECLAMATION = TYPE_REGULATION | 2;
-    static final int REGULATION_PROMOTION = TYPE_REGULATION | 3;
-    static final int REGULATION_DEMOTION = TYPE_REGULATION | 4;
-    /** App is fully restricted from running in the background. */
-    static final int REGULATION_BG_RESTRICTED = TYPE_REGULATION | 5;
-    static final int REGULATION_BG_UNRESTRICTED = TYPE_REGULATION | 6;
-    static final int REGULATION_FORCE_STOP = TYPE_REGULATION | 8;
-
-    static final int REWARD_NOTIFICATION_SEEN = TYPE_REWARD | 0;
-    static final int REWARD_NOTIFICATION_INTERACTION = TYPE_REWARD | 1;
-    static final int REWARD_TOP_ACTIVITY = TYPE_REWARD | 2;
-    static final int REWARD_WIDGET_INTERACTION = TYPE_REWARD | 3;
-    static final int REWARD_OTHER_USER_INTERACTION = TYPE_REWARD | 4;
-
-    @IntDef({
-            AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE,
-            AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_EXACT,
-            AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE,
-            AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_INEXACT,
-            AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE,
-            AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_EXACT,
-            AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE,
-            AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_INEXACT,
-            AlarmManagerEconomicPolicy.ACTION_ALARM_CLOCK,
-            JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START,
-            JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING,
-            JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_START,
-            JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING,
-            JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_START,
-            JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING,
-            JobSchedulerEconomicPolicy.ACTION_JOB_LOW_START,
-            JobSchedulerEconomicPolicy.ACTION_JOB_LOW_RUNNING,
-            JobSchedulerEconomicPolicy.ACTION_JOB_MIN_START,
-            JobSchedulerEconomicPolicy.ACTION_JOB_MIN_RUNNING,
-            JobSchedulerEconomicPolicy.ACTION_JOB_TIMEOUT,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface AppAction {
-    }
-
-    @IntDef({
-            TYPE_ACTION,
-            TYPE_REGULATION,
-            TYPE_REWARD,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface EventType {
-    }
-
-    @IntDef({
-            ALL_POLICIES,
-            POLICY_ALARM,
-            POLICY_JOB,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Policy {
-    }
-
-    @IntDef({
-            REWARD_TOP_ACTIVITY,
-            REWARD_NOTIFICATION_SEEN,
-            REWARD_NOTIFICATION_INTERACTION,
-            REWARD_WIDGET_INTERACTION,
-            REWARD_OTHER_USER_INTERACTION,
-            JobSchedulerEconomicPolicy.REWARD_APP_INSTALL,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface UtilityReward {
-    }
-
-    static class Action {
-        /** Unique id (including across policies) for this action. */
-        public final int id;
-        /**
-         * How many ARCs the system says it takes to perform this action.
-         */
-        public final long costToProduce;
-        /**
-         * The base price to perform this action. If this is
-         * less than the {@link #costToProduce}, then the system should not perform
-         * the action unless a modifier lowers the cost to produce.
-         */
-        public final long basePrice;
-        /**
-         * Whether the remaining stock limit affects an app's ability to perform this action.
-         * If {@code false}, then the action can be performed, even if the cost is higher
-         * than the remaining stock. This does not affect checking against an app's balance.
-         */
-        public final boolean respectsStockLimit;
-
-        Action(int id, long costToProduce, long basePrice) {
-            this(id, costToProduce, basePrice, true);
-        }
-
-        Action(int id, long costToProduce, long basePrice, boolean respectsStockLimit) {
-            this.id = id;
-            this.costToProduce = costToProduce;
-            this.basePrice = basePrice;
-            this.respectsStockLimit = respectsStockLimit;
-        }
-    }
-
-    static class Reward {
-        /** Unique id (including across policies) for this reward. */
-        @UtilityReward
-        public final int id;
-        public final long instantReward;
-        /** Reward credited per second of ongoing activity. */
-        public final long ongoingRewardPerSecond;
-        /** The maximum amount an app can earn from this reward within a 24 hour period. */
-        public final long maxDailyReward;
-
-        Reward(int id, long instantReward, long ongoingReward, long maxDailyReward) {
-            this.id = id;
-            this.instantReward = instantReward;
-            this.ongoingRewardPerSecond = ongoingReward;
-            this.maxDailyReward = maxDailyReward;
-        }
-    }
-
-    static class Cost {
-        public final long costToProduce;
-        public final long price;
-
-        Cost(long costToProduce, long price) {
-            this.costToProduce = costToProduce;
-            this.price = price;
-        }
-    }
-
-    protected final InternalResourceService mIrs;
-    protected final UserSettingDeviceConfigMediator mUserSettingDeviceConfigMediator;
-    private static final Modifier[] COST_MODIFIER_BY_INDEX = new Modifier[NUM_COST_MODIFIERS];
-
-    EconomicPolicy(@NonNull InternalResourceService irs) {
-        mIrs = irs;
-        // Don't cross the streams! Mixing Settings/local user config changes with DeviceConfig
-        // config can cause issues since the scales may be different, so use one or the other.
-        // If user settings exist, then just stick with the Settings constants, even if there
-        // are invalid values.
-        mUserSettingDeviceConfigMediator =
-                new UserSettingDeviceConfigMediator.SettingsOverridesAllMediator(',');
-        for (int mId : getCostModifiers()) {
-            initModifier(mId, irs);
-        }
-    }
-
-    @CallSuper
-    void setup(@NonNull DeviceConfig.Properties properties) {
-        for (int i = 0; i < NUM_COST_MODIFIERS; ++i) {
-            final Modifier modifier = COST_MODIFIER_BY_INDEX[i];
-            if (modifier != null) {
-                modifier.setup();
-            }
-        }
-    }
-
-    @CallSuper
-    void tearDown() {
-        for (int i = 0; i < NUM_COST_MODIFIERS; ++i) {
-            final Modifier modifier = COST_MODIFIER_BY_INDEX[i];
-            if (modifier != null) {
-                modifier.tearDown();
-            }
-        }
-    }
-
-    /**
-     * Returns the minimum suggested balance an app should have when the device is at 100% battery.
-     * This takes into account any exemptions the app may have.
-     */
-    abstract long getMinSatiatedBalance(int userId, @NonNull String pkgName);
-
-    /**
-     * Returns the maximum balance an app should have when the device is at 100% battery. This
-     * exists to ensure that no single app accumulate all available resources and increases fairness
-     * for all apps.
-     */
-    abstract long getMaxSatiatedBalance(int userId, @NonNull String pkgName);
-
-    /**
-     * Returns the maximum number of cakes that should be consumed during a full 100% discharge
-     * cycle. This is the initial limit. The system may choose to increase the limit over time,
-     * but the increased limit should never exceed the value returned from
-     * {@link #getMaxSatiatedConsumptionLimit()}.
-     */
-    abstract long getInitialSatiatedConsumptionLimit();
-
-    /**
-     * Returns the minimum number of cakes that should be available for consumption during a full
-     * 100% discharge cycle.
-     */
-    abstract long getMinSatiatedConsumptionLimit();
-
-    /**
-     * Returns the maximum number of cakes that should be available for consumption during a full
-     * 100% discharge cycle.
-     */
-    abstract long getMaxSatiatedConsumptionLimit();
-
-    /** Return the set of modifiers that should apply to this policy's costs. */
-    @NonNull
-    abstract int[] getCostModifiers();
-
-    @Nullable
-    abstract Action getAction(@AppAction int actionId);
-
-    @Nullable
-    abstract Reward getReward(@UtilityReward int rewardId);
-
-    void dump(IndentingPrintWriter pw) {
-    }
-
-    @NonNull
-    final Cost getCostOfAction(int actionId, int userId, @NonNull String pkgName) {
-        final Action action = getAction(actionId);
-        if (action == null || mIrs.isVip(userId, pkgName)) {
-            return new Cost(0, 0);
-        }
-        long ctp = action.costToProduce;
-        long price = action.basePrice;
-        final int[] costModifiers = getCostModifiers();
-        boolean useProcessStatePriceDeterminant = false;
-        for (int costModifier : costModifiers) {
-            if (costModifier == COST_MODIFIER_PROCESS_STATE) {
-                useProcessStatePriceDeterminant = true;
-            } else {
-                final Modifier modifier = getModifier(costModifier);
-                ctp = modifier.getModifiedCostToProduce(ctp);
-                price = modifier.getModifiedPrice(price);
-            }
-        }
-        // ProcessStateModifier needs to be done last.
-        if (useProcessStatePriceDeterminant) {
-            ProcessStateModifier processStateModifier =
-                    (ProcessStateModifier) getModifier(COST_MODIFIER_PROCESS_STATE);
-            price = processStateModifier.getModifiedPrice(userId, pkgName, ctp, price);
-        }
-        return new Cost(ctp, price);
-    }
-
-    private static void initModifier(@Modifier.CostModifier final int modifierId,
-            @NonNull InternalResourceService irs) {
-        if (modifierId < 0 || modifierId >= COST_MODIFIER_BY_INDEX.length) {
-            throw new IllegalArgumentException("Invalid modifier id " + modifierId);
-        }
-        Modifier modifier = COST_MODIFIER_BY_INDEX[modifierId];
-        if (modifier == null) {
-            switch (modifierId) {
-                case COST_MODIFIER_CHARGING:
-                    modifier = new ChargingModifier(irs);
-                    break;
-                case COST_MODIFIER_DEVICE_IDLE:
-                    modifier = new DeviceIdleModifier(irs);
-                    break;
-                case COST_MODIFIER_POWER_SAVE_MODE:
-                    modifier = new PowerSaveModeModifier(irs);
-                    break;
-                case COST_MODIFIER_PROCESS_STATE:
-                    modifier = new ProcessStateModifier(irs);
-                    break;
-                default:
-                    throw new IllegalArgumentException("Invalid modifier id " + modifierId);
-            }
-            COST_MODIFIER_BY_INDEX[modifierId] = modifier;
-        }
-    }
-
-    @NonNull
-    private static Modifier getModifier(@Modifier.CostModifier final int modifierId) {
-        if (modifierId < 0 || modifierId >= COST_MODIFIER_BY_INDEX.length) {
-            throw new IllegalArgumentException("Invalid modifier id " + modifierId);
-        }
-        final Modifier modifier = COST_MODIFIER_BY_INDEX[modifierId];
-        if (modifier == null) {
-            throw new IllegalStateException(
-                    "Modifier #" + modifierId + " was never initialized");
-        }
-        return modifier;
-    }
-
-    @EventType
-    static int getEventType(int eventId) {
-        return eventId & MASK_TYPE;
-    }
-
-    static boolean isReward(int eventId) {
-        return getEventType(eventId) == TYPE_REWARD;
-    }
-
-    @NonNull
-    static String eventToString(int eventId) {
-        switch (eventId & MASK_TYPE) {
-            case TYPE_ACTION:
-                return actionToString(eventId);
-
-            case TYPE_REGULATION:
-                return regulationToString(eventId);
-
-            case TYPE_REWARD:
-                return rewardToString(eventId);
-
-            default:
-                return "UNKNOWN_EVENT:" + Integer.toHexString(eventId);
-        }
-    }
-
-    @NonNull
-    static String actionToString(int eventId) {
-        switch (eventId & MASK_POLICY) {
-            case POLICY_ALARM:
-                switch (eventId) {
-                    case AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE:
-                        return "ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE";
-                    case AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_EXACT:
-                        return "ALARM_WAKEUP_EXACT";
-                    case AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE:
-                        return "ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE";
-                    case AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_INEXACT:
-                        return "ALARM_WAKEUP_INEXACT";
-                    case AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE:
-                        return "ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE";
-                    case AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_EXACT:
-                        return "ALARM_NONWAKEUP_EXACT";
-                    case AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE:
-                        return "ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE";
-                    case AlarmManagerEconomicPolicy.ACTION_ALARM_NONWAKEUP_INEXACT:
-                        return "ALARM_NONWAKEUP_INEXACT";
-                    case AlarmManagerEconomicPolicy.ACTION_ALARM_CLOCK:
-                        return "ALARM_CLOCK";
-                }
-                break;
-
-            case POLICY_JOB:
-                switch (eventId) {
-                    case JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START:
-                        return "JOB_MAX_START";
-                    case JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING:
-                        return "JOB_MAX_RUNNING";
-                    case JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_START:
-                        return "JOB_HIGH_START";
-                    case JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING:
-                        return "JOB_HIGH_RUNNING";
-                    case JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_START:
-                        return "JOB_DEFAULT_START";
-                    case JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING:
-                        return "JOB_DEFAULT_RUNNING";
-                    case JobSchedulerEconomicPolicy.ACTION_JOB_LOW_START:
-                        return "JOB_LOW_START";
-                    case JobSchedulerEconomicPolicy.ACTION_JOB_LOW_RUNNING:
-                        return "JOB_LOW_RUNNING";
-                    case JobSchedulerEconomicPolicy.ACTION_JOB_MIN_START:
-                        return "JOB_MIN_START";
-                    case JobSchedulerEconomicPolicy.ACTION_JOB_MIN_RUNNING:
-                        return "JOB_MIN_RUNNING";
-                    case JobSchedulerEconomicPolicy.ACTION_JOB_TIMEOUT:
-                        return "JOB_TIMEOUT";
-                }
-                break;
-        }
-        return "UNKNOWN_ACTION:" + Integer.toHexString(eventId);
-    }
-
-    @NonNull
-    static String regulationToString(int eventId) {
-        switch (eventId) {
-            case REGULATION_BASIC_INCOME:
-                return "BASIC_INCOME";
-            case REGULATION_BIRTHRIGHT:
-                return "BIRTHRIGHT";
-            case REGULATION_WEALTH_RECLAMATION:
-                return "WEALTH_RECLAMATION";
-            case REGULATION_PROMOTION:
-                return "PROMOTION";
-            case REGULATION_DEMOTION:
-                return "DEMOTION";
-            case REGULATION_BG_RESTRICTED:
-                return "BG_RESTRICTED";
-            case REGULATION_BG_UNRESTRICTED:
-                return "BG_UNRESTRICTED";
-            case REGULATION_FORCE_STOP:
-                return "FORCE_STOP";
-        }
-        return "UNKNOWN_REGULATION:" + Integer.toHexString(eventId);
-    }
-
-    @NonNull
-    static String rewardToString(int eventId) {
-        switch (eventId) {
-            case REWARD_TOP_ACTIVITY:
-                return "REWARD_TOP_ACTIVITY";
-            case REWARD_NOTIFICATION_SEEN:
-                return "REWARD_NOTIFICATION_SEEN";
-            case REWARD_NOTIFICATION_INTERACTION:
-                return "REWARD_NOTIFICATION_INTERACTION";
-            case REWARD_WIDGET_INTERACTION:
-                return "REWARD_WIDGET_INTERACTION";
-            case REWARD_OTHER_USER_INTERACTION:
-                return "REWARD_OTHER_USER_INTERACTION";
-            case JobSchedulerEconomicPolicy.REWARD_APP_INSTALL:
-                return "REWARD_JOB_APP_INSTALL";
-        }
-        return "UNKNOWN_REWARD:" + Integer.toHexString(eventId);
-    }
-
-    protected long getConstantAsCake(String key, long defaultValCake) {
-        return getConstantAsCake(key, defaultValCake, 0);
-    }
-
-    protected long getConstantAsCake(String key, long defaultValCake, long minValCake) {
-        return Math.max(minValCake,
-                parseCreditValue(
-                        mUserSettingDeviceConfigMediator.getString(key, null), defaultValCake));
-    }
-
-    @VisibleForTesting
-    static class Injector {
-        @Nullable
-        String getSettingsGlobalString(@NonNull ContentResolver resolver, @NonNull String name) {
-            return Settings.Global.getString(resolver, name);
-        }
-    }
-
-    protected static void dumpActiveModifiers(IndentingPrintWriter pw) {
-        for (int i = 0; i < NUM_COST_MODIFIERS; ++i) {
-            pw.print("Modifier ");
-            pw.println(i);
-            pw.increaseIndent();
-
-            Modifier modifier = COST_MODIFIER_BY_INDEX[i];
-            if (modifier != null) {
-                modifier.dump(pw);
-            } else {
-                pw.println("NOT ACTIVE");
-            }
-
-            pw.decreaseIndent();
-        }
-    }
-
-    protected static void dumpAction(IndentingPrintWriter pw, @NonNull Action action) {
-        pw.print(actionToString(action.id));
-        pw.print(": ");
-        pw.print("ctp=");
-        pw.print(cakeToString(action.costToProduce));
-        pw.print(", basePrice=");
-        pw.print(cakeToString(action.basePrice));
-        pw.println();
-    }
-
-    protected static void dumpReward(IndentingPrintWriter pw, @NonNull Reward reward) {
-        pw.print(rewardToString(reward.id));
-        pw.print(": ");
-        pw.print("instant=");
-        pw.print(cakeToString(reward.instantReward));
-        pw.print(", ongoing/sec=");
-        pw.print(cakeToString(reward.ongoingRewardPerSecond));
-        pw.print(", maxDaily=");
-        pw.print(cakeToString(reward.maxDailyReward));
-        pw.println();
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/EconomyManagerInternal.java b/apex/jobscheduler/service/java/com/android/server/tare/EconomyManagerInternal.java
deleted file mode 100644
index 5b305ad..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/EconomyManagerInternal.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.tare.EconomyManager;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * Interface for the system server to deal with the resource economy subsystem.
- *
- * @hide
- */
-public interface EconomyManagerInternal {
-    /**
-     * Used to indicate a future action an app is expected to take.
-     */
-    final class AnticipatedAction {
-        public final int actionId;
-        public final int numInstantaneousCalls;
-        public final long ongoingDurationMs;
-        private final int mHashCode;
-
-        /**
-         * @param actionId              The expected action
-         * @param numInstantaneousCalls How many instantaneous times the action will be performed
-         * @param ongoingDurationMs     An estimate of how long the ongoing event will go on for
-         */
-        public AnticipatedAction(@EconomicPolicy.AppAction int actionId,
-                int numInstantaneousCalls, long ongoingDurationMs) {
-            this.actionId = actionId;
-            this.numInstantaneousCalls = numInstantaneousCalls;
-            this.ongoingDurationMs = ongoingDurationMs;
-
-            int hash = 0;
-            hash = 31 * hash + actionId;
-            hash = 31 * hash + numInstantaneousCalls;
-            hash = 31 * hash + (int) (ongoingDurationMs ^ (ongoingDurationMs >>> 32));
-            mHashCode = hash;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            AnticipatedAction that = (AnticipatedAction) o;
-            return actionId == that.actionId
-                    && numInstantaneousCalls == that.numInstantaneousCalls
-                    && ongoingDurationMs == that.ongoingDurationMs;
-        }
-
-        @Override
-        public int hashCode() {
-            return mHashCode;
-        }
-    }
-
-    /**
-     * A collection of {@link AnticipatedAction AnticipatedActions} that will be performed together.
-     */
-    final class ActionBill {
-        private static final Comparator<AnticipatedAction>
-                sAnticipatedActionComparator = Comparator.comparingInt(aa -> aa.actionId);
-
-        private final List<AnticipatedAction> mAnticipatedActions;
-        private final int mHashCode;
-
-        public ActionBill(@NonNull List<AnticipatedAction> anticipatedActions) {
-            List<AnticipatedAction> actions = new ArrayList<>(anticipatedActions);
-            actions.sort(sAnticipatedActionComparator);
-            mAnticipatedActions = Collections.unmodifiableList(actions);
-
-            int hash = 0;
-            for (int i = 0; i < mAnticipatedActions.size(); ++i) {
-                hash = 31 * hash + mAnticipatedActions.get(i).hashCode();
-            }
-            mHashCode = hash;
-        }
-
-        List<AnticipatedAction> getAnticipatedActions() {
-            return mAnticipatedActions;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            ActionBill that = (ActionBill) o;
-            return mAnticipatedActions.equals(that.mAnticipatedActions);
-        }
-
-        @Override
-        public int hashCode() {
-            return mHashCode;
-        }
-    }
-
-    /** Listener for when an app's ability to afford a bill changes. */
-    interface AffordabilityChangeListener {
-        void onAffordabilityChanged(int userId, @NonNull String pkgName, @NonNull ActionBill bill,
-                boolean canAfford);
-    }
-
-    /** Listener for various TARE state changes. */
-    interface TareStateChangeListener {
-        void onTareEnabledModeChanged(@EconomyManager.EnabledMode int tareEnabledMode);
-    }
-
-    /**
-     * Return {@code true} if the app is able to pay for the anticipated actions.
-     */
-    boolean canPayFor(int userId, @NonNull String pkgName, @NonNull ActionBill bill);
-
-    /**
-     * Returns the maximum duration (in milliseconds) that the specified app can afford the bill,
-     * based on current prices.
-     */
-    long getMaxDurationMs(int userId, @NonNull String pkgName, @NonNull ActionBill bill);
-
-    /** Returns the current TARE enabled mode. */
-    @EconomyManager.EnabledMode
-    int getEnabledMode();
-
-    /** Returns the current TARE enabled mode for the specified policy. */
-    @EconomyManager.EnabledMode
-    int getEnabledMode(@EconomicPolicy.Policy int policyId);
-
-    /**
-     * Register an {@link AffordabilityChangeListener} to track when an app's ability to afford the
-     * indicated bill changes.
-     */
-    void registerAffordabilityChangeListener(int userId, @NonNull String pkgName,
-            @NonNull AffordabilityChangeListener listener, @NonNull ActionBill bill);
-
-    /**
-     * Unregister a {@link AffordabilityChangeListener} from being notified of any changes to an
-     * app's ability to afford the specified bill.
-     */
-    void unregisterAffordabilityChangeListener(int userId, @NonNull String pkgName,
-            @NonNull AffordabilityChangeListener listener, @NonNull ActionBill bill);
-
-    /**
-     * Register a {@link TareStateChangeListener} to track when TARE's state changes.
-     */
-    void registerTareStateChangeListener(@NonNull TareStateChangeListener listener,
-            @EconomicPolicy.Policy int policyId);
-
-    /**
-     * Unregister a {@link TareStateChangeListener} from being notified when TARE's state changes.
-     */
-    void unregisterTareStateChangeListener(@NonNull TareStateChangeListener listener);
-
-    /**
-     * Note that an instantaneous event has occurred. The event must be specified in one of the
-     * EconomicPolicies.
-     *
-     * @param tag An optional tag that can be used to differentiate the same event for the same app.
-     */
-    void noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId,
-            @Nullable String tag);
-
-    /**
-     * Note that a long-running event is starting. The event must be specified in one of the
-     * EconomicPolicies. You must always call
-     * {@link #noteOngoingEventStopped(int, String, int, String)} to end the event. Ongoing
-     * events will be separated and grouped by event-tag combinations. There must be an equal
-     * number of start() and stop() calls for the same event-tag combination in order for the
-     * tracking to finally stop (ie. ongoing events are ref-counted).
-     *
-     * @param tag An optional tag that can be used to differentiate the same event for the same app.
-     */
-    void noteOngoingEventStarted(int userId, @NonNull String pkgName, int eventId,
-            @Nullable String tag);
-
-    /**
-     * Note that a long-running event has stopped. The event must be specified in one of the
-     * EconomicPolicies. Ongoing events are separated and grouped by event-tag combinations.
-     * There must be an equal number of start() and stop() calls for the same event-tag combination
-     * in order for the tracking to finally stop (ie. ongoing events are ref-counted).
-     *
-     * @param tag An optional tag that can be used to differentiate the same event for the same app.
-     */
-    void noteOngoingEventStopped(int userId, @NonNull String pkgName, int eventId,
-            @Nullable String tag);
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/InstalledPackageInfo.java b/apex/jobscheduler/service/java/com/android/server/tare/InstalledPackageInfo.java
deleted file mode 100644
index 49c6d1b..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/InstalledPackageInfo.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.UserIdInt;
-import android.app.AppGlobals;
-import android.content.Context;
-import android.content.Intent;
-import android.content.PermissionChecker;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.InstallSourceInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.os.RemoteException;
-
-import com.android.internal.util.ArrayUtils;
-
-/** POJO to cache only the information about installed packages that TARE cares about. */
-class InstalledPackageInfo {
-    static final int NO_UID = -1;
-
-    /**
-     * Flags to use when querying for front door activities. Disabled components are included
-     * are included for completeness since the app can enable them at any time.
-     */
-    private static final int HEADLESS_APP_QUERY_FLAGS = PackageManager.MATCH_DIRECT_BOOT_AWARE
-            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
-            | PackageManager.MATCH_DISABLED_COMPONENTS;
-
-    public final int uid;
-    public final String packageName;
-    public final boolean hasCode;
-    /**
-     * Whether the app is a system app that is "headless." Headless in this context means that
-     * the app doesn't have any "front door" activities --- activities that would show in the
-     * launcher.
-     */
-    public final boolean isHeadlessSystemApp;
-    public final boolean isSystemInstaller;
-    @Nullable
-    public final String installerPackageName;
-
-    InstalledPackageInfo(@NonNull Context context, @UserIdInt int userId,
-            @NonNull PackageInfo packageInfo) {
-        final ApplicationInfo applicationInfo = packageInfo.applicationInfo;
-        uid = applicationInfo == null ? NO_UID : applicationInfo.uid;
-        packageName = packageInfo.packageName;
-        hasCode = applicationInfo != null && applicationInfo.hasCode();
-
-        final PackageManager packageManager = context.getPackageManager();
-        final Intent frontDoorActivityIntent = new Intent(Intent.ACTION_MAIN)
-                .addCategory(Intent.CATEGORY_LAUNCHER)
-                .setPackage(packageName);
-        isHeadlessSystemApp = applicationInfo != null
-                && (applicationInfo.isSystemApp() || applicationInfo.isUpdatedSystemApp())
-                && ArrayUtils.isEmpty(
-                        packageManager.queryIntentActivitiesAsUser(
-                                frontDoorActivityIntent, HEADLESS_APP_QUERY_FLAGS, userId));
-
-        isSystemInstaller = applicationInfo != null
-                && ArrayUtils.indexOf(
-                packageInfo.requestedPermissions, Manifest.permission.INSTALL_PACKAGES) >= 0
-                && PackageManager.PERMISSION_GRANTED
-                == PermissionChecker.checkPermissionForPreflight(context,
-                Manifest.permission.INSTALL_PACKAGES, PermissionChecker.PID_UNKNOWN,
-                applicationInfo.uid, packageName);
-        InstallSourceInfo installSourceInfo = null;
-        try {
-            installSourceInfo = AppGlobals.getPackageManager().getInstallSourceInfo(packageName,
-                    userId);
-        } catch (RemoteException e) {
-            // Shouldn't happen.
-        }
-        installerPackageName =
-                installSourceInfo == null ? null : installSourceInfo.getInstallingPackageName();
-    }
-
-    @Override
-    public String toString() {
-        return "IPO{"
-                + "uid=" + uid
-                + ", pkgName=" + packageName
-                + (hasCode ? " HAS_CODE" : "")
-                + (isHeadlessSystemApp ? " HEADLESS_SYSTEM" : "")
-                + (isSystemInstaller ? " SYSTEM_INSTALLER" : "")
-                + ", installer=" + installerPackageName
-                + '}';
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
deleted file mode 100644
index 6635484..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
+++ /dev/null
@@ -1,1900 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static android.app.tare.EconomyManager.ENABLED_MODE_OFF;
-import static android.app.tare.EconomyManager.ENABLED_MODE_ON;
-import static android.app.tare.EconomyManager.ENABLED_MODE_SHADOW;
-import static android.app.tare.EconomyManager.enabledModeToString;
-import static android.provider.Settings.Global.TARE_ALARM_MANAGER_CONSTANTS;
-import static android.provider.Settings.Global.TARE_JOB_SCHEDULER_CONSTANTS;
-import static android.text.format.DateUtils.DAY_IN_MILLIS;
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
-import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
-
-import static com.android.server.tare.TareUtils.appToString;
-import static com.android.server.tare.TareUtils.cakeToString;
-import static com.android.server.tare.TareUtils.getCurrentTimeMillis;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.AlarmManager;
-import android.app.AppOpsManager;
-import android.app.tare.EconomyManager;
-import android.app.tare.IEconomyManager;
-import android.app.usage.UsageEvents;
-import android.app.usage.UsageStatsManagerInternal;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.BatteryManager;
-import android.os.BatteryManagerInternal;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.IDeviceIdleController;
-import android.os.Looper;
-import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.DeviceConfig;
-import android.provider.Settings;
-import android.util.ArraySet;
-import android.util.IndentingPrintWriter;
-import android.util.Log;
-import android.util.Slog;
-import android.util.SparseArrayMap;
-import android.util.SparseLongArray;
-import android.util.SparseSetArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.app.IAppOpsCallback;
-import com.android.internal.app.IAppOpsService;
-import com.android.internal.os.SomeArgs;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.DumpUtils;
-import com.android.server.LocalServices;
-import com.android.server.SystemService;
-import com.android.server.pm.UserManagerInternal;
-import com.android.server.tare.EconomicPolicy.Cost;
-import com.android.server.tare.EconomyManagerInternal.TareStateChangeListener;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Responsible for handling app's ARC count based on events, ensuring ARCs are credited when
- * appropriate, and reclaiming ARCs at the right times. The IRS deals with the high level details
- * while the {@link Agent} deals with the nitty-gritty details.
- *
- * Note on locking: Any function with the suffix 'Locked' needs to lock on {@link #mLock}.
- *
- * @hide
- */
-public class InternalResourceService extends SystemService {
-    public static final String TAG = "TARE-IRS";
-    public static final boolean DEBUG = Log.isLoggable("TARE", Log.DEBUG);
-
-    static final long UNUSED_RECLAMATION_PERIOD_MS = 24 * HOUR_IN_MILLIS;
-    /** How much of an app's unused wealth should be reclaimed periodically. */
-    private static final float DEFAULT_UNUSED_RECLAMATION_PERCENTAGE = .1f;
-    /**
-     * The minimum amount of time an app must not have been used by the user before we start
-     * periodically reclaiming ARCs from it.
-     */
-    private static final long MIN_UNUSED_TIME_MS = 3 * DAY_IN_MILLIS;
-    /** The amount of time to delay reclamation by after boot. */
-    private static final long RECLAMATION_STARTUP_DELAY_MS = 30_000L;
-    /**
-     * The amount of time after TARE has first been set up that a system installer will be allowed
-     * expanded credit privileges.
-     */
-    static final long INSTALLER_FIRST_SETUP_GRACE_PERIOD_MS = 7 * DAY_IN_MILLIS;
-    /**
-     * The amount of time to wait after TARE has first been set up before considering adjusting the
-     * stock/consumption limit.
-     */
-    private static final long STOCK_ADJUSTMENT_FIRST_SETUP_GRACE_PERIOD_MS = 5 * DAY_IN_MILLIS;
-    /**
-     * The battery level above which we may consider quantitative easing (increasing the consumption
-     * limit).
-     */
-    private static final int QUANTITATIVE_EASING_BATTERY_THRESHOLD = 50;
-    /**
-     * The battery level above which we may consider adjusting the desired stock level.
-     */
-    private static final int STOCK_RECALCULATION_BATTERY_THRESHOLD = 80;
-    /**
-     * The amount of time to wait before considering recalculating the desired stock level.
-     */
-    private static final long STOCK_RECALCULATION_DELAY_MS = 16 * HOUR_IN_MILLIS;
-    /**
-     * The minimum amount of time we must have background drain for before considering
-     * recalculating the desired stock level.
-     */
-    private static final long STOCK_RECALCULATION_MIN_DATA_DURATION_MS = 8 * HOUR_IN_MILLIS;
-    private static final int PACKAGE_QUERY_FLAGS =
-            PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
-                    | PackageManager.MATCH_APEX | PackageManager.GET_PERMISSIONS;
-
-    /** Global lock for all resource economy state. */
-    private final Object mLock = new Object();
-
-    private final Handler mHandler;
-    private final BatteryManagerInternal mBatteryManagerInternal;
-    private final PackageManager mPackageManager;
-    private final PackageManagerInternal mPackageManagerInternal;
-    private final UserManagerInternal mUserManagerInternal;
-
-    private IAppOpsService mAppOpsService;
-    private IDeviceIdleController mDeviceIdleController;
-
-    private final Agent mAgent;
-    private final Analyst mAnalyst;
-    private final ConfigObserver mConfigObserver;
-    private final EconomyManagerStub mEconomyManagerStub;
-    private final Scribe mScribe;
-
-    @GuardedBy("mLock")
-    private CompleteEconomicPolicy mCompleteEconomicPolicy;
-
-    @NonNull
-    @GuardedBy("mLock")
-    private final SparseArrayMap<String, InstalledPackageInfo> mPkgCache = new SparseArrayMap<>();
-
-    /** Cached mapping of UIDs (for all users) to a list of packages in the UID. */
-    @GuardedBy("mLock")
-    private final SparseSetArray<String> mUidToPackageCache = new SparseSetArray<>();
-
-    /** Cached mapping of userId+package to their UIDs (for all users) */
-    @GuardedBy("mPackageToUidCache")
-    private final SparseArrayMap<String, Integer> mPackageToUidCache = new SparseArrayMap<>();
-
-    @GuardedBy("mStateChangeListeners")
-    private final SparseSetArray<TareStateChangeListener> mStateChangeListeners =
-            new SparseSetArray<>();
-
-    /**
-     * List of packages that are fully restricted and shouldn't be allowed to run in the background.
-     */
-    @GuardedBy("mLock")
-    private final SparseSetArray<String> mRestrictedApps = new SparseSetArray<>();
-
-    /** List of packages that are "exempted" from battery restrictions. */
-    // TODO(144864180): include userID
-    @GuardedBy("mLock")
-    private ArraySet<String> mExemptedApps = new ArraySet<>();
-
-    @GuardedBy("mLock")
-    private final SparseArrayMap<String, Boolean> mVipOverrides = new SparseArrayMap<>();
-
-    /**
-     * Set of temporary Very Important Packages and when their VIP status ends, in the elapsed
-     * realtime ({@link android.annotation.ElapsedRealtimeLong}) timebase.
-     */
-    @GuardedBy("mLock")
-    private final SparseArrayMap<String, Long> mTemporaryVips = new SparseArrayMap<>();
-
-    /** Set of apps each installer is responsible for installing. */
-    @GuardedBy("mLock")
-    private final SparseArrayMap<String, ArraySet<String>> mInstallers = new SparseArrayMap<>();
-
-    /** The package name of the wellbeing app. */
-    @GuardedBy("mLock")
-    @Nullable
-    private String mWellbeingPackage;
-
-    private volatile boolean mHasBattery = true;
-    @EconomyManager.EnabledMode
-    private volatile int mEnabledMode;
-    private volatile int mBootPhase;
-    private volatile boolean mExemptListLoaded;
-    // In the range [0,100] to represent 0% to 100% battery.
-    @GuardedBy("mLock")
-    private int mCurrentBatteryLevel;
-
-    // TODO(250007395): make configurable per device (via config.xml)
-    private final int mDefaultTargetBackgroundBatteryLifeHours;
-    @GuardedBy("mLock")
-    private int mTargetBackgroundBatteryLifeHours;
-
-    private final IAppOpsCallback mApbListener = new IAppOpsCallback.Stub() {
-        @Override
-        public void opChanged(int op, int uid, String packageName, String persistentDeviceId) {
-            boolean restricted = false;
-            try {
-                restricted = mAppOpsService.checkOperation(
-                        AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, uid, packageName)
-                        != AppOpsManager.MODE_ALLOWED;
-            } catch (RemoteException e) {
-                // Shouldn't happen
-            }
-            final int userId = UserHandle.getUserId(uid);
-            synchronized (mLock) {
-                if (restricted) {
-                    if (mRestrictedApps.add(userId, packageName)) {
-                        mAgent.onAppRestrictedLocked(userId, packageName);
-                    }
-                } else if (mRestrictedApps.remove(UserHandle.getUserId(uid), packageName)) {
-                    mAgent.onAppUnrestrictedLocked(userId, packageName);
-                }
-            }
-        }
-    };
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Nullable
-        private String getPackageName(Intent intent) {
-            Uri uri = intent.getData();
-            return uri != null ? uri.getSchemeSpecificPart() : null;
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            switch (intent.getAction()) {
-                case Intent.ACTION_BATTERY_CHANGED: {
-                    final boolean hasBattery =
-                            intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, mHasBattery);
-                    if (mHasBattery != hasBattery) {
-                        mHasBattery = hasBattery;
-                        mConfigObserver.updateEnabledStatus();
-                    }
-                }
-                break;
-                case Intent.ACTION_BATTERY_LEVEL_CHANGED:
-                    onBatteryLevelChanged();
-                    break;
-                case Intent.ACTION_PACKAGE_FULLY_REMOVED: {
-                    final String pkgName = getPackageName(intent);
-                    final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
-                    onPackageRemoved(pkgUid, pkgName);
-                }
-                break;
-                case Intent.ACTION_PACKAGE_ADDED: {
-                    if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
-                        final String pkgName = getPackageName(intent);
-                        final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
-                        onPackageAdded(pkgUid, pkgName);
-                    }
-                }
-                break;
-                case Intent.ACTION_PACKAGE_RESTARTED: {
-                    final String pkgName = getPackageName(intent);
-                    final int pkgUid = intent.getIntExtra(Intent.EXTRA_UID, -1);
-                    final int userId = UserHandle.getUserId(pkgUid);
-                    onPackageForceStopped(userId, pkgName);
-                }
-                break;
-                case Intent.ACTION_USER_ADDED: {
-                    final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                    onUserAdded(userId);
-                }
-                break;
-                case Intent.ACTION_USER_REMOVED: {
-                    final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
-                    onUserRemoved(userId);
-                }
-                break;
-                case PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED:
-                    onExemptionListChanged();
-                    break;
-            }
-        }
-    };
-
-    private final UsageStatsManagerInternal.UsageEventListener mSurveillanceAgent =
-            new UsageStatsManagerInternal.UsageEventListener() {
-                /**
-                 * Callback to inform listeners of a new event.
-                 */
-                @Override
-                public void onUsageEvent(int userId, @NonNull UsageEvents.Event event) {
-                    // Skip posting a message to the handler for events we don't care about.
-                    switch (event.getEventType()) {
-                        case UsageEvents.Event.ACTIVITY_RESUMED:
-                        case UsageEvents.Event.ACTIVITY_PAUSED:
-                        case UsageEvents.Event.ACTIVITY_STOPPED:
-                        case UsageEvents.Event.ACTIVITY_DESTROYED:
-                        case UsageEvents.Event.USER_INTERACTION:
-                        case UsageEvents.Event.CHOOSER_ACTION:
-                        case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
-                        case UsageEvents.Event.NOTIFICATION_SEEN:
-                            mHandler.obtainMessage(MSG_PROCESS_USAGE_EVENT, userId, 0, event)
-                                    .sendToTarget();
-                            break;
-                        default:
-                            if (DEBUG) {
-                                Slog.d(TAG, "Dropping event " + event.getEventType());
-                            }
-                            break;
-                    }
-                }
-            };
-
-    private final AlarmManager.OnAlarmListener mUnusedWealthReclamationListener =
-            new AlarmManager.OnAlarmListener() {
-                @Override
-                public void onAlarm() {
-                    synchronized (mLock) {
-                        mAgent.reclaimUnusedAssetsLocked(
-                                DEFAULT_UNUSED_RECLAMATION_PERCENTAGE, MIN_UNUSED_TIME_MS, false);
-                        mScribe.setLastReclamationTimeLocked(getCurrentTimeMillis());
-                        scheduleUnusedWealthReclamationLocked();
-                    }
-                }
-            };
-
-    private static final int MSG_NOTIFY_AFFORDABILITY_CHANGE_LISTENER = 0;
-    private static final int MSG_SCHEDULE_UNUSED_WEALTH_RECLAMATION_EVENT = 1;
-    private static final int MSG_PROCESS_USAGE_EVENT = 2;
-    private static final int MSG_NOTIFY_STATE_CHANGE_LISTENERS = 3;
-    private static final int MSG_NOTIFY_STATE_CHANGE_LISTENER = 4;
-    private static final int MSG_CLEAN_UP_TEMP_VIP_LIST = 5;
-    private static final String ALARM_TAG_WEALTH_RECLAMATION = "*tare.reclamation*";
-
-    /**
-     * Initializes the system service.
-     * <p>
-     * Subclasses must define a single argument constructor that accepts the context
-     * and passes it to super.
-     * </p>
-     *
-     * @param context The system server context.
-     */
-    public InternalResourceService(Context context) {
-        super(context);
-
-        mHandler = new IrsHandler(TareHandlerThread.get().getLooper());
-        mBatteryManagerInternal = LocalServices.getService(BatteryManagerInternal.class);
-        mPackageManager = context.getPackageManager();
-        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
-        mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
-        mEconomyManagerStub = new EconomyManagerStub();
-        mAnalyst = new Analyst();
-        mScribe = new Scribe(this, mAnalyst);
-        mCompleteEconomicPolicy = new CompleteEconomicPolicy(this);
-        mAgent = new Agent(this, mScribe, mAnalyst);
-
-        mConfigObserver = new ConfigObserver(mHandler, context);
-
-        mDefaultTargetBackgroundBatteryLifeHours =
-                mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)
-                        ? 100 // ~ 1.0%/hr
-                        : 40; // ~ 2.5%/hr
-        mTargetBackgroundBatteryLifeHours = mDefaultTargetBackgroundBatteryLifeHours;
-
-        publishLocalService(EconomyManagerInternal.class, new LocalService());
-    }
-
-    @Override
-    public void onStart() {
-        publishBinderService(Context.RESOURCE_ECONOMY_SERVICE, mEconomyManagerStub);
-    }
-
-    @Override
-    public void onBootPhase(int phase) {
-        mBootPhase = phase;
-
-        switch (phase) {
-            case PHASE_SYSTEM_SERVICES_READY:
-                mAppOpsService = IAppOpsService.Stub.asInterface(
-                        ServiceManager.getService(Context.APP_OPS_SERVICE));
-                mDeviceIdleController = IDeviceIdleController.Stub.asInterface(
-                        ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
-                mConfigObserver.start();
-                onBootPhaseSystemServicesReady();
-                break;
-            case PHASE_THIRD_PARTY_APPS_CAN_START:
-                onBootPhaseThirdPartyAppsCanStart();
-                break;
-            case PHASE_BOOT_COMPLETED:
-                onBootPhaseBootCompleted();
-                break;
-        }
-    }
-
-    @NonNull
-    Object getLock() {
-        return mLock;
-    }
-
-    /** Returns the installed packages for all users. */
-    @NonNull
-    @GuardedBy("mLock")
-    CompleteEconomicPolicy getCompleteEconomicPolicyLocked() {
-        return mCompleteEconomicPolicy;
-    }
-
-    /** Returns the number of apps that this app is expected to update at some point. */
-    int getAppUpdateResponsibilityCount(final int userId, @NonNull final String pkgName) {
-        synchronized (mLock) {
-            // TODO(248274798): return 0 if the app has lost the install permission
-            return ArrayUtils.size(mInstallers.get(userId, pkgName));
-        }
-    }
-
-    @NonNull
-    SparseArrayMap<String, InstalledPackageInfo> getInstalledPackages() {
-        synchronized (mLock) {
-            return mPkgCache;
-        }
-    }
-
-    /** Returns the installed packages for the specified user. */
-    @NonNull
-    List<InstalledPackageInfo> getInstalledPackages(final int userId) {
-        final List<InstalledPackageInfo> userPkgs = new ArrayList<>();
-        synchronized (mLock) {
-            final int uIdx = mPkgCache.indexOfKey(userId);
-            if (uIdx < 0) {
-                return userPkgs;
-            }
-            for (int p = mPkgCache.numElementsForKeyAt(uIdx) - 1; p >= 0; --p) {
-                final InstalledPackageInfo packageInfo = mPkgCache.valueAt(uIdx, p);
-                userPkgs.add(packageInfo);
-            }
-        }
-        return userPkgs;
-    }
-
-    @Nullable
-    InstalledPackageInfo getInstalledPackageInfo(final int userId, @NonNull final String pkgName) {
-        synchronized (mLock) {
-            return mPkgCache.get(userId, pkgName);
-        }
-    }
-
-    @GuardedBy("mLock")
-    long getConsumptionLimitLocked() {
-        return mCurrentBatteryLevel * mScribe.getSatiatedConsumptionLimitLocked() / 100;
-    }
-
-    @GuardedBy("mLock")
-    long getMinBalanceLocked(final int userId, @NonNull final String pkgName) {
-        return mCurrentBatteryLevel * mCompleteEconomicPolicy.getMinSatiatedBalance(userId, pkgName)
-                / 100;
-    }
-
-    @GuardedBy("mLock")
-    long getInitialSatiatedConsumptionLimitLocked() {
-        return mCompleteEconomicPolicy.getInitialSatiatedConsumptionLimit();
-    }
-
-
-    long getRealtimeSinceFirstSetupMs() {
-        return mScribe.getRealtimeSinceFirstSetupMs(SystemClock.elapsedRealtime());
-    }
-
-    int getUid(final int userId, @NonNull final String pkgName) {
-        synchronized (mPackageToUidCache) {
-            Integer uid = mPackageToUidCache.get(userId, pkgName);
-            if (uid == null) {
-                uid = mPackageManagerInternal.getPackageUid(pkgName, 0, userId);
-                mPackageToUidCache.add(userId, pkgName, uid);
-            }
-            return uid;
-        }
-    }
-
-    @EconomyManager.EnabledMode
-    int getEnabledMode() {
-        return mEnabledMode;
-    }
-
-    @EconomyManager.EnabledMode
-    int getEnabledMode(int policyId) {
-        synchronized (mLock) {
-            // For now, treat enabled policies as using the same enabled mode as full TARE.
-            // TODO: have enabled mode by policy
-            if (mCompleteEconomicPolicy.isPolicyEnabled(policyId)) {
-                return mEnabledMode;
-            }
-            return ENABLED_MODE_OFF;
-        }
-    }
-
-    boolean isHeadlessSystemApp(final int userId, @NonNull String pkgName) {
-        if (pkgName == null) {
-            Slog.wtfStack(TAG, "isHeadlessSystemApp called with null package");
-            return false;
-        }
-        synchronized (mLock) {
-            final InstalledPackageInfo ipo = getInstalledPackageInfo(userId, pkgName);
-            if (ipo != null && ipo.isHeadlessSystemApp) {
-                return true;
-            }
-            // The wellbeing app is pre-set on the device, not expected to be interacted with
-            // much by the user, but can be expected to do work in the background on behalf of
-            // the user. As such, it's a pseudo-headless system app, so treat it as a headless
-            // system app.
-            return pkgName.equals(mWellbeingPackage);
-        }
-    }
-
-    boolean isPackageExempted(final int userId, @NonNull String pkgName) {
-        synchronized (mLock) {
-            return mExemptedApps.contains(pkgName);
-        }
-    }
-
-    boolean isPackageRestricted(final int userId, @NonNull String pkgName) {
-        synchronized (mLock) {
-            return mRestrictedApps.contains(userId, pkgName);
-        }
-    }
-
-    boolean isSystem(final int userId, @NonNull String pkgName) {
-        if ("android".equals(pkgName)) {
-            return true;
-        }
-        return UserHandle.isCore(getUid(userId, pkgName));
-    }
-
-    boolean isVip(final int userId, @NonNull String pkgName) {
-        return isVip(userId, pkgName, SystemClock.elapsedRealtime());
-    }
-
-    boolean isVip(final int userId, @NonNull String pkgName, final long nowElapsed) {
-        synchronized (mLock) {
-            final Boolean override = mVipOverrides.get(userId, pkgName);
-            if (override != null) {
-                return override;
-            }
-        }
-        if (isSystem(userId, pkgName)) {
-            // The government, I mean the system, can create ARCs as it needs to in order to
-            // operate.
-            return true;
-        }
-        synchronized (mLock) {
-            final Long expirationTimeElapsed = mTemporaryVips.get(userId, pkgName);
-            if (expirationTimeElapsed != null) {
-                return nowElapsed <= expirationTimeElapsed;
-            }
-        }
-        return false;
-    }
-
-    void onBatteryLevelChanged() {
-        synchronized (mLock) {
-            final int newBatteryLevel = getCurrentBatteryLevel();
-            mAnalyst.noteBatteryLevelChange(newBatteryLevel);
-            final boolean increased = newBatteryLevel > mCurrentBatteryLevel;
-            if (increased) {
-                if (newBatteryLevel >= STOCK_RECALCULATION_BATTERY_THRESHOLD) {
-                    maybeAdjustDesiredStockLevelLocked();
-                }
-                mAgent.distributeBasicIncomeLocked(newBatteryLevel);
-            } else if (newBatteryLevel == mCurrentBatteryLevel) {
-                // The broadcast is also sent when the plug type changes...
-                return;
-            }
-            mCurrentBatteryLevel = newBatteryLevel;
-            adjustCreditSupplyLocked(increased);
-        }
-    }
-
-    void onDeviceStateChanged() {
-        synchronized (mLock) {
-            mAgent.onDeviceStateChangedLocked();
-        }
-    }
-
-    void onExemptionListChanged() {
-        final int[] userIds = mUserManagerInternal.getUserIds();
-        synchronized (mLock) {
-            final ArraySet<String> removed = mExemptedApps;
-            final ArraySet<String> added = new ArraySet<>();
-            try {
-                mExemptedApps = new ArraySet<>(mDeviceIdleController.getFullPowerWhitelist());
-                mExemptListLoaded = true;
-            } catch (RemoteException e) {
-                // Shouldn't happen.
-            }
-
-            for (int i = mExemptedApps.size() - 1; i >= 0; --i) {
-                final String pkg = mExemptedApps.valueAt(i);
-                if (!removed.contains(pkg)) {
-                    added.add(pkg);
-                }
-                removed.remove(pkg);
-            }
-            for (int a = added.size() - 1; a >= 0; --a) {
-                final String pkgName = added.valueAt(a);
-                for (int userId : userIds) {
-                    // Since the exemption list doesn't specify user ID and we track by user ID,
-                    // we need to see if the app exists on the user before talking to the agent.
-                    // Otherwise, we may end up with invalid ledgers.
-                    final boolean appExists = getUid(userId, pkgName) >= 0;
-                    if (appExists) {
-                        mAgent.onAppExemptedLocked(userId, pkgName);
-                    }
-                }
-            }
-            for (int r = removed.size() - 1; r >= 0; --r) {
-                final String pkgName = removed.valueAt(r);
-                for (int userId : userIds) {
-                    // Since the exemption list doesn't specify user ID and we track by user ID,
-                    // we need to see if the app exists on the user before talking to the agent.
-                    // Otherwise, we may end up with invalid ledgers.
-                    final boolean appExists = getUid(userId, pkgName) >= 0;
-                    if (appExists) {
-                        mAgent.onAppUnexemptedLocked(userId, pkgName);
-                    }
-                }
-            }
-        }
-    }
-
-    void onPackageAdded(final int uid, @NonNull final String pkgName) {
-        final int userId = UserHandle.getUserId(uid);
-        final PackageInfo packageInfo;
-        try {
-            packageInfo =
-                    mPackageManager.getPackageInfoAsUser(pkgName, PACKAGE_QUERY_FLAGS, userId);
-        } catch (PackageManager.NameNotFoundException e) {
-            Slog.wtf(TAG, "PM couldn't find newly added package: " + pkgName, e);
-            return;
-        }
-        synchronized (mPackageToUidCache) {
-            mPackageToUidCache.add(userId, pkgName, uid);
-        }
-        synchronized (mLock) {
-            final InstalledPackageInfo ipo = new InstalledPackageInfo(getContext(), userId,
-                    packageInfo);
-            final InstalledPackageInfo oldIpo = mPkgCache.add(userId, pkgName, ipo);
-            maybeUpdateInstallerStatusLocked(oldIpo, ipo);
-            mUidToPackageCache.add(uid, pkgName);
-            // TODO: only do this when the user first launches the app (app leaves stopped state)
-            mAgent.grantBirthrightLocked(userId, pkgName);
-            if (ipo.installerPackageName != null) {
-                mAgent.noteInstantaneousEventLocked(userId, ipo.installerPackageName,
-                        JobSchedulerEconomicPolicy.REWARD_APP_INSTALL, null);
-            }
-        }
-    }
-
-    void onPackageForceStopped(final int userId, @NonNull final String pkgName) {
-        synchronized (mLock) {
-            // Remove all credits if the user force stops the app. It will slowly regain them
-            // in response to different events.
-            mAgent.reclaimAllAssetsLocked(userId, pkgName, EconomicPolicy.REGULATION_FORCE_STOP);
-        }
-    }
-
-    void onPackageRemoved(final int uid, @NonNull final String pkgName) {
-        final int userId = UserHandle.getUserId(uid);
-        synchronized (mPackageToUidCache) {
-            mPackageToUidCache.delete(userId, pkgName);
-        }
-        synchronized (mLock) {
-            mUidToPackageCache.remove(uid, pkgName);
-            mVipOverrides.delete(userId, pkgName);
-            final InstalledPackageInfo ipo = mPkgCache.delete(userId, pkgName);
-            mInstallers.delete(userId, pkgName);
-            if (ipo != null && ipo.installerPackageName != null) {
-                final ArraySet<String> list = mInstallers.get(userId, ipo.installerPackageName);
-                if (list != null) {
-                    list.remove(pkgName);
-                }
-            }
-            mAgent.onPackageRemovedLocked(userId, pkgName);
-        }
-    }
-
-    void onUidStateChanged(final int uid) {
-        synchronized (mLock) {
-            final ArraySet<String> pkgNames = getPackagesForUidLocked(uid);
-            if (pkgNames == null) {
-                Slog.e(TAG, "Don't have packages for uid " + uid);
-            } else {
-                mAgent.onAppStatesChangedLocked(UserHandle.getUserId(uid), pkgNames);
-            }
-        }
-    }
-
-    void onUserAdded(final int userId) {
-        synchronized (mLock) {
-            final List<PackageInfo> pkgs =
-                    mPackageManager.getInstalledPackagesAsUser(PACKAGE_QUERY_FLAGS, userId);
-            for (int i = pkgs.size() - 1; i >= 0; --i) {
-                final InstalledPackageInfo ipo =
-                        new InstalledPackageInfo(getContext(), userId, pkgs.get(i));
-                final InstalledPackageInfo oldIpo = mPkgCache.add(userId, ipo.packageName, ipo);
-                maybeUpdateInstallerStatusLocked(oldIpo, ipo);
-            }
-            mAgent.grantBirthrightsLocked(userId);
-            final long nowElapsed = SystemClock.elapsedRealtime();
-            mScribe.setUserAddedTimeLocked(userId, nowElapsed);
-            grantInstallersTemporaryVipStatusLocked(userId,
-                    nowElapsed, INSTALLER_FIRST_SETUP_GRACE_PERIOD_MS);
-        }
-    }
-
-    void onUserRemoved(final int userId) {
-        synchronized (mLock) {
-            mVipOverrides.delete(userId);
-            final int uIdx = mPkgCache.indexOfKey(userId);
-            if (uIdx >= 0) {
-                for (int p = mPkgCache.numElementsForKeyAt(uIdx) - 1; p >= 0; --p) {
-                    final InstalledPackageInfo pkgInfo = mPkgCache.valueAt(uIdx, p);
-                    mUidToPackageCache.remove(pkgInfo.uid);
-                }
-            }
-            mInstallers.delete(userId);
-            mPkgCache.delete(userId);
-            mAgent.onUserRemovedLocked(userId);
-            mScribe.onUserRemovedLocked(userId);
-        }
-    }
-
-    /**
-     * Try to increase the consumption limit if apps are reaching the current limit too quickly.
-     */
-    @GuardedBy("mLock")
-    void maybePerformQuantitativeEasingLocked() {
-        if (mConfigObserver.ENABLE_TIP3) {
-            maybeAdjustDesiredStockLevelLocked();
-            return;
-        }
-        if (getRealtimeSinceFirstSetupMs() < STOCK_ADJUSTMENT_FIRST_SETUP_GRACE_PERIOD_MS) {
-            // Things can be very tumultuous soon after first setup.
-            return;
-        }
-        // We don't need to increase the limit if the device runs out of consumable credits
-        // when the battery is low.
-        final long remainingConsumableCakes = mScribe.getRemainingConsumableCakesLocked();
-        if (mCurrentBatteryLevel <= QUANTITATIVE_EASING_BATTERY_THRESHOLD
-                || remainingConsumableCakes > 0) {
-            return;
-        }
-        final long currentConsumptionLimit = mScribe.getSatiatedConsumptionLimitLocked();
-        final long shortfall = (mCurrentBatteryLevel - QUANTITATIVE_EASING_BATTERY_THRESHOLD)
-                * currentConsumptionLimit / 100;
-        final long newConsumptionLimit = Math.min(currentConsumptionLimit + shortfall,
-                mCompleteEconomicPolicy.getMaxSatiatedConsumptionLimit());
-        if (newConsumptionLimit != currentConsumptionLimit) {
-            Slog.i(TAG, "Increasing consumption limit from " + cakeToString(currentConsumptionLimit)
-                    + " to " + cakeToString(newConsumptionLimit));
-            mScribe.setConsumptionLimitLocked(newConsumptionLimit);
-            adjustCreditSupplyLocked(/* allowIncrease */ true);
-        }
-    }
-
-    /**
-     * Adjust the consumption limit based on historical data and the target battery drain.
-     */
-    @GuardedBy("mLock")
-    void maybeAdjustDesiredStockLevelLocked() {
-        if (!mConfigObserver.ENABLE_TIP3) {
-            return;
-        }
-        if (getRealtimeSinceFirstSetupMs() < STOCK_ADJUSTMENT_FIRST_SETUP_GRACE_PERIOD_MS) {
-            // Things can be very tumultuous soon after first setup.
-            return;
-        }
-        // Don't adjust the limit too often or while the battery is low.
-        final long now = getCurrentTimeMillis();
-        if ((now - mScribe.getLastStockRecalculationTimeLocked()) < STOCK_RECALCULATION_DELAY_MS
-                || mCurrentBatteryLevel <= STOCK_RECALCULATION_BATTERY_THRESHOLD) {
-            return;
-        }
-
-        // For now, use screen off battery drain as a proxy for background battery drain.
-        // TODO: get more accurate background battery drain numbers
-        final long totalScreenOffDurationMs = mAnalyst.getBatteryScreenOffDurationMs();
-        if (totalScreenOffDurationMs < STOCK_RECALCULATION_MIN_DATA_DURATION_MS) {
-            return;
-        }
-        final long totalDischargeMah = mAnalyst.getBatteryScreenOffDischargeMah();
-        if (totalDischargeMah == 0) {
-            Slog.i(TAG, "Total discharge was 0");
-            return;
-        }
-        final long batteryCapacityMah = mBatteryManagerInternal.getBatteryFullCharge() / 1000;
-        final long estimatedLifeHours = batteryCapacityMah * totalScreenOffDurationMs
-                / totalDischargeMah / HOUR_IN_MILLIS;
-        final long percentageOfTarget =
-                100 * estimatedLifeHours / mTargetBackgroundBatteryLifeHours;
-        if (DEBUG) {
-            Slog.d(TAG, "maybeAdjustDesiredStockLevelLocked:"
-                    + " screenOffMs=" + totalScreenOffDurationMs
-                    + " dischargeMah=" + totalDischargeMah
-                    + " capacityMah=" + batteryCapacityMah
-                    + " estimatedLifeHours=" + estimatedLifeHours
-                    + " %ofTarget=" + percentageOfTarget);
-        }
-        final long currentConsumptionLimit = mScribe.getSatiatedConsumptionLimitLocked();
-        final long newConsumptionLimit;
-        if (percentageOfTarget > 105) {
-            // The stock is too low. We're doing pretty well. We can increase the stock slightly
-            // to let apps do more work in the background.
-            newConsumptionLimit = Math.min((long) (currentConsumptionLimit * 1.01),
-                    mCompleteEconomicPolicy.getMaxSatiatedConsumptionLimit());
-        } else if (percentageOfTarget < 100) {
-            // The stock is too high IMO. We're below the target. Decrease the stock to reduce
-            // background work.
-            newConsumptionLimit = Math.max((long) (currentConsumptionLimit * .98),
-                    mCompleteEconomicPolicy.getMinSatiatedConsumptionLimit());
-        } else {
-            // The stock is just right.
-            return;
-        }
-        // TODO(250007191): calculate and log implied service level
-        if (newConsumptionLimit != currentConsumptionLimit) {
-            Slog.i(TAG, "Adjusting consumption limit from " + cakeToString(currentConsumptionLimit)
-                    + " to " + cakeToString(newConsumptionLimit)
-                    + " because drain was " + percentageOfTarget + "% of target");
-            mScribe.setConsumptionLimitLocked(newConsumptionLimit);
-            adjustCreditSupplyLocked(/* allowIncrease */ true);
-            mScribe.setLastStockRecalculationTimeLocked(now);
-        }
-    }
-
-    void postAffordabilityChanged(final int userId, @NonNull final String pkgName,
-            @NonNull Agent.ActionAffordabilityNote affordabilityNote) {
-        if (DEBUG) {
-            Slog.d(TAG, userId + ":" + pkgName + " affordability changed to "
-                    + affordabilityNote.isCurrentlyAffordable());
-        }
-        final SomeArgs args = SomeArgs.obtain();
-        args.argi1 = userId;
-        args.arg1 = pkgName;
-        args.arg2 = affordabilityNote;
-        mHandler.obtainMessage(MSG_NOTIFY_AFFORDABILITY_CHANGE_LISTENER, args).sendToTarget();
-    }
-
-    @GuardedBy("mLock")
-    private void adjustCreditSupplyLocked(boolean allowIncrease) {
-        final long newLimit = getConsumptionLimitLocked();
-        final long remainingConsumableCakes = mScribe.getRemainingConsumableCakesLocked();
-        if (remainingConsumableCakes == newLimit) {
-            return;
-        }
-        if (remainingConsumableCakes > newLimit) {
-            mScribe.adjustRemainingConsumableCakesLocked(newLimit - remainingConsumableCakes);
-        } else if (allowIncrease) {
-            final double perc = mCurrentBatteryLevel / 100d;
-            final long shortfall = newLimit - remainingConsumableCakes;
-            mScribe.adjustRemainingConsumableCakesLocked((long) (perc * shortfall));
-        }
-        mAgent.onCreditSupplyChanged();
-    }
-
-    @GuardedBy("mLock")
-    private void grantInstallersTemporaryVipStatusLocked(int userId, long nowElapsed,
-            long grantDurationMs) {
-        final long grantEndTimeElapsed = nowElapsed + grantDurationMs;
-        final int uIdx = mPkgCache.indexOfKey(userId);
-        if (uIdx < 0) {
-            return;
-        }
-        for (int pIdx = mPkgCache.numElementsForKey(uIdx) - 1; pIdx >= 0; --pIdx) {
-            final InstalledPackageInfo ipo = mPkgCache.valueAt(uIdx, pIdx);
-
-            if (ipo.isSystemInstaller) {
-                final Long currentGrantEndTimeElapsed = mTemporaryVips.get(userId, ipo.packageName);
-                if (currentGrantEndTimeElapsed == null
-                        || currentGrantEndTimeElapsed < grantEndTimeElapsed) {
-                    mTemporaryVips.add(userId, ipo.packageName, grantEndTimeElapsed);
-                }
-            }
-        }
-        mHandler.sendEmptyMessageDelayed(MSG_CLEAN_UP_TEMP_VIP_LIST, grantDurationMs);
-    }
-
-    @GuardedBy("mLock")
-    private void processUsageEventLocked(final int userId, @NonNull UsageEvents.Event event) {
-        if (mEnabledMode == ENABLED_MODE_OFF) {
-            return;
-        }
-        final String pkgName = event.getPackageName();
-        if (DEBUG) {
-            Slog.d(TAG, "Processing event " + event.getEventType()
-                    + " (" + event.mInstanceId + ")"
-                    + " for " + appToString(userId, pkgName));
-        }
-        final long nowElapsed = SystemClock.elapsedRealtime();
-        switch (event.getEventType()) {
-            case UsageEvents.Event.ACTIVITY_RESUMED:
-                mAgent.noteOngoingEventLocked(userId, pkgName,
-                        EconomicPolicy.REWARD_TOP_ACTIVITY, String.valueOf(event.mInstanceId),
-                        nowElapsed);
-                break;
-            case UsageEvents.Event.ACTIVITY_PAUSED:
-            case UsageEvents.Event.ACTIVITY_STOPPED:
-            case UsageEvents.Event.ACTIVITY_DESTROYED:
-                final long now = getCurrentTimeMillis();
-                mAgent.stopOngoingActionLocked(userId, pkgName,
-                        EconomicPolicy.REWARD_TOP_ACTIVITY, String.valueOf(event.mInstanceId),
-                        nowElapsed, now);
-                break;
-            case UsageEvents.Event.USER_INTERACTION:
-            case UsageEvents.Event.CHOOSER_ACTION:
-                mAgent.noteInstantaneousEventLocked(userId, pkgName,
-                        EconomicPolicy.REWARD_OTHER_USER_INTERACTION, null);
-                break;
-            case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
-            case UsageEvents.Event.NOTIFICATION_SEEN:
-                mAgent.noteInstantaneousEventLocked(userId, pkgName,
-                        EconomicPolicy.REWARD_NOTIFICATION_SEEN, null);
-                break;
-        }
-    }
-
-    @GuardedBy("mLock")
-    private void scheduleUnusedWealthReclamationLocked() {
-        final long now = getCurrentTimeMillis();
-        final long nextReclamationTime = Math.max(now + RECLAMATION_STARTUP_DELAY_MS,
-                mScribe.getLastReclamationTimeLocked() + UNUSED_RECLAMATION_PERIOD_MS);
-        mHandler.post(() -> {
-            // Never call out to AlarmManager with the lock held. This sits below AM.
-            AlarmManager alarmManager = getContext().getSystemService(AlarmManager.class);
-            if (alarmManager != null) {
-                alarmManager.setWindow(AlarmManager.ELAPSED_REALTIME,
-                        SystemClock.elapsedRealtime() + (nextReclamationTime - now),
-                        30 * MINUTE_IN_MILLIS,
-                        ALARM_TAG_WEALTH_RECLAMATION, mUnusedWealthReclamationListener, mHandler);
-            } else {
-                mHandler.sendEmptyMessageDelayed(
-                        MSG_SCHEDULE_UNUSED_WEALTH_RECLAMATION_EVENT, RECLAMATION_STARTUP_DELAY_MS);
-            }
-        });
-    }
-
-    private int getCurrentBatteryLevel() {
-        return mBatteryManagerInternal.getBatteryLevel();
-    }
-
-    @Nullable
-    @GuardedBy("mLock")
-    private ArraySet<String> getPackagesForUidLocked(final int uid) {
-        ArraySet<String> packages = mUidToPackageCache.get(uid);
-        if (packages == null) {
-            final String[] pkgs = mPackageManager.getPackagesForUid(uid);
-            if (pkgs != null) {
-                for (String pkg : pkgs) {
-                    mUidToPackageCache.add(uid, pkg);
-                }
-                packages = mUidToPackageCache.get(uid);
-            }
-        }
-        return packages;
-    }
-
-    private boolean isTareSupported() {
-        // TARE is presently designed for devices with batteries. Don't enable it on
-        // battery-less devices for now.
-        return mHasBattery;
-    }
-
-    @GuardedBy("mLock")
-    private void loadInstalledPackageListLocked() {
-        mPkgCache.clear();
-        final int[] userIds = mUserManagerInternal.getUserIds();
-        for (int userId : userIds) {
-            final List<PackageInfo> pkgs =
-                    mPackageManager.getInstalledPackagesAsUser(PACKAGE_QUERY_FLAGS, userId);
-            for (int i = pkgs.size() - 1; i >= 0; --i) {
-                final InstalledPackageInfo ipo =
-                        new InstalledPackageInfo(getContext(), userId, pkgs.get(i));
-                final InstalledPackageInfo oldIpo = mPkgCache.add(userId, ipo.packageName, ipo);
-                maybeUpdateInstallerStatusLocked(oldIpo, ipo);
-            }
-        }
-    }
-
-    /**
-     * Used to update the set of installed apps for each installer. This only has an effect if the
-     * installer package name is different between {@code oldIpo} and {@code newIpo}.
-     */
-    @GuardedBy("mLock")
-    private void maybeUpdateInstallerStatusLocked(@Nullable InstalledPackageInfo oldIpo,
-            @NonNull InstalledPackageInfo newIpo) {
-        final boolean changed;
-        if (oldIpo == null) {
-            changed = newIpo.installerPackageName != null;
-        } else {
-            changed = !Objects.equals(oldIpo.installerPackageName, newIpo.installerPackageName);
-        }
-        if (!changed) {
-            return;
-        }
-        // InstallSourceInfo doesn't track userId, so for now, assume the installer on the package's
-        // user profile did the installation.
-        // TODO(246640162): use the actual installer's user ID
-        final int userId = UserHandle.getUserId(newIpo.uid);
-        final String pkgName = newIpo.packageName;
-        if (oldIpo != null) {
-            final ArraySet<String> oldList = mInstallers.get(userId, oldIpo.installerPackageName);
-            if (oldList != null) {
-                oldList.remove(pkgName);
-            }
-        }
-        if (newIpo.installerPackageName != null) {
-            ArraySet<String> newList = mInstallers.get(userId, newIpo.installerPackageName);
-            if (newList == null) {
-                newList = new ArraySet<>();
-                mInstallers.add(userId, newIpo.installerPackageName, newList);
-            }
-            newList.add(pkgName);
-        }
-    }
-
-    private void registerListeners() {
-        final IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
-        filter.addAction(Intent.ACTION_BATTERY_LEVEL_CHANGED);
-        filter.addAction(PowerManager.ACTION_POWER_SAVE_WHITELIST_CHANGED);
-        getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
-
-        final IntentFilter pkgFilter = new IntentFilter();
-        pkgFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
-        pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
-        pkgFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
-        pkgFilter.addDataScheme("package");
-        getContext()
-                .registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, pkgFilter, null, null);
-
-        final IntentFilter userFilter = new IntentFilter(Intent.ACTION_USER_REMOVED);
-        userFilter.addAction(Intent.ACTION_USER_ADDED);
-        getContext()
-                .registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, userFilter, null, null);
-
-        UsageStatsManagerInternal usmi = LocalServices.getService(UsageStatsManagerInternal.class);
-        usmi.registerListener(mSurveillanceAgent);
-
-        try {
-            mAppOpsService
-                    .startWatchingMode(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, null, mApbListener);
-        } catch (RemoteException e) {
-            // shouldn't happen.
-        }
-    }
-
-    /** Perform long-running and/or heavy setup work. This should be called off the main thread. */
-    private void setupHeavyWork() {
-        if (mBootPhase < PHASE_THIRD_PARTY_APPS_CAN_START || mEnabledMode == ENABLED_MODE_OFF) {
-            return;
-        }
-        synchronized (mLock) {
-            mCompleteEconomicPolicy.setup(mConfigObserver.getAllDeviceConfigProperties());
-            loadInstalledPackageListLocked();
-            final SparseLongArray timeSinceUsersAdded;
-            final boolean isFirstSetup = !mScribe.recordExists();
-            final long nowElapsed = SystemClock.elapsedRealtime();
-            if (isFirstSetup) {
-                mAgent.grantBirthrightsLocked();
-                mScribe.setConsumptionLimitLocked(
-                        mCompleteEconomicPolicy.getInitialSatiatedConsumptionLimit());
-                // Set the last reclamation time to now so we don't start reclaiming assets
-                // too early.
-                mScribe.setLastReclamationTimeLocked(getCurrentTimeMillis());
-                timeSinceUsersAdded = new SparseLongArray();
-            } else {
-                mScribe.loadFromDiskLocked();
-                if (mScribe.getSatiatedConsumptionLimitLocked()
-                        < mCompleteEconomicPolicy.getMinSatiatedConsumptionLimit()
-                        || mScribe.getSatiatedConsumptionLimitLocked()
-                        > mCompleteEconomicPolicy.getMaxSatiatedConsumptionLimit()) {
-                    // Reset the consumption limit since several factors may have changed.
-                    mScribe.setConsumptionLimitLocked(
-                            mCompleteEconomicPolicy.getInitialSatiatedConsumptionLimit());
-                } else {
-                    // Adjust the supply in case battery level changed while the device was off.
-                    adjustCreditSupplyLocked(true);
-                }
-                timeSinceUsersAdded = mScribe.getRealtimeSinceUsersAddedLocked(nowElapsed);
-            }
-
-            final int[] userIds = mUserManagerInternal.getUserIds();
-            for (int userId : userIds) {
-                final long timeSinceUserAddedMs = timeSinceUsersAdded.get(userId, 0);
-                // Temporarily mark installers as VIPs so they aren't subject to credit
-                // limits and policies on first boot.
-                if (timeSinceUserAddedMs < INSTALLER_FIRST_SETUP_GRACE_PERIOD_MS) {
-                    final long remainingGraceDurationMs =
-                            INSTALLER_FIRST_SETUP_GRACE_PERIOD_MS - timeSinceUserAddedMs;
-
-                    grantInstallersTemporaryVipStatusLocked(userId, nowElapsed,
-                            remainingGraceDurationMs);
-                }
-            }
-            scheduleUnusedWealthReclamationLocked();
-        }
-    }
-
-    private void onBootPhaseSystemServicesReady() {
-        if (mBootPhase < PHASE_SYSTEM_SERVICES_READY || mEnabledMode == ENABLED_MODE_OFF) {
-            return;
-        }
-        synchronized (mLock) {
-            registerListeners();
-            // As of Android UDC, users can't change the wellbeing package, so load it once
-            // as soon as possible and don't bother trying to update it afterwards.
-            mWellbeingPackage = mPackageManager.getWellbeingPackageName();
-            mCurrentBatteryLevel = getCurrentBatteryLevel();
-            // Get the current battery presence, if available. This would succeed if TARE is
-            // toggled long after boot.
-            final Intent batteryStatus = getContext().registerReceiver(null,
-                    new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
-            if (batteryStatus != null) {
-                final boolean hasBattery =
-                        batteryStatus.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
-                if (mHasBattery != hasBattery) {
-                    mHasBattery = hasBattery;
-                    mConfigObserver.updateEnabledStatus();
-                }
-            }
-        }
-    }
-
-    private void onBootPhaseThirdPartyAppsCanStart() {
-        if (mBootPhase < PHASE_THIRD_PARTY_APPS_CAN_START || mEnabledMode == ENABLED_MODE_OFF) {
-            return;
-        }
-        mHandler.post(this::setupHeavyWork);
-    }
-
-    private void onBootPhaseBootCompleted() {
-        if (mBootPhase < PHASE_BOOT_COMPLETED || mEnabledMode == ENABLED_MODE_OFF) {
-            return;
-        }
-        synchronized (mLock) {
-            if (!mExemptListLoaded) {
-                try {
-                    mExemptedApps = new ArraySet<>(mDeviceIdleController.getFullPowerWhitelist());
-                    mExemptListLoaded = true;
-                } catch (RemoteException e) {
-                    // Shouldn't happen.
-                }
-            }
-        }
-    }
-
-    private void setupEverything() {
-        if (mEnabledMode == ENABLED_MODE_OFF) {
-            return;
-        }
-        if (mBootPhase >= PHASE_SYSTEM_SERVICES_READY) {
-            onBootPhaseSystemServicesReady();
-        }
-        if (mBootPhase >= PHASE_THIRD_PARTY_APPS_CAN_START) {
-            onBootPhaseThirdPartyAppsCanStart();
-        }
-        if (mBootPhase >= PHASE_BOOT_COMPLETED) {
-            onBootPhaseBootCompleted();
-        }
-    }
-
-    private void tearDownEverything() {
-        if (mEnabledMode != ENABLED_MODE_OFF) {
-            return;
-        }
-        synchronized (mLock) {
-            mAgent.tearDownLocked();
-            mAnalyst.tearDown();
-            mCompleteEconomicPolicy.tearDown();
-            mExemptedApps.clear();
-            mExemptListLoaded = false;
-            mHandler.post(() -> {
-                // Never call out to AlarmManager with the lock held. This sits below AM.
-                AlarmManager alarmManager = getContext().getSystemService(AlarmManager.class);
-                if (alarmManager != null) {
-                    alarmManager.cancel(mUnusedWealthReclamationListener);
-                }
-            });
-            mPkgCache.clear();
-            mScribe.tearDownLocked();
-            mUidToPackageCache.clear();
-            getContext().unregisterReceiver(mBroadcastReceiver);
-            UsageStatsManagerInternal usmi =
-                    LocalServices.getService(UsageStatsManagerInternal.class);
-            usmi.unregisterListener(mSurveillanceAgent);
-            try {
-                mAppOpsService.stopWatchingMode(mApbListener);
-            } catch (RemoteException e) {
-                // shouldn't happen.
-            }
-        }
-        synchronized (mPackageToUidCache) {
-            mPackageToUidCache.clear();
-        }
-    }
-
-    private final class IrsHandler extends Handler {
-        IrsHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_CLEAN_UP_TEMP_VIP_LIST: {
-                    removeMessages(MSG_CLEAN_UP_TEMP_VIP_LIST);
-
-                    synchronized (mLock) {
-                        final long nowElapsed = SystemClock.elapsedRealtime();
-
-                        long earliestExpiration = Long.MAX_VALUE;
-                        for (int u = 0; u < mTemporaryVips.numMaps(); ++u) {
-                            final int userId = mTemporaryVips.keyAt(u);
-
-                            for (int p = mTemporaryVips.numElementsForKeyAt(u) - 1; p >= 0; --p) {
-                                final String pkgName = mTemporaryVips.keyAt(u, p);
-                                final Long expiration = mTemporaryVips.valueAt(u, p);
-
-                                if (expiration == null || expiration < nowElapsed) {
-                                    mTemporaryVips.delete(userId, pkgName);
-                                } else {
-                                    earliestExpiration = Math.min(earliestExpiration, expiration);
-                                }
-                            }
-                        }
-
-                        if (earliestExpiration < Long.MAX_VALUE) {
-                            sendEmptyMessageDelayed(MSG_CLEAN_UP_TEMP_VIP_LIST,
-                                    earliestExpiration - nowElapsed);
-                        }
-                    }
-                }
-                break;
-
-                case MSG_NOTIFY_AFFORDABILITY_CHANGE_LISTENER: {
-                    final SomeArgs args = (SomeArgs) msg.obj;
-                    final int userId = args.argi1;
-                    final String pkgName = (String) args.arg1;
-                    final Agent.ActionAffordabilityNote affordabilityNote =
-                            (Agent.ActionAffordabilityNote) args.arg2;
-
-                    final EconomyManagerInternal.AffordabilityChangeListener listener =
-                            affordabilityNote.getListener();
-                    listener.onAffordabilityChanged(userId, pkgName,
-                            affordabilityNote.getActionBill(),
-                            affordabilityNote.isCurrentlyAffordable());
-
-                    args.recycle();
-                }
-                break;
-
-                case MSG_NOTIFY_STATE_CHANGE_LISTENER: {
-                    final int policy = msg.arg1;
-                    final TareStateChangeListener listener = (TareStateChangeListener) msg.obj;
-                    listener.onTareEnabledModeChanged(getEnabledMode(policy));
-                }
-                break;
-
-                case MSG_NOTIFY_STATE_CHANGE_LISTENERS: {
-                    final int changedPolicies = msg.arg1;
-                    synchronized (mStateChangeListeners) {
-                        final int size = mStateChangeListeners.size();
-                        for (int l = 0; l < size; ++l) {
-                            final int policy = mStateChangeListeners.keyAt(l);
-                            if ((policy & changedPolicies) == 0) {
-                                continue;
-                            }
-                            final ArraySet<TareStateChangeListener> listeners =
-                                    mStateChangeListeners.get(policy);
-                            final int enabledMode = getEnabledMode(policy);
-                            for (int p = listeners.size() - 1; p >= 0; --p) {
-                                final TareStateChangeListener listener = listeners.valueAt(p);
-                                listener.onTareEnabledModeChanged(enabledMode);
-                            }
-                        }
-                    }
-                }
-                break;
-
-                case MSG_PROCESS_USAGE_EVENT: {
-                    final int userId = msg.arg1;
-                    final UsageEvents.Event event = (UsageEvents.Event) msg.obj;
-                    synchronized (mLock) {
-                        processUsageEventLocked(userId, event);
-                    }
-                }
-                break;
-
-                case MSG_SCHEDULE_UNUSED_WEALTH_RECLAMATION_EVENT: {
-                    removeMessages(MSG_SCHEDULE_UNUSED_WEALTH_RECLAMATION_EVENT);
-                    synchronized (mLock) {
-                        scheduleUnusedWealthReclamationLocked();
-                    }
-                }
-                break;
-            }
-        }
-    }
-
-    /**
-     * Binder stub trampoline implementation
-     */
-    final class EconomyManagerStub extends IEconomyManager.Stub {
-        /**
-         * "dumpsys" infrastructure
-         */
-        @Override
-        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-            if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
-
-            boolean dumpAll = true;
-            if (!ArrayUtils.isEmpty(args)) {
-                String arg = args[0];
-                if ("-h".equals(arg) || "--help".equals(arg)) {
-                    dumpHelp(pw);
-                    return;
-                } else if ("-a".equals(arg)) {
-                    // -a is passed when dumping a bug report. Bug reports have a time limit for
-                    // each service dump, so we can't dump everything.
-                    dumpAll = false;
-                } else if (arg.length() > 0 && arg.charAt(0) == '-') {
-                    pw.println("Unknown option: " + arg);
-                    return;
-                }
-            }
-
-            final long identityToken = Binder.clearCallingIdentity();
-            try {
-                dumpInternal(new IndentingPrintWriter(pw, "  "), dumpAll);
-            } finally {
-                Binder.restoreCallingIdentity(identityToken);
-            }
-        }
-
-        @Override
-        @EconomyManager.EnabledMode
-        public int getEnabledMode() {
-            return InternalResourceService.this.getEnabledMode();
-        }
-
-        @Override
-        public int handleShellCommand(@NonNull ParcelFileDescriptor in,
-                @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
-                @NonNull String[] args) {
-            return (new TareShellCommand(InternalResourceService.this)).exec(
-                    this, in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(),
-                    args);
-        }
-    }
-
-    private final class LocalService implements EconomyManagerInternal {
-        /**
-         * Use an extremely large value to indicate that an app can pay for a bill indefinitely.
-         * The value set here should be large/long enough that there's no reasonable expectation
-         * of a device operating uninterrupted (or in the exact same state) for that period of time.
-         * We intentionally don't use Long.MAX_VALUE to avoid potential overflow if a client
-         * doesn't check the value and just immediately adds it to the current time.
-         */
-        private static final long FOREVER_MS = 27 * 365 * 24 * HOUR_IN_MILLIS;
-
-        @Override
-        public void registerAffordabilityChangeListener(int userId, @NonNull String pkgName,
-                @NonNull AffordabilityChangeListener listener, @NonNull ActionBill bill) {
-            if (!isTareSupported() || isSystem(userId, pkgName)) {
-                // The system's affordability never changes.
-                return;
-            }
-            synchronized (mLock) {
-                mAgent.registerAffordabilityChangeListenerLocked(userId, pkgName, listener, bill);
-            }
-        }
-
-        @Override
-        public void unregisterAffordabilityChangeListener(int userId, @NonNull String pkgName,
-                @NonNull AffordabilityChangeListener listener, @NonNull ActionBill bill) {
-            if (isSystem(userId, pkgName)) {
-                // The system's affordability never changes.
-                return;
-            }
-            synchronized (mLock) {
-                mAgent.unregisterAffordabilityChangeListenerLocked(userId, pkgName, listener, bill);
-            }
-        }
-
-        @Override
-        public void registerTareStateChangeListener(@NonNull TareStateChangeListener listener,
-                int policyId) {
-            if (!isTareSupported()) {
-                return;
-            }
-            synchronized (mStateChangeListeners) {
-                if (mStateChangeListeners.add(policyId, listener)) {
-                    mHandler.obtainMessage(MSG_NOTIFY_STATE_CHANGE_LISTENER, policyId, 0, listener)
-                            .sendToTarget();
-                }
-            }
-        }
-
-        @Override
-        public void unregisterTareStateChangeListener(@NonNull TareStateChangeListener listener) {
-            synchronized (mStateChangeListeners) {
-                for (int i = mStateChangeListeners.size() - 1; i >= 0; --i) {
-                    final ArraySet<TareStateChangeListener> listeners =
-                            mStateChangeListeners.get(mStateChangeListeners.keyAt(i));
-                    listeners.remove(listener);
-                }
-            }
-        }
-
-        @Override
-        public boolean canPayFor(int userId, @NonNull String pkgName, @NonNull ActionBill bill) {
-            if (mEnabledMode == ENABLED_MODE_OFF) {
-                return true;
-            }
-            if (isVip(userId, pkgName)) {
-                // The government, I mean the system, can create ARCs as it needs to in order to
-                // allow VIPs to operate.
-                return true;
-            }
-            // TODO: take temp-allowlist into consideration
-            long requiredBalance = 0;
-            final List<EconomyManagerInternal.AnticipatedAction> projectedActions =
-                    bill.getAnticipatedActions();
-            synchronized (mLock) {
-                for (int i = 0; i < projectedActions.size(); ++i) {
-                    AnticipatedAction action = projectedActions.get(i);
-                    final Cost cost = mCompleteEconomicPolicy.getCostOfAction(
-                            action.actionId, userId, pkgName);
-                    requiredBalance += cost.price * action.numInstantaneousCalls
-                            + cost.price * (action.ongoingDurationMs / 1000);
-                }
-                return mAgent.getBalanceLocked(userId, pkgName) >= requiredBalance
-                        && mScribe.getRemainingConsumableCakesLocked() >= requiredBalance;
-            }
-        }
-
-        @Override
-        public long getMaxDurationMs(int userId, @NonNull String pkgName,
-                @NonNull ActionBill bill) {
-            if (mEnabledMode == ENABLED_MODE_OFF) {
-                return FOREVER_MS;
-            }
-            if (isVip(userId, pkgName)) {
-                return FOREVER_MS;
-            }
-            long totalCostPerSecond = 0;
-            final List<EconomyManagerInternal.AnticipatedAction> projectedActions =
-                    bill.getAnticipatedActions();
-            synchronized (mLock) {
-                for (int i = 0; i < projectedActions.size(); ++i) {
-                    AnticipatedAction action = projectedActions.get(i);
-                    final Cost cost = mCompleteEconomicPolicy.getCostOfAction(
-                            action.actionId, userId, pkgName);
-                    totalCostPerSecond += cost.price;
-                }
-                if (totalCostPerSecond == 0) {
-                    return FOREVER_MS;
-                }
-                final long minBalance = Math.min(
-                        mAgent.getBalanceLocked(userId, pkgName),
-                        mScribe.getRemainingConsumableCakesLocked());
-                return minBalance * 1000 / totalCostPerSecond;
-            }
-        }
-
-        @Override
-        public int getEnabledMode() {
-            return mEnabledMode;
-        }
-
-        @Override
-        public int getEnabledMode(int policyId) {
-            return InternalResourceService.this.getEnabledMode(policyId);
-        }
-
-        @Override
-        public void noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId,
-                @Nullable String tag) {
-            if (mEnabledMode == ENABLED_MODE_OFF) {
-                return;
-            }
-            synchronized (mLock) {
-                mAgent.noteInstantaneousEventLocked(userId, pkgName, eventId, tag);
-            }
-        }
-
-        @Override
-        public void noteOngoingEventStarted(int userId, @NonNull String pkgName, int eventId,
-                @Nullable String tag) {
-            if (mEnabledMode == ENABLED_MODE_OFF) {
-                return;
-            }
-            synchronized (mLock) {
-                final long nowElapsed = SystemClock.elapsedRealtime();
-                mAgent.noteOngoingEventLocked(userId, pkgName, eventId, tag, nowElapsed);
-            }
-        }
-
-        @Override
-        public void noteOngoingEventStopped(int userId, @NonNull String pkgName, int eventId,
-                @Nullable String tag) {
-            if (mEnabledMode == ENABLED_MODE_OFF) {
-                return;
-            }
-            final long nowElapsed = SystemClock.elapsedRealtime();
-            final long now = getCurrentTimeMillis();
-            synchronized (mLock) {
-                mAgent.stopOngoingActionLocked(userId, pkgName, eventId, tag, nowElapsed, now);
-            }
-        }
-    }
-
-    private class ConfigObserver extends ContentObserver
-            implements DeviceConfig.OnPropertiesChangedListener {
-        private static final String KEY_ENABLE_TIP3 = "enable_tip3";
-        private static final String KEY_TARGET_BACKGROUND_BATTERY_LIFE_HOURS =
-                "target_bg_battery_life_hrs";
-
-        private static final boolean DEFAULT_ENABLE_TIP3 = true;
-
-        /** Use a target background battery drain rate to determine consumption limits. */
-        public boolean ENABLE_TIP3 = DEFAULT_ENABLE_TIP3;
-
-        private final ContentResolver mContentResolver;
-
-        ConfigObserver(Handler handler, Context context) {
-            super(handler);
-            mContentResolver = context.getContentResolver();
-        }
-
-        public void start() {
-            DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_TARE,
-                    TareHandlerThread.getExecutor(), this);
-            mContentResolver.registerContentObserver(
-                    Settings.Global.getUriFor(Settings.Global.ENABLE_TARE), false, this);
-            mContentResolver.registerContentObserver(
-                    Settings.Global.getUriFor(TARE_ALARM_MANAGER_CONSTANTS), false, this);
-            mContentResolver.registerContentObserver(
-                    Settings.Global.getUriFor(TARE_JOB_SCHEDULER_CONSTANTS), false, this);
-            onPropertiesChanged(getAllDeviceConfigProperties());
-            updateEnabledStatus();
-        }
-
-        @NonNull
-        DeviceConfig.Properties getAllDeviceConfigProperties() {
-            // Don't want to cache the Properties object locally in case it ends up being large,
-            // especially since it'll only be used once/infrequently (during setup or on a change).
-            return DeviceConfig.getProperties(DeviceConfig.NAMESPACE_TARE);
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            if (uri.equals(Settings.Global.getUriFor(Settings.Global.ENABLE_TARE))) {
-                updateEnabledStatus();
-            } else if (uri.equals(Settings.Global.getUriFor(TARE_ALARM_MANAGER_CONSTANTS))
-                    || uri.equals(Settings.Global.getUriFor(TARE_JOB_SCHEDULER_CONSTANTS))) {
-                updateEconomicPolicy();
-            }
-        }
-
-        @Override
-        public void onPropertiesChanged(DeviceConfig.Properties properties) {
-            boolean economicPolicyUpdated = false;
-            synchronized (mLock) {
-                for (String name : properties.getKeyset()) {
-                    if (name == null) {
-                        continue;
-                    }
-                    switch (name) {
-                        case EconomyManager.KEY_ENABLE_TARE_MODE:
-                            updateEnabledStatus();
-                            break;
-                        case KEY_ENABLE_TIP3:
-                            ENABLE_TIP3 = properties.getBoolean(name, DEFAULT_ENABLE_TIP3);
-                            break;
-                        case KEY_TARGET_BACKGROUND_BATTERY_LIFE_HOURS:
-                            synchronized (mLock) {
-                                mTargetBackgroundBatteryLifeHours = properties.getInt(name,
-                                        mDefaultTargetBackgroundBatteryLifeHours);
-                                maybeAdjustDesiredStockLevelLocked();
-                            }
-                            break;
-                        default:
-                            if (!economicPolicyUpdated
-                                    && (name.startsWith("am") || name.startsWith("js")
-                                    || name.startsWith("enable_policy"))) {
-                                updateEconomicPolicy();
-                                economicPolicyUpdated = true;
-                            }
-                    }
-                }
-            }
-        }
-
-        private void updateEnabledStatus() {
-            // User setting should override DeviceConfig setting.
-            final int tareEnabledModeDC = DeviceConfig.getInt(DeviceConfig.NAMESPACE_TARE,
-                    EconomyManager.KEY_ENABLE_TARE_MODE, EconomyManager.DEFAULT_ENABLE_TARE_MODE);
-            final int tareEnabledModeConfig = isTareSupported()
-                    ? Settings.Global.getInt(mContentResolver,
-                            Settings.Global.ENABLE_TARE, tareEnabledModeDC)
-                    : ENABLED_MODE_OFF;
-            final int enabledMode;
-            if (tareEnabledModeConfig == ENABLED_MODE_OFF
-                    || tareEnabledModeConfig == ENABLED_MODE_ON
-                    || tareEnabledModeConfig == ENABLED_MODE_SHADOW) {
-                // Config has a valid enabled mode.
-                enabledMode = tareEnabledModeConfig;
-            } else {
-                enabledMode = EconomyManager.DEFAULT_ENABLE_TARE_MODE;
-            }
-            if (mEnabledMode != enabledMode) {
-                // A full change where we've gone from OFF to {SHADOW or ON}, or vie versa.
-                // With this transition, we'll have to set up or tear down.
-                final boolean fullEnableChange =
-                        mEnabledMode == ENABLED_MODE_OFF || enabledMode == ENABLED_MODE_OFF;
-                mEnabledMode = enabledMode;
-                if (fullEnableChange) {
-                    if (mEnabledMode != ENABLED_MODE_OFF) {
-                        setupEverything();
-                    } else {
-                        tearDownEverything();
-                    }
-                }
-                mHandler.obtainMessage(
-                                MSG_NOTIFY_STATE_CHANGE_LISTENERS, EconomicPolicy.ALL_POLICIES, 0)
-                        .sendToTarget();
-            }
-        }
-
-        private void updateEconomicPolicy() {
-            synchronized (mLock) {
-                final long minLimit = mCompleteEconomicPolicy.getMinSatiatedConsumptionLimit();
-                final long maxLimit = mCompleteEconomicPolicy.getMaxSatiatedConsumptionLimit();
-                final int oldEnabledPolicies = mCompleteEconomicPolicy.getEnabledPolicyIds();
-                mCompleteEconomicPolicy.tearDown();
-                mCompleteEconomicPolicy = new CompleteEconomicPolicy(InternalResourceService.this);
-                if (mEnabledMode != ENABLED_MODE_OFF
-                        && mBootPhase >= PHASE_THIRD_PARTY_APPS_CAN_START) {
-                    mCompleteEconomicPolicy.setup(getAllDeviceConfigProperties());
-                    if (minLimit != mCompleteEconomicPolicy.getMinSatiatedConsumptionLimit()
-                            || maxLimit
-                            != mCompleteEconomicPolicy.getMaxSatiatedConsumptionLimit()) {
-                        // Reset the consumption limit since several factors may have changed.
-                        mScribe.setConsumptionLimitLocked(
-                                mCompleteEconomicPolicy.getInitialSatiatedConsumptionLimit());
-                    }
-                    mAgent.onPricingChangedLocked();
-                    final int newEnabledPolicies = mCompleteEconomicPolicy.getEnabledPolicyIds();
-                    if (oldEnabledPolicies != newEnabledPolicies) {
-                        final int changedPolicies = oldEnabledPolicies ^ newEnabledPolicies;
-                        mHandler.obtainMessage(
-                                        MSG_NOTIFY_STATE_CHANGE_LISTENERS, changedPolicies, 0)
-                                .sendToTarget();
-                    }
-                }
-            }
-        }
-    }
-
-    // Shell command infrastructure
-    int executeClearVip(@NonNull PrintWriter pw) {
-        synchronized (mLock) {
-            final SparseSetArray<String> changedPkgs = new SparseSetArray<>();
-            for (int u = mVipOverrides.numMaps() - 1; u >= 0; --u) {
-                final int userId = mVipOverrides.keyAt(u);
-
-                for (int p = mVipOverrides.numElementsForKeyAt(u) - 1; p >= 0; --p) {
-                    changedPkgs.add(userId, mVipOverrides.keyAt(u, p));
-                }
-            }
-            mVipOverrides.clear();
-            if (mEnabledMode != ENABLED_MODE_OFF) {
-                mAgent.onVipStatusChangedLocked(changedPkgs);
-            }
-        }
-        pw.println("Cleared all VIP statuses");
-        return TareShellCommand.COMMAND_SUCCESS;
-    }
-
-    int executeSetVip(@NonNull PrintWriter pw,
-            int userId, @NonNull String pkgName, @Nullable Boolean newVipState) {
-        final boolean changed;
-        synchronized (mLock) {
-            final boolean wasVip = isVip(userId, pkgName);
-            if (newVipState == null) {
-                mVipOverrides.delete(userId, pkgName);
-            } else {
-                mVipOverrides.add(userId, pkgName, newVipState);
-            }
-            changed = isVip(userId, pkgName) != wasVip;
-            if (mEnabledMode != ENABLED_MODE_OFF && changed) {
-                mAgent.onVipStatusChangedLocked(userId, pkgName);
-            }
-        }
-        pw.println(appToString(userId, pkgName) + " VIP status set to " + newVipState + "."
-                + " Final VIP state changed? " + changed);
-        return TareShellCommand.COMMAND_SUCCESS;
-    }
-
-    // Dump infrastructure
-    private static void dumpHelp(PrintWriter pw) {
-        pw.println("Resource Economy (economy) dump options:");
-        pw.println("  [-h|--help] [package] ...");
-        pw.println("    -h | --help: print this help");
-        pw.println("  [package] is an optional package name to limit the output to.");
-    }
-
-    private void dumpInternal(final IndentingPrintWriter pw, final boolean dumpAll) {
-        if (!isTareSupported()) {
-            pw.print("Unsupported by device");
-            return;
-        }
-        synchronized (mLock) {
-            pw.print("Enabled mode: ");
-            pw.println(enabledModeToString(mEnabledMode));
-
-            pw.print("Current battery level: ");
-            pw.println(mCurrentBatteryLevel);
-
-            final long consumptionLimit = getConsumptionLimitLocked();
-            pw.print("Consumption limit (current/initial-satiated/current-satiated): ");
-            pw.print(cakeToString(consumptionLimit));
-            pw.print("/");
-            pw.print(cakeToString(mCompleteEconomicPolicy.getInitialSatiatedConsumptionLimit()));
-            pw.print("/");
-            pw.println(cakeToString(mScribe.getSatiatedConsumptionLimitLocked()));
-
-            pw.print("Target bg battery life (hours): ");
-            pw.print(mTargetBackgroundBatteryLifeHours);
-            pw.print(" (");
-            pw.print(String.format("%.2f", 100f / mTargetBackgroundBatteryLifeHours));
-            pw.println("%/hr)");
-
-            final long remainingConsumable = mScribe.getRemainingConsumableCakesLocked();
-            pw.print("Goods remaining: ");
-            pw.print(cakeToString(remainingConsumable));
-            pw.print(" (");
-            pw.print(String.format("%.2f", 100f * remainingConsumable / consumptionLimit));
-            pw.println("% of current limit)");
-
-            pw.print("Device wealth: ");
-            pw.println(cakeToString(mScribe.getCakesInCirculationForLoggingLocked()));
-
-            pw.println();
-            pw.print("Exempted apps", mExemptedApps);
-            pw.println();
-
-            pw.println();
-            pw.print("Wellbeing app=");
-            pw.println(mWellbeingPackage == null ? "None" : mWellbeingPackage);
-
-            boolean printedVips = false;
-            pw.println();
-            pw.print("VIPs:");
-            pw.increaseIndent();
-            for (int u = 0; u < mVipOverrides.numMaps(); ++u) {
-                final int userId = mVipOverrides.keyAt(u);
-
-                for (int p = 0; p < mVipOverrides.numElementsForKeyAt(u); ++p) {
-                    final String pkgName = mVipOverrides.keyAt(u, p);
-
-                    printedVips = true;
-                    pw.println();
-                    pw.print(appToString(userId, pkgName));
-                    pw.print("=");
-                    pw.print(mVipOverrides.valueAt(u, p));
-                }
-            }
-            if (printedVips) {
-                pw.println();
-            } else {
-                pw.print(" None");
-            }
-            pw.decreaseIndent();
-            pw.println();
-
-            boolean printedTempVips = false;
-            pw.println();
-            pw.print("Temp VIPs:");
-            pw.increaseIndent();
-            for (int u = 0; u < mTemporaryVips.numMaps(); ++u) {
-                final int userId = mTemporaryVips.keyAt(u);
-
-                for (int p = 0; p < mTemporaryVips.numElementsForKeyAt(u); ++p) {
-                    final String pkgName = mTemporaryVips.keyAt(u, p);
-
-                    printedTempVips = true;
-                    pw.println();
-                    pw.print(appToString(userId, pkgName));
-                    pw.print("=");
-                    pw.print(mTemporaryVips.valueAt(u, p));
-                }
-            }
-            if (printedTempVips) {
-                pw.println();
-            } else {
-                pw.print(" None");
-            }
-            pw.decreaseIndent();
-            pw.println();
-
-            pw.println();
-            pw.println("Installers:");
-            pw.increaseIndent();
-            for (int u = 0; u < mInstallers.numMaps(); ++u) {
-                final int userId = mInstallers.keyAt(u);
-
-                for (int p = 0; p < mInstallers.numElementsForKeyAt(u); ++p) {
-                    final String pkgName = mInstallers.keyAt(u, p);
-
-                    pw.print(appToString(userId, pkgName));
-                    pw.print(": ");
-                    pw.print(mInstallers.valueAt(u, p).size());
-                    pw.println(" apps");
-                }
-            }
-            pw.decreaseIndent();
-
-            pw.println();
-            mCompleteEconomicPolicy.dump(pw);
-
-            pw.println();
-            mScribe.dumpLocked(pw, dumpAll);
-
-            pw.println();
-            mAgent.dumpLocked(pw);
-
-            pw.println();
-            mAnalyst.dump(pw);
-
-            // Put this at the end since this may be a lot and we want to have the earlier
-            // information easily accessible.
-            boolean printedInterestingIpos = false;
-            pw.println();
-            pw.print("Interesting apps:");
-            pw.increaseIndent();
-            for (int u = 0; u < mPkgCache.numMaps(); ++u) {
-                for (int p = 0; p < mPkgCache.numElementsForKeyAt(u); ++p) {
-                    final InstalledPackageInfo ipo = mPkgCache.valueAt(u, p);
-
-                    // Printing out every single app will be too much. Only print apps that
-                    // have some interesting characteristic.
-                    final boolean isInteresting = ipo.hasCode
-                            && ipo.isHeadlessSystemApp
-                            && !UserHandle.isCore(ipo.uid);
-                    if (!isInteresting) {
-                        continue;
-                    }
-
-                    printedInterestingIpos = true;
-                    pw.println();
-                    pw.print(ipo);
-                }
-            }
-            if (printedInterestingIpos) {
-                pw.println();
-            } else {
-                pw.print(" None");
-            }
-            pw.decreaseIndent();
-            pw.println();
-        }
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
deleted file mode 100644
index 69e5736..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_MAX_CONSUMPTION_LIMIT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_CONSUMPTION_LIMIT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_INSTANT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_MAX_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_APP_INSTALL_ONGOING_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES;
-import static android.app.tare.EconomyManager.DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_DEFAULT_START_CTP;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_HIGH_START_CTP;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_RUNNING_CTP;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_LOW_START_CTP;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_RUNNING_CTP;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MAX_START_CTP;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_RUNNING_CTP;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_MIN_START_CTP;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE;
-import static android.app.tare.EconomyManager.KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP;
-import static android.app.tare.EconomyManager.KEY_JS_INITIAL_CONSUMPTION_LIMIT;
-import static android.app.tare.EconomyManager.KEY_JS_MAX_CONSUMPTION_LIMIT;
-import static android.app.tare.EconomyManager.KEY_JS_MAX_SATIATED_BALANCE;
-import static android.app.tare.EconomyManager.KEY_JS_MIN_CONSUMPTION_LIMIT;
-import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED;
-import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP;
-import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER;
-import static android.app.tare.EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_APP_INSTALL_INSTANT;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_APP_INSTALL_MAX;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_APP_INSTALL_ONGOING;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_MAX;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_INSTANT;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_MAX;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_TOP_ACTIVITY_ONGOING;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_MAX;
-import static android.app.tare.EconomyManager.KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING;
-import static android.app.tare.EconomyManager.arcToCake;
-import static android.provider.Settings.Global.TARE_JOB_SCHEDULER_CONSTANTS;
-
-import static com.android.server.tare.Modifier.COST_MODIFIER_CHARGING;
-import static com.android.server.tare.Modifier.COST_MODIFIER_DEVICE_IDLE;
-import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE;
-import static com.android.server.tare.Modifier.COST_MODIFIER_PROCESS_STATE;
-import static com.android.server.tare.TareUtils.appToString;
-import static com.android.server.tare.TareUtils.cakeToString;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.provider.DeviceConfig;
-import android.util.IndentingPrintWriter;
-import android.util.Slog;
-import android.util.SparseArray;
-
-/**
- * Policy defining pricing information and daily ARC requirements and suggestions for
- * JobScheduler.
- */
-public class JobSchedulerEconomicPolicy extends EconomicPolicy {
-    private static final String TAG = "TARE- " + JobSchedulerEconomicPolicy.class.getSimpleName();
-
-    public static final int ACTION_JOB_MAX_START = TYPE_ACTION | POLICY_JOB | 0;
-    public static final int ACTION_JOB_MAX_RUNNING = TYPE_ACTION | POLICY_JOB | 1;
-    public static final int ACTION_JOB_HIGH_START = TYPE_ACTION | POLICY_JOB | 2;
-    public static final int ACTION_JOB_HIGH_RUNNING = TYPE_ACTION | POLICY_JOB | 3;
-    public static final int ACTION_JOB_DEFAULT_START = TYPE_ACTION | POLICY_JOB | 4;
-    public static final int ACTION_JOB_DEFAULT_RUNNING = TYPE_ACTION | POLICY_JOB | 5;
-    public static final int ACTION_JOB_LOW_START = TYPE_ACTION | POLICY_JOB | 6;
-    public static final int ACTION_JOB_LOW_RUNNING = TYPE_ACTION | POLICY_JOB | 7;
-    public static final int ACTION_JOB_MIN_START = TYPE_ACTION | POLICY_JOB | 8;
-    public static final int ACTION_JOB_MIN_RUNNING = TYPE_ACTION | POLICY_JOB | 9;
-    public static final int ACTION_JOB_TIMEOUT = TYPE_ACTION | POLICY_JOB | 10;
-
-    public static final int REWARD_APP_INSTALL = TYPE_REWARD | POLICY_JOB | 0;
-
-    private static final int[] COST_MODIFIERS = new int[]{
-            COST_MODIFIER_CHARGING,
-            COST_MODIFIER_DEVICE_IDLE,
-            COST_MODIFIER_POWER_SAVE_MODE,
-            COST_MODIFIER_PROCESS_STATE
-    };
-
-    private long mMinSatiatedBalanceExempted;
-    private long mMinSatiatedBalanceHeadlessSystemApp;
-    private long mMinSatiatedBalanceOther;
-    private long mMinSatiatedBalanceIncrementalAppUpdater;
-    private long mMaxSatiatedBalance;
-    private long mInitialSatiatedConsumptionLimit;
-    private long mMinSatiatedConsumptionLimit;
-    private long mMaxSatiatedConsumptionLimit;
-
-    private final Injector mInjector;
-
-    private final SparseArray<Action> mActions = new SparseArray<>();
-    private final SparseArray<Reward> mRewards = new SparseArray<>();
-
-    JobSchedulerEconomicPolicy(InternalResourceService irs, Injector injector) {
-        super(irs);
-        mInjector = injector;
-        loadConstants("", null);
-    }
-
-    @Override
-    void setup(@NonNull DeviceConfig.Properties properties) {
-        super.setup(properties);
-        final ContentResolver resolver = mIrs.getContext().getContentResolver();
-        loadConstants(mInjector.getSettingsGlobalString(resolver, TARE_JOB_SCHEDULER_CONSTANTS),
-                properties);
-    }
-
-    @Override
-    long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) {
-        if (mIrs.isPackageRestricted(userId, pkgName)) {
-            return 0;
-        }
-
-        final long baseBalance;
-        if (mIrs.isPackageExempted(userId, pkgName)) {
-            baseBalance = mMinSatiatedBalanceExempted;
-        } else if (mIrs.isHeadlessSystemApp(userId, pkgName)) {
-            baseBalance = mMinSatiatedBalanceHeadlessSystemApp;
-        } else {
-            baseBalance = mMinSatiatedBalanceOther;
-        }
-
-        long minBalance = baseBalance;
-
-        final int updateResponsibilityCount = mIrs.getAppUpdateResponsibilityCount(userId, pkgName);
-        minBalance += updateResponsibilityCount * mMinSatiatedBalanceIncrementalAppUpdater;
-
-        return Math.min(minBalance, mMaxSatiatedBalance);
-    }
-
-    @Override
-    long getMaxSatiatedBalance(int userId, @NonNull String pkgName) {
-        if (mIrs.isPackageRestricted(userId, pkgName)) {
-            return 0;
-        }
-        final InstalledPackageInfo ipo = mIrs.getInstalledPackageInfo(userId, pkgName);
-        if (ipo == null) {
-            Slog.wtfStack(TAG,
-                    "Tried to get max balance of invalid app: " + appToString(userId, pkgName));
-        } else {
-            // A system installer's max balance is elevated for some time after first boot so
-            // they can use jobs to download and install apps.
-            if (ipo.isSystemInstaller) {
-                final long timeSinceFirstSetupMs = mIrs.getRealtimeSinceFirstSetupMs();
-                final boolean stillExempted = timeSinceFirstSetupMs
-                        < InternalResourceService.INSTALLER_FIRST_SETUP_GRACE_PERIOD_MS;
-                if (stillExempted) {
-                    return mMaxSatiatedConsumptionLimit;
-                }
-            }
-        }
-        return mMaxSatiatedBalance;
-    }
-
-    @Override
-    long getInitialSatiatedConsumptionLimit() {
-        return mInitialSatiatedConsumptionLimit;
-    }
-
-    @Override
-    long getMinSatiatedConsumptionLimit() {
-        return mMinSatiatedConsumptionLimit;
-    }
-
-    @Override
-    long getMaxSatiatedConsumptionLimit() {
-        return mMaxSatiatedConsumptionLimit;
-    }
-
-    @NonNull
-    @Override
-    int[] getCostModifiers() {
-        return COST_MODIFIERS;
-    }
-
-    @Nullable
-    @Override
-    Action getAction(@AppAction int actionId) {
-        return mActions.get(actionId);
-    }
-
-    @Nullable
-    @Override
-    Reward getReward(@UtilityReward int rewardId) {
-        return mRewards.get(rewardId);
-    }
-
-    private void loadConstants(String policyValuesString,
-            @Nullable DeviceConfig.Properties properties) {
-        mActions.clear();
-        mRewards.clear();
-
-        try {
-            mUserSettingDeviceConfigMediator.setSettingsString(policyValuesString);
-            mUserSettingDeviceConfigMediator.setDeviceConfigProperties(properties);
-        } catch (IllegalArgumentException e) {
-            Slog.e(TAG, "Global setting key incorrect: ", e);
-        }
-
-        mMinSatiatedBalanceOther = getConstantAsCake(
-            KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES);
-        mMinSatiatedBalanceHeadlessSystemApp = getConstantAsCake(
-                KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
-                DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
-                mMinSatiatedBalanceOther);
-        mMinSatiatedBalanceExempted = getConstantAsCake(
-                KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED,
-                DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
-                mMinSatiatedBalanceHeadlessSystemApp);
-        mMinSatiatedBalanceIncrementalAppUpdater = getConstantAsCake(
-                KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER,
-                DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES);
-        mMaxSatiatedBalance = getConstantAsCake(
-            KEY_JS_MAX_SATIATED_BALANCE, DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
-            Math.max(arcToCake(1), mMinSatiatedBalanceExempted));
-        mMinSatiatedConsumptionLimit = getConstantAsCake(
-                KEY_JS_MIN_CONSUMPTION_LIMIT, DEFAULT_JS_MIN_CONSUMPTION_LIMIT_CAKES,
-                arcToCake(1));
-        mInitialSatiatedConsumptionLimit = getConstantAsCake(
-                KEY_JS_INITIAL_CONSUMPTION_LIMIT, DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES,
-                mMinSatiatedConsumptionLimit);
-        mMaxSatiatedConsumptionLimit = getConstantAsCake(
-                KEY_JS_MAX_CONSUMPTION_LIMIT, DEFAULT_JS_MAX_CONSUMPTION_LIMIT_CAKES,
-                mInitialSatiatedConsumptionLimit);
-
-        mActions.put(ACTION_JOB_MAX_START, new Action(ACTION_JOB_MAX_START,
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_MAX_START_CTP,
-                        DEFAULT_JS_ACTION_JOB_MAX_START_CTP_CAKES),
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE_CAKES)));
-        mActions.put(ACTION_JOB_MAX_RUNNING, new Action(ACTION_JOB_MAX_RUNNING,
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_MAX_RUNNING_CTP,
-                        DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP_CAKES),
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE_CAKES)));
-        mActions.put(ACTION_JOB_HIGH_START, new Action(ACTION_JOB_HIGH_START,
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_HIGH_START_CTP,
-                        DEFAULT_JS_ACTION_JOB_HIGH_START_CTP_CAKES),
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE_CAKES)));
-        mActions.put(ACTION_JOB_HIGH_RUNNING, new Action(ACTION_JOB_HIGH_RUNNING,
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP,
-                        DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP_CAKES),
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE_CAKES)));
-        mActions.put(ACTION_JOB_DEFAULT_START, new Action(ACTION_JOB_DEFAULT_START,
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_DEFAULT_START_CTP,
-                        DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP_CAKES),
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE_CAKES)));
-        mActions.put(ACTION_JOB_DEFAULT_RUNNING, new Action(ACTION_JOB_DEFAULT_RUNNING,
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP,
-                        DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP_CAKES),
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE_CAKES)));
-        mActions.put(ACTION_JOB_LOW_START, new Action(ACTION_JOB_LOW_START,
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_LOW_START_CTP,
-                        DEFAULT_JS_ACTION_JOB_LOW_START_CTP_CAKES),
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE_CAKES)));
-        mActions.put(ACTION_JOB_LOW_RUNNING, new Action(ACTION_JOB_LOW_RUNNING,
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_LOW_RUNNING_CTP,
-                        DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP_CAKES),
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE_CAKES)));
-        mActions.put(ACTION_JOB_MIN_START, new Action(ACTION_JOB_MIN_START,
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_MIN_START_CTP,
-                        DEFAULT_JS_ACTION_JOB_MIN_START_CTP_CAKES),
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE_CAKES)));
-        mActions.put(ACTION_JOB_MIN_RUNNING, new Action(ACTION_JOB_MIN_RUNNING,
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_MIN_RUNNING_CTP,
-                        DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP_CAKES),
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE_CAKES)));
-        mActions.put(ACTION_JOB_TIMEOUT, new Action(ACTION_JOB_TIMEOUT,
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP,
-                        DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP_CAKES),
-                getConstantAsCake(
-                        KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE,
-                        DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE_CAKES)));
-
-        mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY,
-                getConstantAsCake(
-                        KEY_JS_REWARD_TOP_ACTIVITY_INSTANT,
-                        DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT_CAKES),
-                getConstantAsCake(
-                        KEY_JS_REWARD_TOP_ACTIVITY_ONGOING,
-                        DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING_CAKES),
-                getConstantAsCake(
-                        KEY_JS_REWARD_TOP_ACTIVITY_MAX,
-                        DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX_CAKES)));
-        mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN,
-                getConstantAsCake(
-                        KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT,
-                        DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT_CAKES),
-                getConstantAsCake(
-                        KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING,
-                        DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING_CAKES),
-                getConstantAsCake(
-                        KEY_JS_REWARD_NOTIFICATION_SEEN_MAX,
-                        DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX_CAKES)));
-        mRewards.put(REWARD_NOTIFICATION_INTERACTION,
-                new Reward(REWARD_NOTIFICATION_INTERACTION,
-                        getConstantAsCake(
-                                KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT,
-                                DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT_CAKES),
-                        getConstantAsCake(
-                                KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING,
-                                DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING_CAKES),
-                        getConstantAsCake(
-                                KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX,
-                                DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX_CAKES)));
-        mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION,
-                getConstantAsCake(
-                        KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT,
-                        DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT_CAKES),
-                getConstantAsCake(
-                        KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING,
-                        DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING_CAKES),
-                getConstantAsCake(
-                        KEY_JS_REWARD_WIDGET_INTERACTION_MAX,
-                        DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX_CAKES)));
-        mRewards.put(REWARD_OTHER_USER_INTERACTION,
-                new Reward(REWARD_OTHER_USER_INTERACTION,
-                        getConstantAsCake(
-                                KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT,
-                                DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT_CAKES),
-                        getConstantAsCake(
-                                KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING,
-                                DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING_CAKES),
-                        getConstantAsCake(
-                                KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX,
-                                DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX_CAKES)));
-        mRewards.put(REWARD_APP_INSTALL,
-                new Reward(REWARD_APP_INSTALL,
-                        getConstantAsCake(
-                                KEY_JS_REWARD_APP_INSTALL_INSTANT,
-                                DEFAULT_JS_REWARD_APP_INSTALL_INSTANT_CAKES),
-                        getConstantAsCake(
-                                KEY_JS_REWARD_APP_INSTALL_ONGOING,
-                                DEFAULT_JS_REWARD_APP_INSTALL_ONGOING_CAKES),
-                        getConstantAsCake(
-                                KEY_JS_REWARD_APP_INSTALL_MAX,
-                                DEFAULT_JS_REWARD_APP_INSTALL_MAX_CAKES)));
-    }
-
-    @Override
-    void dump(IndentingPrintWriter pw) {
-        pw.println("Min satiated balance:");
-        pw.increaseIndent();
-        pw.print("Exempted", cakeToString(mMinSatiatedBalanceExempted)).println();
-        pw.print("Other", cakeToString(mMinSatiatedBalanceOther)).println();
-        pw.print("+App Updater", cakeToString(mMinSatiatedBalanceIncrementalAppUpdater)).println();
-        pw.decreaseIndent();
-        pw.print("Max satiated balance", cakeToString(mMaxSatiatedBalance)).println();
-        pw.print("Consumption limits: [");
-        pw.print(cakeToString(mMinSatiatedConsumptionLimit));
-        pw.print(", ");
-        pw.print(cakeToString(mInitialSatiatedConsumptionLimit));
-        pw.print(", ");
-        pw.print(cakeToString(mMaxSatiatedConsumptionLimit));
-        pw.println("]");
-
-        pw.println();
-        pw.println("Actions:");
-        pw.increaseIndent();
-        for (int i = 0; i < mActions.size(); ++i) {
-            dumpAction(pw, mActions.valueAt(i));
-        }
-        pw.decreaseIndent();
-
-        pw.println();
-        pw.println("Rewards:");
-        pw.increaseIndent();
-        for (int i = 0; i < mRewards.size(); ++i) {
-            dumpReward(pw, mRewards.valueAt(i));
-        }
-        pw.decreaseIndent();
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java b/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java
deleted file mode 100644
index 92b21e1..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
-import static android.util.TimeUtils.dumpTime;
-
-import static com.android.server.tare.TareUtils.cakeToString;
-import static com.android.server.tare.TareUtils.getCurrentTimeMillis;
-
-import android.annotation.CurrentTimeMillisLong;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Build;
-import android.util.IndentingPrintWriter;
-import android.util.Log;
-import android.util.SparseLongArray;
-import android.util.TimeUtils;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Ledger to track the last recorded balance and recent activities of an app.
- */
-class Ledger {
-    private static final String TAG = "TARE-" + Ledger.class.getSimpleName();
-    private static final boolean DEBUG = InternalResourceService.DEBUG
-            || Log.isLoggable(TAG, Log.DEBUG);
-
-    /** The window size within which rewards will be counted and used towards reward limiting. */
-    private static final long TOTAL_REWARD_WINDOW_MS = 24 * HOUR_IN_MILLIS;
-    /** The number of buckets to split {@link #TOTAL_REWARD_WINDOW_MS} into. */
-    @VisibleForTesting
-    static final int NUM_REWARD_BUCKET_WINDOWS = 4;
-    /**
-     * The duration size of each bucket resulting from splitting {@link #TOTAL_REWARD_WINDOW_MS}
-     * into smaller buckets.
-     */
-    private static final long REWARD_BUCKET_WINDOW_SIZE_MS =
-            TOTAL_REWARD_WINDOW_MS / NUM_REWARD_BUCKET_WINDOWS;
-    /** The maximum number of transactions to retain in memory at any one time. */
-    @VisibleForTesting
-    static final int MAX_TRANSACTION_COUNT = Build.IS_ENG || Build.IS_USERDEBUG || DEBUG ? 32 : 4;
-
-    static class Transaction {
-        public final long startTimeMs;
-        public final long endTimeMs;
-        public final int eventId;
-        @Nullable
-        public final String tag;
-        public final long delta;
-        public final long ctp;
-
-        Transaction(long startTimeMs, long endTimeMs,
-                int eventId, @Nullable String tag, long delta, long ctp) {
-            this.startTimeMs = startTimeMs;
-            this.endTimeMs = endTimeMs;
-            this.eventId = eventId;
-            this.tag = tag == null ? null : tag.intern();
-            this.delta = delta;
-            this.ctp = ctp;
-        }
-    }
-
-    static class RewardBucket {
-        @CurrentTimeMillisLong
-        public long startTimeMs;
-        public final SparseLongArray cumulativeDelta = new SparseLongArray();
-
-        private void reset() {
-            startTimeMs = 0;
-            cumulativeDelta.clear();
-        }
-    }
-
-    /** Last saved balance. This doesn't take currently ongoing events into account. */
-    private long mCurrentBalance = 0;
-    private final Transaction[] mTransactions = new Transaction[MAX_TRANSACTION_COUNT];
-    /** Index within {@link #mTransactions} where the next transaction should be placed. */
-    private int mTransactionIndex = 0;
-    private final RewardBucket[] mRewardBuckets = new RewardBucket[NUM_REWARD_BUCKET_WINDOWS];
-    /** Index within {@link #mRewardBuckets} of the current active bucket. */
-    private int mRewardBucketIndex = 0;
-
-    Ledger() {
-    }
-
-    Ledger(long currentBalance, @NonNull List<Transaction> transactions,
-            @NonNull List<RewardBucket> rewardBuckets) {
-        mCurrentBalance = currentBalance;
-
-        final int numTxs = transactions.size();
-        for (int i = Math.max(0, numTxs - MAX_TRANSACTION_COUNT); i < numTxs; ++i) {
-            mTransactions[mTransactionIndex++] = transactions.get(i);
-        }
-        mTransactionIndex %= MAX_TRANSACTION_COUNT;
-
-        final int numBuckets = rewardBuckets.size();
-        if (numBuckets > 0) {
-            // Set the index to -1 so that we put the first bucket in index 0.
-            mRewardBucketIndex = -1;
-            for (int i = Math.max(0, numBuckets - NUM_REWARD_BUCKET_WINDOWS); i < numBuckets; ++i) {
-                mRewardBuckets[++mRewardBucketIndex] = rewardBuckets.get(i);
-            }
-        }
-    }
-
-    long getCurrentBalance() {
-        return mCurrentBalance;
-    }
-
-    @Nullable
-    Transaction getEarliestTransaction() {
-        for (int t = 0; t < mTransactions.length; ++t) {
-            final Transaction transaction =
-                    mTransactions[(mTransactionIndex + t) % mTransactions.length];
-            if (transaction != null) {
-                return transaction;
-            }
-        }
-        return null;
-    }
-
-    @NonNull
-    List<RewardBucket> getRewardBuckets() {
-        final long cutoffMs = getCurrentTimeMillis() - TOTAL_REWARD_WINDOW_MS;
-        final List<RewardBucket> list = new ArrayList<>(NUM_REWARD_BUCKET_WINDOWS);
-        for (int i = 1; i <= NUM_REWARD_BUCKET_WINDOWS; ++i) {
-            final int idx = (mRewardBucketIndex + i) % NUM_REWARD_BUCKET_WINDOWS;
-            final RewardBucket rewardBucket = mRewardBuckets[idx];
-            if (rewardBucket != null) {
-                if (cutoffMs <= rewardBucket.startTimeMs) {
-                    list.add(rewardBucket);
-                } else {
-                    rewardBucket.reset();
-                }
-            }
-        }
-        return list;
-    }
-
-    @NonNull
-    List<Transaction> getTransactions() {
-        final List<Transaction> list = new ArrayList<>(MAX_TRANSACTION_COUNT);
-        for (int i = 0; i < MAX_TRANSACTION_COUNT; ++i) {
-            final int idx = (mTransactionIndex + i) % MAX_TRANSACTION_COUNT;
-            final Transaction transaction = mTransactions[idx];
-            if (transaction != null) {
-                list.add(transaction);
-            }
-        }
-        return list;
-    }
-
-    void recordTransaction(@NonNull Transaction transaction) {
-        mTransactions[mTransactionIndex] = transaction;
-        mCurrentBalance += transaction.delta;
-        mTransactionIndex = (mTransactionIndex + 1) % MAX_TRANSACTION_COUNT;
-
-        if (EconomicPolicy.isReward(transaction.eventId)) {
-            final RewardBucket bucket = getCurrentRewardBucket();
-            bucket.cumulativeDelta.put(transaction.eventId,
-                    bucket.cumulativeDelta.get(transaction.eventId, 0) + transaction.delta);
-        }
-    }
-
-    @NonNull
-    private RewardBucket getCurrentRewardBucket() {
-        RewardBucket bucket = mRewardBuckets[mRewardBucketIndex];
-        final long now = getCurrentTimeMillis();
-        if (bucket == null) {
-            bucket = new RewardBucket();
-            bucket.startTimeMs = now;
-            mRewardBuckets[mRewardBucketIndex] = bucket;
-            return bucket;
-        }
-
-        if (now - bucket.startTimeMs < REWARD_BUCKET_WINDOW_SIZE_MS) {
-            return bucket;
-        }
-
-        mRewardBucketIndex = (mRewardBucketIndex + 1) % NUM_REWARD_BUCKET_WINDOWS;
-        bucket = mRewardBuckets[mRewardBucketIndex];
-        if (bucket == null) {
-            bucket = new RewardBucket();
-            mRewardBuckets[mRewardBucketIndex] = bucket;
-        }
-        bucket.reset();
-        // Using now as the start time means there will be some gaps between sequential buckets,
-        // but makes processing of large gaps between events easier.
-        bucket.startTimeMs = now;
-        return bucket;
-    }
-
-    long get24HourSum(int eventId, final long now) {
-        final long windowStartTime = now - 24 * HOUR_IN_MILLIS;
-        long sum = 0;
-        for (int i = 0; i < mRewardBuckets.length; ++i) {
-            final RewardBucket bucket = mRewardBuckets[i];
-            if (bucket != null
-                    && bucket.startTimeMs >= windowStartTime && bucket.startTimeMs < now) {
-                sum += bucket.cumulativeDelta.get(eventId, 0);
-            }
-        }
-        return sum;
-    }
-
-    /**
-     * Deletes transactions that are older than {@code minAgeMs}.
-     * @return The earliest transaction in the ledger, or {@code null} if there are no more
-     * transactions.
-     */
-    @Nullable
-    Transaction removeOldTransactions(long minAgeMs) {
-        final long cutoff = getCurrentTimeMillis() - minAgeMs;
-        for (int t = 0; t < mTransactions.length; ++t) {
-            final int idx = (mTransactionIndex + t) % mTransactions.length;
-            final Transaction transaction = mTransactions[idx];
-            if (transaction == null) {
-                continue;
-            }
-            if (transaction.endTimeMs <= cutoff) {
-                mTransactions[idx] = null;
-            } else {
-                // Everything we look at after this transaction will also be within the window,
-                // so no need to go further.
-                return transaction;
-            }
-        }
-        return null;
-    }
-
-    void dump(IndentingPrintWriter pw, int numRecentTransactions) {
-        pw.print("Current balance", cakeToString(getCurrentBalance())).println();
-        pw.println();
-
-        boolean printedTransactionTitle = false;
-        for (int t = 0; t < Math.min(MAX_TRANSACTION_COUNT, numRecentTransactions); ++t) {
-            final int idx = (mTransactionIndex + t) % MAX_TRANSACTION_COUNT;
-            final Transaction transaction = mTransactions[idx];
-            if (transaction == null) {
-                continue;
-            }
-
-            if (!printedTransactionTitle) {
-                pw.println("Transactions:");
-                pw.increaseIndent();
-                printedTransactionTitle = true;
-            }
-
-            dumpTime(pw, transaction.startTimeMs);
-            pw.print("--");
-            dumpTime(pw, transaction.endTimeMs);
-            pw.print(": ");
-            pw.print(EconomicPolicy.eventToString(transaction.eventId));
-            if (transaction.tag != null) {
-                pw.print("(");
-                pw.print(transaction.tag);
-                pw.print(")");
-            }
-            pw.print(" --> ");
-            pw.print(cakeToString(transaction.delta));
-            pw.print(" (ctp=");
-            pw.print(cakeToString(transaction.ctp));
-            pw.println(")");
-        }
-        if (printedTransactionTitle) {
-            pw.decreaseIndent();
-            pw.println();
-        }
-
-        final long now = getCurrentTimeMillis();
-        boolean printedBucketTitle = false;
-        for (int b = 0; b < NUM_REWARD_BUCKET_WINDOWS; ++b) {
-            final int idx = (mRewardBucketIndex - b + NUM_REWARD_BUCKET_WINDOWS)
-                    % NUM_REWARD_BUCKET_WINDOWS;
-            final RewardBucket rewardBucket = mRewardBuckets[idx];
-            if (rewardBucket == null || rewardBucket.startTimeMs == 0) {
-                continue;
-            }
-
-            if (!printedBucketTitle) {
-                pw.println("Reward buckets:");
-                pw.increaseIndent();
-                printedBucketTitle = true;
-            }
-
-            dumpTime(pw, rewardBucket.startTimeMs);
-            pw.print(" (");
-            TimeUtils.formatDuration(now - rewardBucket.startTimeMs, pw);
-            pw.println(" ago):");
-            pw.increaseIndent();
-            for (int r = 0; r < rewardBucket.cumulativeDelta.size(); ++r) {
-                pw.print(EconomicPolicy.eventToString(rewardBucket.cumulativeDelta.keyAt(r)));
-                pw.print(": ");
-                pw.println(cakeToString(rewardBucket.cumulativeDelta.valueAt(r)));
-            }
-            pw.decreaseIndent();
-        }
-        if (printedBucketTitle) {
-            pw.decreaseIndent();
-            pw.println();
-        }
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Modifier.java b/apex/jobscheduler/service/java/com/android/server/tare/Modifier.java
deleted file mode 100644
index 311b6cb..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/Modifier.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import android.annotation.IntDef;
-import android.util.IndentingPrintWriter;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Base class of a modifier that can affect end pricing.
- */
-abstract class Modifier {
-    static final int COST_MODIFIER_CHARGING = 0;
-    static final int COST_MODIFIER_DEVICE_IDLE = 1;
-    static final int COST_MODIFIER_POWER_SAVE_MODE = 2;
-    static final int COST_MODIFIER_PROCESS_STATE = 3;
-    static final int NUM_COST_MODIFIERS = COST_MODIFIER_PROCESS_STATE + 1;
-
-    @IntDef({
-            COST_MODIFIER_CHARGING,
-            COST_MODIFIER_DEVICE_IDLE,
-            COST_MODIFIER_POWER_SAVE_MODE,
-            COST_MODIFIER_PROCESS_STATE,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CostModifier {
-    }
-
-    /**
-     * Returns a modified cost to produce based on the modifier's state.
-     *
-     * @param ctp Current cost to produce
-     */
-    long getModifiedCostToProduce(long ctp) {
-        return ctp;
-    }
-
-    /**
-     * Returns a modified price based on the modifier's state.
-     *
-     * @param price Current price
-     */
-    long getModifiedPrice(long price) {
-        return price;
-    }
-
-    void setup() {
-    }
-
-    void tearDown() {
-    }
-
-    abstract void dump(IndentingPrintWriter pw);
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/OWNERS b/apex/jobscheduler/service/java/com/android/server/tare/OWNERS
deleted file mode 100644
index 96ec75f..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-dplotnikov@google.com
-kwekua@google.com
-mwachens@google.com
-suprabh@google.com
-yamasani@google.com
\ No newline at end of file
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/PowerSaveModeModifier.java b/apex/jobscheduler/service/java/com/android/server/tare/PowerSaveModeModifier.java
deleted file mode 100644
index 542bfd1..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/PowerSaveModeModifier.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import android.annotation.NonNull;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.util.IndentingPrintWriter;
-import android.util.Log;
-import android.util.Slog;
-
-/** Modifier that makes things more expensive in adaptive and full battery saver are active. */
-class PowerSaveModeModifier extends Modifier {
-    private static final String TAG = "TARE-" + PowerSaveModeModifier.class.getSimpleName();
-    private static final boolean DEBUG = InternalResourceService.DEBUG
-            || Log.isLoggable(TAG, Log.DEBUG);
-
-    private final InternalResourceService mIrs;
-    private final PowerSaveModeTracker mPowerSaveModeTracker;
-
-    PowerSaveModeModifier(@NonNull InternalResourceService irs) {
-        super();
-        mIrs = irs;
-        mPowerSaveModeTracker = new PowerSaveModeTracker();
-    }
-
-    @Override
-    public void setup() {
-        mPowerSaveModeTracker.startTracking(mIrs.getContext());
-    }
-
-    @Override
-    public void tearDown() {
-        mPowerSaveModeTracker.stopTracking(mIrs.getContext());
-    }
-
-    @Override
-    long getModifiedCostToProduce(long ctp) {
-        if (mPowerSaveModeTracker.mPowerSaveModeEnabled) {
-            return (long) (1.5 * ctp);
-        }
-        // TODO: get adaptive power save mode
-        if (mPowerSaveModeTracker.mPowerSaveModeEnabled) {
-            return (long) (1.25 * ctp);
-        }
-        return ctp;
-    }
-
-    @Override
-    void dump(IndentingPrintWriter pw) {
-        pw.print("power save=");
-        pw.println(mPowerSaveModeTracker.mPowerSaveModeEnabled);
-    }
-
-    // TODO: migrate to relying on PowerSaveState and ServiceType.TARE
-    private final class PowerSaveModeTracker extends BroadcastReceiver {
-        private boolean mIsSetup = false;
-
-        private final PowerManager mPowerManager;
-        private volatile boolean mPowerSaveModeEnabled;
-
-        private PowerSaveModeTracker() {
-            mPowerManager = mIrs.getContext().getSystemService(PowerManager.class);
-        }
-
-        public void startTracking(@NonNull Context context) {
-            if (mIsSetup) {
-                return;
-            }
-
-            final IntentFilter filter = new IntentFilter();
-            filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
-            context.registerReceiver(this, filter);
-
-            // Initialise tracker state.
-            mPowerSaveModeEnabled = mPowerManager.isPowerSaveMode();
-
-            mIsSetup = true;
-        }
-
-        public void stopTracking(@NonNull Context context) {
-            if (!mIsSetup) {
-                return;
-            }
-
-            context.unregisterReceiver(this);
-            mIsSetup = false;
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)) {
-                final boolean enabled = mPowerManager.isPowerSaveMode();
-                if (DEBUG) {
-                    Slog.d(TAG, "Power save mode changed to " + enabled
-                            + ", fired @ " + SystemClock.elapsedRealtime());
-                }
-                if (mPowerSaveModeEnabled != enabled) {
-                    mPowerSaveModeEnabled = enabled;
-                    mIrs.onDeviceStateChanged();
-                }
-            }
-        }
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/ProcessStateModifier.java b/apex/jobscheduler/service/java/com/android/server/tare/ProcessStateModifier.java
deleted file mode 100644
index 58536675..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/ProcessStateModifier.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.app.ActivityManager;
-import android.app.IUidObserver;
-import android.app.UidObserver;
-import android.os.RemoteException;
-import android.util.IndentingPrintWriter;
-import android.util.Slog;
-import android.util.SparseArrayMap;
-import android.util.SparseIntArray;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/** Modifier that makes things more cheaper based on an app's process state. */
-class ProcessStateModifier extends Modifier {
-    private static final String TAG = "TARE-" + ProcessStateModifier.class.getSimpleName();
-
-    private static final int PROC_STATE_BUCKET_NONE = 0;
-    private static final int PROC_STATE_BUCKET_TOP = 1;
-    private static final int PROC_STATE_BUCKET_FGS = 2;
-    private static final int PROC_STATE_BUCKET_BFGS = 3;
-    private static final int PROC_STATE_BUCKET_BG = 4;
-
-    @IntDef(prefix = {"PROC_STATE_BUCKET_"}, value = {
-            PROC_STATE_BUCKET_NONE,
-            PROC_STATE_BUCKET_TOP,
-            PROC_STATE_BUCKET_FGS,
-            PROC_STATE_BUCKET_BFGS,
-            PROC_STATE_BUCKET_BG
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ProcStateBucket {
-    }
-
-    private final Object mLock = new Object();
-    private final InternalResourceService mIrs;
-
-    /** Cached mapping of userId+package to their UIDs (for all users) */
-    private final SparseArrayMap<String, Integer> mPackageToUidCache = new SparseArrayMap<>();
-
-    @GuardedBy("mLock")
-    private final SparseIntArray mUidProcStateBucketCache = new SparseIntArray();
-
-    private final IUidObserver mUidObserver = new UidObserver() {
-        @Override
-        public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
-            final int newBucket = getProcStateBucket(procState);
-            synchronized (mLock) {
-                final int curBucket = mUidProcStateBucketCache.get(uid);
-                if (curBucket != newBucket) {
-                    mUidProcStateBucketCache.put(uid, newBucket);
-                }
-                notifyStateChangedLocked(uid);
-            }
-        }
-
-        @Override
-        public void onUidGone(int uid, boolean disabled) {
-            synchronized (mLock) {
-                if (mUidProcStateBucketCache.indexOfKey(uid) < 0) {
-                    Slog.e(TAG, "UID " + uid + " marked gone but wasn't in cache.");
-                    return;
-                }
-                mUidProcStateBucketCache.delete(uid);
-                notifyStateChangedLocked(uid);
-            }
-        }
-    };
-
-    ProcessStateModifier(@NonNull InternalResourceService irs) {
-        super();
-        mIrs = irs;
-    }
-
-    @Override
-    @GuardedBy("mLock")
-    void setup() {
-        try {
-            ActivityManager.getService().registerUidObserver(mUidObserver,
-                    ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
-                    ActivityManager.PROCESS_STATE_UNKNOWN, null);
-        } catch (RemoteException e) {
-            // ignored; both services live in system_server
-        }
-    }
-
-    @Override
-    @GuardedBy("mLock")
-    void tearDown() {
-        try {
-            ActivityManager.getService().unregisterUidObserver(mUidObserver);
-        } catch (RemoteException e) {
-            // ignored; both services live in system_server
-        }
-        mPackageToUidCache.clear();
-        mUidProcStateBucketCache.clear();
-    }
-
-    /**
-     * Get the final modified price based on an app's process state.
-     *
-     * @param ctp   Cost to produce. @see EconomicPolicy.Action#costToProduce
-     * @param price Current price
-     */
-    long getModifiedPrice(final int userId, @NonNull final String pkgName,
-            final long ctp, final long price) {
-        final int procState;
-        synchronized (mLock) {
-            procState = mUidProcStateBucketCache.get(
-                    mIrs.getUid(userId, pkgName), PROC_STATE_BUCKET_NONE);
-        }
-        switch (procState) {
-            case PROC_STATE_BUCKET_TOP:
-                return 0;
-            case PROC_STATE_BUCKET_FGS:
-                // Can't get notification priority. Just use CTP for now.
-                return Math.min(ctp, price);
-            case PROC_STATE_BUCKET_BFGS:
-                if (price <= ctp) {
-                    return price;
-                }
-                return (long) (ctp + .5 * (price - ctp));
-            case PROC_STATE_BUCKET_BG:
-            default:
-                return price;
-        }
-    }
-
-    @Override
-    @GuardedBy("mLock")
-    void dump(IndentingPrintWriter pw) {
-        pw.print("Proc state bucket cache = ");
-        pw.println(mUidProcStateBucketCache);
-    }
-
-    @ProcStateBucket
-    private int getProcStateBucket(int procState) {
-        if (procState <= ActivityManager.PROCESS_STATE_TOP) {
-            return PROC_STATE_BUCKET_TOP;
-        }
-        if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
-            return PROC_STATE_BUCKET_FGS;
-        }
-        if (procState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
-            return PROC_STATE_BUCKET_BFGS;
-        }
-        return PROC_STATE_BUCKET_BG;
-    }
-
-    @GuardedBy("mLock")
-    private void notifyStateChangedLocked(final int uid) {
-        // Never call out to the IRS with the local lock held.
-        TareHandlerThread.getHandler().post(() -> mIrs.onUidStateChanged(uid));
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/README.md b/apex/jobscheduler/service/java/com/android/server/tare/README.md
deleted file mode 100644
index 8d25ecc..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/README.md
+++ /dev/null
@@ -1,153 +0,0 @@
-# Overview
-
-Welcome to The Android Resource Economy (TARE for short). If you're reading this, you may be
-wondering what all of this code is for and what it means. TARE is an attempt to apply economic
-principles to resource (principally battery) management. It acknowledges that battery is a limited
-resource on mobile devices and that the system must allocate and apportion those resources
-accordingly. Every action (running a job, firing an alarm, using the network, using the CPU, etc.)
-has a cost. Once that action has been performed and that bit of battery has been drained, it's no
-longer available for someone else (another app) to use until the user charges the device again.
-
-The key tenets of TARE are:
-
-1. Charge for actions --- when an app performs an action, reduce its access to resources in the
-   future. This should help remind everyone that everything they do has a cost.
-1. Reward for good actions --- reward and encourage behavior that provides value to the user
-1. Fine bad actions --- fine and discourage behavior that is bad for the user
-
-In an ideal world, the system could be said to most efficiently allocate resources by maximizing its
-profits &mdash; by maximizing the aggregate sum of the difference between an action's price (that
-the app ends up paying) and the cost to produce by the system. This assumes that more important
-actions have a higher price than less important actions and all actors have perfect information and
-convey that information accurately. With these assumptions, maximizing profits implies that the
-system runs the most important work first and proceeds in decreasing order of importance. Of course,
-that also means the system will not run anything where an app would pay less for the action than the
-system's cost to produce that action. Some of this breaks down when we throw TOP apps into the mix
-&mdash; TOP apps pay 0 for all actions, even though the CTP may be greater than 0. This is to ensure
-ideal user experience for the app the user is actively interacting with. Similar caveats exist for
-system-critical processes (such as the OS itself) and apps running foreground services (since those
-could be critical to user experience, as is the case for media and navigation apps). Excluding those
-caveats/special situations, maximizing profits of actions performed by apps in the background should
-be the target.
-
-To achieve the goal laid out by TARE, we use Android Resource Credits (ARCs for short) as the
-internal/representative currency of the system.
-
-## How do ARCs work?
-
-ARCs are required to perform any action while in the background. Some actions may have a fixed cost.
-Others may be more dynamic (some may even allow apps to bid higher ARCs for some actions to have
-them prioritized). If the app doesn't have enough ARCs, the action can't be performed. Apps are
-granted ARCs (below a certain threshold) as the device charges. Apps are also granted ARCs for
-providing user value (eg. for doing things that engage the user).
-
-ARCs will be used across the entire system as one unified concept. When an app performs an action,
-it pulls from the same account, regardless of the action. This means that apps can choose to do more
-of one action in lieu of being able to do as much of another. For example, an app can choose to use
-all of its ARCs for jobs if it doesn't want to schedule any alarms.
-
-### Scaling
-
-With the ARC system, we can limit the total number of ARCs in circulation, thus limiting how much
-total work can be done, regardless of how many apps the user has installed.
-
-## EconomicPolicy
-
-An EconomicPolicy defines the actions and rewards a specific subsystem makes use of. Each subsystem
-will likely have a unique set of actions that apps can perform, and may choose to reward apps for
-certain behaviors. Generally, the app should be rewarded with ARCs for behaviors that indicate that
-the app provided value to the user. The current set of behaviors that apps may be rewarded for
-include 1) a user seeing a notification, 2) a user interacting with a notification, 3) the user
-opening the app and/or staying in the app for some period of time, 4) the user interacting with a
-widget, and 5) the user explicitly interacting with the app in some other way. These behaviors may
-change as we determine better ways of identifying providing value to the user and/or user desire for
-the app to perform the actions it's requesting.
-
-### Consumption Limit
-
-The consumption limit represents the maximum amount of resources available to be consumed. When the
-battery is satiated (at 100%), then the amount of resources available to be consumed is equal to the
-consumption limit. Each action has a cost to produce that action. When the action is performed,
-those resources are consumed. Thus, when an action is performed, the action's CTP is deducted from
-the remaining amount of resources available. In keeping with the tenet that resources are limited
-and ARCs are a proxy for battery consumption, the amount of resources available to be consumed are
-adjusted as the battery level changes. That is, the consumption limit is scaled based on the current
-battery level, and if the amount currently available to be consumed is greater than the scaled
-consumption limit, then the available resources are decreased to match the scaled limit.
-
-### Regulation
-
-Regulations are unique events invoked by the ~~government~~ system in order to get the whole economy
-moving smoothly.
-
-# Significant Changes
-
-## Tare Improvement Proposal #1 (TIP1)
-
-The initial implementation/proposal combined the supply of resources with the allocation in a single
-mechanism. It defined the maximum number of resources (ARCs) available at a time, and then divided
-(allocated) that number among the installed apps, intending to have some left over that could be
-allocated as part of the rewards. There were several problems with that mechanism:
-
-1. Not all apps used their credits, which meant that allocating credits to those packages
-   effectively permanently reduced the number of usable/re-allocatable ARCs.
-1. Having a global maximum circulation spread across multiple apps meant that as more apps were
-   installed, the allocation to each app decreased. Eventually (with enough apps installed), no app
-   would be given enough credits to perform any actions.
-
-These problems effectively meant that misallocation was a big problem, demand wasn't well reflected,
-and some apps may not have been able to perform work even though they otherwise should have been.
-
-TIP1 separated allocation (to apps) from supply (by the system) and
-allowed apps to accrue credits as appropriate while still limiting the total number of credits
-consumed.
-
-## Tare Improvement Proposal #3 (TIP3)
-
-TIP1 introduced Consumption Limits, which control the total number of ARCs that can be used to
-perform actions, based on the production costs of each action. The Consumption Limits were initially
-determined manually, but could increase in the system if apps used the full consumption limit before
-the device had drained to 50% battery. As with any system that relies on manually deciding
-parameters, the only mechanism to identify an optimal value is through experimentation, which can
-take many iterations and requires extended periods of time to observe results. The limits are also
-chosen and adjusted without consideration of the resulting battery drain of each possible value. In
-addition, having the system potentially increase the limit without considering a decrease introduced
-potential for battery life to get worse as time goes on and the user installed more background-work
-demanding apps.
-
-TIP3 uses a target background battery drain rate to dynamically adjust the Consumption Limit.
-
-# Potential Future Changes
-
-These are some ideas for further changes. There's no guarantee that they'll be implemented.
-
-* Include additional components and policies for them. TARE may benefit from adding policies for
-  components such as broadcast dispatching, network traffic, location requests, and sensor usage.
-* Have a separate "account" for critical/special actions. In other words, have two accounts for each
-  app, where one acts like a special savings account and is only allowed to be used for special
-  actions such as expedited job execution. The second account would have a lower maximum than the
-  main account, but would help to make sure that normal actions don't interfere too much with more
-  critical actions.
-* Transferring credits from one app to another. For apps that rely on others for some pieces of
-  work, it may be beneficial to allow the requesting app to transfer, donate, or somehow make
-  available some of its own credits to the app doing the work in order to make sure the working app
-  has enough credits available to do the work.
-* Formulate values based on device hardware. For example, adjust the consumption limit based on the
-  battery size, or the price and/or CTP of actions based on hardware efficiency.
-* Price discovery via an auction system. Instead of just setting a fixed price that may be modified
-  by device and app states, let an app say how much it's willing to pay for a specific action and
-  then have a small auction when the system needs to decide which app to perform the action for
-  first or how much to charge the app.
-
-# Definitions
-
-* ARC: Android Resource Credits are the "currency" units used as an abstraction layer over the real
-  battery drain. They allow the system to standardize costs and prices across various devices.
-* Cake: A lie; also the smallest unit of an ARC (1 cake = one-billionth of an ARC = 1 nano-ARC).
-  When the apps request to do something, we shall let them eat cake.
-* Cost to produce (CTP): An economic term that refers to the total cost incurred by a business to
-  produce a specific quantity of a product or offer a service. In TARE's context, CTP is meant to be
-  the estimated cost t ohe system to accomplish a certain action. These "actions" are basically APIs
-  that apps use to get something done. So the idea is to define the base cost for an app to use a
-  specific API.
-* Satiated: used to refer to when the device is fully charged (at 100% battery level)
\ No newline at end of file
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java b/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java
deleted file mode 100644
index 87e1249..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java
+++ /dev/null
@@ -1,827 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static android.app.tare.EconomyManager.ENABLED_MODE_OFF;
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
-
-import static com.android.server.tare.TareUtils.appToString;
-import static com.android.server.tare.TareUtils.cakeToString;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.os.Environment;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.util.ArraySet;
-import android.util.AtomicFile;
-import android.util.IndentingPrintWriter;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.util.SparseArrayMap;
-import android.util.SparseLongArray;
-import android.util.Xml;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.modules.utils.TypedXmlPullParser;
-import com.android.modules.utils.TypedXmlSerializer;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Maintains the current TARE state and handles writing it to disk and reading it back from disk.
- */
-public class Scribe {
-    private static final String TAG = "TARE-" + Scribe.class.getSimpleName();
-    private static final boolean DEBUG = InternalResourceService.DEBUG
-            || Log.isLoggable(TAG, Log.DEBUG);
-
-    /** The maximum number of transactions to dump per ledger. */
-    private static final int MAX_NUM_TRANSACTION_DUMP = 25;
-    /**
-     * The maximum amount of time we'll keep a transaction around for.
-     */
-    private static final long MAX_TRANSACTION_AGE_MS = 8 * 24 * HOUR_IN_MILLIS;
-
-    private static final String XML_TAG_HIGH_LEVEL_STATE = "irs-state";
-    private static final String XML_TAG_LEDGER = "ledger";
-    private static final String XML_TAG_TARE = "tare";
-    private static final String XML_TAG_TRANSACTION = "transaction";
-    private static final String XML_TAG_REWARD_BUCKET = "rewardBucket";
-    private static final String XML_TAG_USER = "user";
-    private static final String XML_TAG_PERIOD_REPORT = "report";
-
-    private static final String XML_ATTR_CTP = "ctp";
-    private static final String XML_ATTR_DELTA = "delta";
-    private static final String XML_ATTR_EVENT_ID = "eventId";
-    private static final String XML_ATTR_TAG = "tag";
-    private static final String XML_ATTR_START_TIME = "startTime";
-    private static final String XML_ATTR_END_TIME = "endTime";
-    private static final String XML_ATTR_PACKAGE_NAME = "pkgName";
-    private static final String XML_ATTR_CURRENT_BALANCE = "currentBalance";
-    private static final String XML_ATTR_USER_ID = "userId";
-    private static final String XML_ATTR_VERSION = "version";
-    private static final String XML_ATTR_LAST_RECLAMATION_TIME = "lastReclamationTime";
-    private static final String XML_ATTR_LAST_STOCK_RECALCULATION_TIME =
-            "lastStockRecalculationTime";
-    private static final String XML_ATTR_REMAINING_CONSUMABLE_CAKES = "remainingConsumableCakes";
-    private static final String XML_ATTR_CONSUMPTION_LIMIT = "consumptionLimit";
-    private static final String XML_ATTR_TIME_SINCE_FIRST_SETUP_MS = "timeSinceFirstSetup";
-    private static final String XML_ATTR_PR_DISCHARGE = "discharge";
-    private static final String XML_ATTR_PR_BATTERY_LEVEL = "batteryLevel";
-    private static final String XML_ATTR_PR_PROFIT = "profit";
-    private static final String XML_ATTR_PR_NUM_PROFIT = "numProfits";
-    private static final String XML_ATTR_PR_LOSS = "loss";
-    private static final String XML_ATTR_PR_NUM_LOSS = "numLoss";
-    private static final String XML_ATTR_PR_REWARDS = "rewards";
-    private static final String XML_ATTR_PR_NUM_REWARDS = "numRewards";
-    private static final String XML_ATTR_PR_POS_REGULATIONS = "posRegulations";
-    private static final String XML_ATTR_PR_NUM_POS_REGULATIONS = "numPosRegulations";
-    private static final String XML_ATTR_PR_NEG_REGULATIONS = "negRegulations";
-    private static final String XML_ATTR_PR_NUM_NEG_REGULATIONS = "numNegRegulations";
-    private static final String XML_ATTR_PR_SCREEN_OFF_DURATION_MS = "screenOffDurationMs";
-    private static final String XML_ATTR_PR_SCREEN_OFF_DISCHARGE_MAH = "screenOffDischargeMah";
-
-    /** Version of the file schema. */
-    private static final int STATE_FILE_VERSION = 0;
-    /** Minimum amount of time between consecutive writes. */
-    private static final long WRITE_DELAY = 30_000L;
-
-    private final AtomicFile mStateFile;
-    private final InternalResourceService mIrs;
-    private final Analyst mAnalyst;
-
-    /**
-     * The value of elapsed realtime since TARE was first setup that was read from disk.
-     * This will only be changed when the persisted file is read.
-     */
-    private long mLoadedTimeSinceFirstSetup;
-    @GuardedBy("mIrs.getLock()")
-    private long mLastReclamationTime;
-    @GuardedBy("mIrs.getLock()")
-    private long mLastStockRecalculationTime;
-    @GuardedBy("mIrs.getLock()")
-    private long mSatiatedConsumptionLimit;
-    @GuardedBy("mIrs.getLock()")
-    private long mRemainingConsumableCakes;
-    @GuardedBy("mIrs.getLock()")
-    private final SparseArrayMap<String, Ledger> mLedgers = new SparseArrayMap<>();
-    /** Offsets used to calculate the total realtime since each user was added. */
-    @GuardedBy("mIrs.getLock()")
-    private final SparseLongArray mRealtimeSinceUsersAddedOffsets = new SparseLongArray();
-
-    private final Runnable mCleanRunnable = this::cleanupLedgers;
-    private final Runnable mWriteRunnable = this::writeState;
-
-    Scribe(InternalResourceService irs, Analyst analyst) {
-        this(irs, analyst, Environment.getDataSystemDirectory());
-    }
-
-    @VisibleForTesting
-    Scribe(InternalResourceService irs, Analyst analyst, File dataDir) {
-        mIrs = irs;
-        mAnalyst = analyst;
-
-        final File tareDir = new File(dataDir, "tare");
-        //noinspection ResultOfMethodCallIgnored
-        tareDir.mkdirs();
-        mStateFile = new AtomicFile(new File(tareDir, "state.xml"), "tare");
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    void adjustRemainingConsumableCakesLocked(long delta) {
-        final long staleCakes = mRemainingConsumableCakes;
-        mRemainingConsumableCakes += delta;
-        if (mRemainingConsumableCakes < 0) {
-            Slog.w(TAG, "Overdrew consumable cakes by " + cakeToString(-mRemainingConsumableCakes));
-            // A negative value would interfere with allowing free actions, so set the minimum as 0.
-            mRemainingConsumableCakes = 0;
-        }
-        if (mRemainingConsumableCakes != staleCakes) {
-            // No point doing any work if there was no functional change.
-            postWrite();
-        }
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    void discardLedgerLocked(final int userId, @NonNull final String pkgName) {
-        mLedgers.delete(userId, pkgName);
-        postWrite();
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    void onUserRemovedLocked(final int userId) {
-        mLedgers.delete(userId);
-        mRealtimeSinceUsersAddedOffsets.delete(userId);
-        postWrite();
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    long getSatiatedConsumptionLimitLocked() {
-        return mSatiatedConsumptionLimit;
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    long getLastReclamationTimeLocked() {
-        return mLastReclamationTime;
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    long getLastStockRecalculationTimeLocked() {
-        return mLastStockRecalculationTime;
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    @NonNull
-    Ledger getLedgerLocked(final int userId, @NonNull final String pkgName) {
-        Ledger ledger = mLedgers.get(userId, pkgName);
-        if (ledger == null) {
-            ledger = new Ledger();
-            mLedgers.add(userId, pkgName, ledger);
-        }
-        return ledger;
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    @NonNull
-    SparseArrayMap<String, Ledger> getLedgersLocked() {
-        return mLedgers;
-    }
-
-    /**
-     * Returns the sum of credits granted to all apps on the system. This is expensive so don't
-     * call it for normal operation.
-     */
-    @GuardedBy("mIrs.getLock()")
-    long getCakesInCirculationForLoggingLocked() {
-        long sum = 0;
-        for (int uIdx = mLedgers.numMaps() - 1; uIdx >= 0; --uIdx) {
-            for (int pIdx = mLedgers.numElementsForKeyAt(uIdx) - 1; pIdx >= 0; --pIdx) {
-                sum += mLedgers.valueAt(uIdx, pIdx).getCurrentBalance();
-            }
-        }
-        return sum;
-    }
-
-    /** Returns the cumulative elapsed realtime since TARE was first setup. */
-    long getRealtimeSinceFirstSetupMs(long nowElapsed) {
-        return mLoadedTimeSinceFirstSetup + nowElapsed;
-    }
-
-    /** Returns the total amount of cakes that remain to be consumed. */
-    @GuardedBy("mIrs.getLock()")
-    long getRemainingConsumableCakesLocked() {
-        return mRemainingConsumableCakes;
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    SparseLongArray getRealtimeSinceUsersAddedLocked(long nowElapsed) {
-        final SparseLongArray realtimes = new SparseLongArray();
-        for (int i = mRealtimeSinceUsersAddedOffsets.size() - 1; i >= 0; --i) {
-            realtimes.put(mRealtimeSinceUsersAddedOffsets.keyAt(i),
-                    mRealtimeSinceUsersAddedOffsets.valueAt(i) + nowElapsed);
-        }
-        return realtimes;
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    void loadFromDiskLocked() {
-        mLedgers.clear();
-        if (!recordExists()) {
-            mSatiatedConsumptionLimit = mIrs.getInitialSatiatedConsumptionLimitLocked();
-            mRemainingConsumableCakes = mIrs.getConsumptionLimitLocked();
-            return;
-        }
-        mSatiatedConsumptionLimit = 0;
-        mRemainingConsumableCakes = 0;
-
-        final SparseArray<ArraySet<String>> installedPackagesPerUser = new SparseArray<>();
-        final SparseArrayMap<String, InstalledPackageInfo> installedPackages =
-                mIrs.getInstalledPackages();
-        for (int uIdx = installedPackages.numMaps() - 1; uIdx >= 0; --uIdx) {
-            final int userId = installedPackages.keyAt(uIdx);
-
-            for (int pIdx = installedPackages.numElementsForKeyAt(uIdx) - 1; pIdx >= 0; --pIdx) {
-                final InstalledPackageInfo packageInfo = installedPackages.valueAt(uIdx, pIdx);
-                if (packageInfo.uid != InstalledPackageInfo.NO_UID) {
-                    ArraySet<String> pkgsForUser = installedPackagesPerUser.get(userId);
-                    if (pkgsForUser == null) {
-                        pkgsForUser = new ArraySet<>();
-                        installedPackagesPerUser.put(userId, pkgsForUser);
-                    }
-                    pkgsForUser.add(packageInfo.packageName);
-                }
-            }
-        }
-
-        final List<Analyst.Report> reports = new ArrayList<>();
-        try (FileInputStream fis = mStateFile.openRead()) {
-            TypedXmlPullParser parser = Xml.resolvePullParser(fis);
-
-            int eventType = parser.getEventType();
-            while (eventType != XmlPullParser.START_TAG
-                    && eventType != XmlPullParser.END_DOCUMENT) {
-                eventType = parser.next();
-            }
-            if (eventType == XmlPullParser.END_DOCUMENT) {
-                if (DEBUG) {
-                    Slog.w(TAG, "No persisted state.");
-                }
-                return;
-            }
-
-            String tagName = parser.getName();
-            if (XML_TAG_TARE.equals(tagName)) {
-                final int version = parser.getAttributeInt(null, XML_ATTR_VERSION);
-                if (version < 0 || version > STATE_FILE_VERSION) {
-                    Slog.e(TAG, "Invalid version number (" + version + "), aborting file read");
-                    return;
-                }
-            }
-
-            final long now = System.currentTimeMillis();
-            final long endTimeCutoff = now - MAX_TRANSACTION_AGE_MS;
-            long earliestEndTime = Long.MAX_VALUE;
-            for (eventType = parser.next(); eventType != XmlPullParser.END_DOCUMENT;
-                    eventType = parser.next()) {
-                if (eventType != XmlPullParser.START_TAG) {
-                    continue;
-                }
-                tagName = parser.getName();
-                if (tagName == null) {
-                    continue;
-                }
-
-                switch (tagName) {
-                    case XML_TAG_HIGH_LEVEL_STATE:
-                        mLastReclamationTime =
-                                parser.getAttributeLong(null, XML_ATTR_LAST_RECLAMATION_TIME);
-                        mLastStockRecalculationTime = parser.getAttributeLong(null,
-                                XML_ATTR_LAST_STOCK_RECALCULATION_TIME, 0);
-                        mLoadedTimeSinceFirstSetup =
-                                parser.getAttributeLong(null, XML_ATTR_TIME_SINCE_FIRST_SETUP_MS,
-                                        // If there's no recorded time since first setup, then
-                                        // offset the current elapsed time so it doesn't shift the
-                                        // timing too much.
-                                        -SystemClock.elapsedRealtime());
-                        mSatiatedConsumptionLimit =
-                                parser.getAttributeLong(null, XML_ATTR_CONSUMPTION_LIMIT,
-                                        mIrs.getInitialSatiatedConsumptionLimitLocked());
-                        final long consumptionLimit = mIrs.getConsumptionLimitLocked();
-                        mRemainingConsumableCakes = Math.min(consumptionLimit,
-                                parser.getAttributeLong(null, XML_ATTR_REMAINING_CONSUMABLE_CAKES,
-                                        consumptionLimit));
-                        break;
-                    case XML_TAG_USER:
-                        earliestEndTime = Math.min(earliestEndTime,
-                                readUserFromXmlLocked(
-                                        parser, installedPackagesPerUser, endTimeCutoff));
-                        break;
-                    case XML_TAG_PERIOD_REPORT:
-                        reports.add(readReportFromXml(parser));
-                        break;
-                    default:
-                        Slog.e(TAG, "Unexpected tag: " + tagName);
-                        break;
-                }
-            }
-            mAnalyst.loadReports(reports);
-            scheduleCleanup(earliestEndTime);
-        } catch (IOException | XmlPullParserException e) {
-            Slog.wtf(TAG, "Error reading state from disk", e);
-        }
-    }
-
-    @VisibleForTesting
-    void postWrite() {
-        TareHandlerThread.getHandler().postDelayed(mWriteRunnable, WRITE_DELAY);
-    }
-
-    boolean recordExists() {
-        return mStateFile.exists();
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    void setConsumptionLimitLocked(long limit) {
-        if (mRemainingConsumableCakes > limit) {
-            mRemainingConsumableCakes = limit;
-        } else if (limit > mSatiatedConsumptionLimit) {
-            final long diff = mSatiatedConsumptionLimit - mRemainingConsumableCakes;
-            mRemainingConsumableCakes = (limit - diff);
-        }
-        mSatiatedConsumptionLimit = limit;
-        postWrite();
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    void setLastReclamationTimeLocked(long time) {
-        mLastReclamationTime = time;
-        postWrite();
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    void setLastStockRecalculationTimeLocked(long time) {
-        mLastStockRecalculationTime = time;
-        postWrite();
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    void setUserAddedTimeLocked(int userId, long timeElapsed) {
-        // Use the current time as an offset so that when we persist the time, it correctly persists
-        // as "time since now".
-        mRealtimeSinceUsersAddedOffsets.put(userId, -timeElapsed);
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    void tearDownLocked() {
-        TareHandlerThread.getHandler().removeCallbacks(mCleanRunnable);
-        TareHandlerThread.getHandler().removeCallbacks(mWriteRunnable);
-        mLedgers.clear();
-        mRemainingConsumableCakes = 0;
-        mSatiatedConsumptionLimit = 0;
-        mLastReclamationTime = 0;
-    }
-
-    @VisibleForTesting
-    void writeImmediatelyForTesting() {
-        mWriteRunnable.run();
-    }
-
-    private void cleanupLedgers() {
-        synchronized (mIrs.getLock()) {
-            TareHandlerThread.getHandler().removeCallbacks(mCleanRunnable);
-            long earliestEndTime = Long.MAX_VALUE;
-            for (int uIdx = mLedgers.numMaps() - 1; uIdx >= 0; --uIdx) {
-                final int userId = mLedgers.keyAt(uIdx);
-
-                for (int pIdx = mLedgers.numElementsForKey(userId) - 1; pIdx >= 0; --pIdx) {
-                    final String pkgName = mLedgers.keyAt(uIdx, pIdx);
-                    final Ledger ledger = mLedgers.get(userId, pkgName);
-                    final Ledger.Transaction transaction =
-                            ledger.removeOldTransactions(MAX_TRANSACTION_AGE_MS);
-                    if (transaction != null) {
-                        earliestEndTime = Math.min(earliestEndTime, transaction.endTimeMs);
-                    }
-                }
-            }
-            scheduleCleanup(earliestEndTime);
-        }
-    }
-
-    /** Returns the {@link String#intern() interned} String if it's not null. */
-    @Nullable
-    private static String intern(@Nullable String val) {
-        return val == null ? null : val.intern();
-    }
-
-    /**
-     * @param parser Xml parser at the beginning of a "<ledger/>" tag. The next "parser.next()" call
-     *               will take the parser into the body of the ledger tag.
-     * @return Newly instantiated ledger holding all the information we just read out of the xml
-     * tag, and the package name associated with the ledger.
-     */
-    @Nullable
-    private static Pair<String, Ledger> readLedgerFromXml(TypedXmlPullParser parser,
-            ArraySet<String> validPackages, long endTimeCutoff)
-            throws XmlPullParserException, IOException {
-        final String pkgName;
-        final long curBalance;
-        final List<Ledger.Transaction> transactions = new ArrayList<>();
-        final List<Ledger.RewardBucket> rewardBuckets = new ArrayList<>();
-
-        pkgName = intern(parser.getAttributeValue(null, XML_ATTR_PACKAGE_NAME));
-        curBalance = parser.getAttributeLong(null, XML_ATTR_CURRENT_BALANCE);
-
-        final boolean isInstalled = validPackages.contains(pkgName);
-        if (!isInstalled) {
-            // Don't return early since we need to go through all the transaction tags and get
-            // to the end of the ledger tag.
-            Slog.w(TAG, "Invalid pkg " + pkgName + " is saved to disk");
-        }
-
-        for (int eventType = parser.next(); eventType != XmlPullParser.END_DOCUMENT;
-                eventType = parser.next()) {
-            final String tagName = parser.getName();
-            if (eventType == XmlPullParser.END_TAG) {
-                if (XML_TAG_LEDGER.equals(tagName)) {
-                    // We've reached the end of the ledger tag.
-                    break;
-                }
-                continue;
-            }
-            if (eventType != XmlPullParser.START_TAG || tagName == null) {
-                Slog.e(TAG, "Unexpected event: (" + eventType + ") " + tagName);
-                return null;
-            }
-            if (!isInstalled) {
-                continue;
-            }
-            if (DEBUG) {
-                Slog.d(TAG, "Starting ledger tag: " + tagName);
-            }
-            switch (tagName) {
-                case XML_TAG_TRANSACTION:
-                    final long endTime = parser.getAttributeLong(null, XML_ATTR_END_TIME);
-                    if (endTime <= endTimeCutoff) {
-                        if (DEBUG) {
-                            Slog.d(TAG, "Skipping event because it's too old.");
-                        }
-                        continue;
-                    }
-                    final String tag = intern(parser.getAttributeValue(null, XML_ATTR_TAG));
-                    final long startTime = parser.getAttributeLong(null, XML_ATTR_START_TIME);
-                    final int eventId = parser.getAttributeInt(null, XML_ATTR_EVENT_ID);
-                    final long delta = parser.getAttributeLong(null, XML_ATTR_DELTA);
-                    final long ctp = parser.getAttributeLong(null, XML_ATTR_CTP);
-                    transactions.add(
-                            new Ledger.Transaction(startTime, endTime, eventId, tag, delta, ctp));
-                    break;
-                case XML_TAG_REWARD_BUCKET:
-                    rewardBuckets.add(readRewardBucketFromXml(parser));
-                    break;
-                default:
-                    // Expecting only "transaction" and "rewardBucket" tags.
-                    Slog.e(TAG, "Unexpected event: (" + eventType + ") " + tagName);
-                    return null;
-            }
-        }
-
-        if (!isInstalled) {
-            return null;
-        }
-        return Pair.create(pkgName, new Ledger(curBalance, transactions, rewardBuckets));
-    }
-
-    /**
-     * @param parser Xml parser at the beginning of a "<user>" tag. The next "parser.next()" call
-     *               will take the parser into the body of the user tag.
-     * @return The earliest valid transaction end time found for the user.
-     */
-    @GuardedBy("mIrs.getLock()")
-    private long readUserFromXmlLocked(TypedXmlPullParser parser,
-            SparseArray<ArraySet<String>> installedPackagesPerUser,
-            long endTimeCutoff) throws XmlPullParserException, IOException {
-        int curUser = parser.getAttributeInt(null, XML_ATTR_USER_ID);
-        final ArraySet<String> installedPackages = installedPackagesPerUser.get(curUser);
-        if (installedPackages == null) {
-            Slog.w(TAG, "Invalid user " + curUser + " is saved to disk");
-            curUser = UserHandle.USER_NULL;
-            // Don't return early since we need to go through all the ledger tags and get to the end
-            // of the user tag.
-        }
-        if (curUser != UserHandle.USER_NULL) {
-            mRealtimeSinceUsersAddedOffsets.put(curUser,
-                            parser.getAttributeLong(null, XML_ATTR_TIME_SINCE_FIRST_SETUP_MS,
-                                    // If there's no recorded time since first setup, then
-                                    // offset the current elapsed time so it doesn't shift the
-                                    // timing too much.
-                                    -SystemClock.elapsedRealtime()));
-        }
-        long earliestEndTime = Long.MAX_VALUE;
-
-        for (int eventType = parser.next(); eventType != XmlPullParser.END_DOCUMENT;
-                eventType = parser.next()) {
-            final String tagName = parser.getName();
-            if (eventType == XmlPullParser.END_TAG) {
-                if (XML_TAG_USER.equals(tagName)) {
-                    // We've reached the end of the user tag.
-                    break;
-                }
-                continue;
-            }
-            if (XML_TAG_LEDGER.equals(tagName)) {
-                if (curUser == UserHandle.USER_NULL) {
-                    continue;
-                }
-                final Pair<String, Ledger> ledgerData =
-                        readLedgerFromXml(parser, installedPackages, endTimeCutoff);
-                if (ledgerData == null) {
-                    continue;
-                }
-                final Ledger ledger = ledgerData.second;
-                if (ledger != null) {
-                    mLedgers.add(curUser, ledgerData.first, ledger);
-                    final Ledger.Transaction transaction = ledger.getEarliestTransaction();
-                    if (transaction != null) {
-                        earliestEndTime = Math.min(earliestEndTime, transaction.endTimeMs);
-                    }
-                }
-            } else {
-                Slog.e(TAG, "Unknown tag: " + tagName);
-            }
-        }
-
-        return earliestEndTime;
-    }
-
-    /**
-     * @param parser Xml parser at the beginning of a {@link #XML_TAG_PERIOD_REPORT} tag. The next
-     *               "parser.next()" call will take the parser into the body of the report tag.
-     * @return Newly instantiated Report holding all the information we just read out of the xml tag
-     */
-    @NonNull
-    private static Analyst.Report readReportFromXml(TypedXmlPullParser parser)
-            throws XmlPullParserException, IOException {
-        final Analyst.Report report = new Analyst.Report();
-
-        report.cumulativeBatteryDischarge = parser.getAttributeInt(null, XML_ATTR_PR_DISCHARGE);
-        report.currentBatteryLevel = parser.getAttributeInt(null, XML_ATTR_PR_BATTERY_LEVEL);
-        report.cumulativeProfit = parser.getAttributeLong(null, XML_ATTR_PR_PROFIT);
-        report.numProfitableActions = parser.getAttributeInt(null, XML_ATTR_PR_NUM_PROFIT);
-        report.cumulativeLoss = parser.getAttributeLong(null, XML_ATTR_PR_LOSS);
-        report.numUnprofitableActions = parser.getAttributeInt(null, XML_ATTR_PR_NUM_LOSS);
-        report.cumulativeRewards = parser.getAttributeLong(null, XML_ATTR_PR_REWARDS);
-        report.numRewards = parser.getAttributeInt(null, XML_ATTR_PR_NUM_REWARDS);
-        report.cumulativePositiveRegulations =
-                parser.getAttributeLong(null, XML_ATTR_PR_POS_REGULATIONS);
-        report.numPositiveRegulations =
-                parser.getAttributeInt(null, XML_ATTR_PR_NUM_POS_REGULATIONS);
-        report.cumulativeNegativeRegulations =
-                parser.getAttributeLong(null, XML_ATTR_PR_NEG_REGULATIONS);
-        report.numNegativeRegulations =
-                parser.getAttributeInt(null, XML_ATTR_PR_NUM_NEG_REGULATIONS);
-        report.screenOffDurationMs =
-                parser.getAttributeLong(null, XML_ATTR_PR_SCREEN_OFF_DURATION_MS, 0);
-        report.screenOffDischargeMah =
-                parser.getAttributeLong(null, XML_ATTR_PR_SCREEN_OFF_DISCHARGE_MAH, 0);
-
-        return report;
-    }
-
-    /**
-     * @param parser Xml parser at the beginning of a {@value #XML_TAG_REWARD_BUCKET} tag. The next
-     *               "parser.next()" call will take the parser into the body of the tag.
-     * @return Newly instantiated {@link Ledger.RewardBucket} holding all the information we just
-     * read out of the xml tag.
-     */
-    @Nullable
-    private static Ledger.RewardBucket readRewardBucketFromXml(TypedXmlPullParser parser)
-            throws XmlPullParserException, IOException {
-
-        final Ledger.RewardBucket rewardBucket = new Ledger.RewardBucket();
-
-        rewardBucket.startTimeMs = parser.getAttributeLong(null, XML_ATTR_START_TIME);
-
-        for (int eventType = parser.next(); eventType != XmlPullParser.END_DOCUMENT;
-                eventType = parser.next()) {
-            final String tagName = parser.getName();
-            if (eventType == XmlPullParser.END_TAG) {
-                if (XML_TAG_REWARD_BUCKET.equals(tagName)) {
-                    // We've reached the end of the rewardBucket tag.
-                    break;
-                }
-                continue;
-            }
-            if (eventType != XmlPullParser.START_TAG || !XML_ATTR_DELTA.equals(tagName)) {
-                // Expecting only delta tags.
-                Slog.e(TAG, "Unexpected event: (" + eventType + ") " + tagName);
-                return null;
-            }
-
-            final int eventId = parser.getAttributeInt(null, XML_ATTR_EVENT_ID);
-            final long delta = parser.getAttributeLong(null, XML_ATTR_DELTA);
-            rewardBucket.cumulativeDelta.put(eventId, delta);
-        }
-
-        return rewardBucket;
-    }
-
-    private void scheduleCleanup(long earliestEndTime) {
-        if (earliestEndTime == Long.MAX_VALUE) {
-            return;
-        }
-        // This is just cleanup to manage memory. We don't need to do it too often or at the exact
-        // intended real time, so the delay that comes from using the Handler (and is limited
-        // to uptime) should be fine.
-        final long delayMs = Math.max(HOUR_IN_MILLIS,
-                earliestEndTime + MAX_TRANSACTION_AGE_MS - System.currentTimeMillis());
-        TareHandlerThread.getHandler().postDelayed(mCleanRunnable, delayMs);
-    }
-
-    private void writeState() {
-        synchronized (mIrs.getLock()) {
-            TareHandlerThread.getHandler().removeCallbacks(mWriteRunnable);
-            // Remove mCleanRunnable callbacks since we're going to clean up the ledgers before
-            // writing anyway.
-            TareHandlerThread.getHandler().removeCallbacks(mCleanRunnable);
-            if (mIrs.getEnabledMode() == ENABLED_MODE_OFF) {
-                // If it's no longer enabled, we would have cleared all the data in memory and would
-                // accidentally write an empty file, thus deleting all the history.
-                return;
-            }
-            long earliestStoredEndTime = Long.MAX_VALUE;
-            try (FileOutputStream fos = mStateFile.startWrite()) {
-                TypedXmlSerializer out = Xml.resolveSerializer(fos);
-                out.startDocument(null, true);
-
-                out.startTag(null, XML_TAG_TARE);
-                out.attributeInt(null, XML_ATTR_VERSION, STATE_FILE_VERSION);
-
-                out.startTag(null, XML_TAG_HIGH_LEVEL_STATE);
-                out.attributeLong(null, XML_ATTR_LAST_RECLAMATION_TIME, mLastReclamationTime);
-                out.attributeLong(null,
-                        XML_ATTR_LAST_STOCK_RECALCULATION_TIME, mLastStockRecalculationTime);
-                out.attributeLong(null, XML_ATTR_TIME_SINCE_FIRST_SETUP_MS,
-                        mLoadedTimeSinceFirstSetup + SystemClock.elapsedRealtime());
-                out.attributeLong(null, XML_ATTR_CONSUMPTION_LIMIT, mSatiatedConsumptionLimit);
-                out.attributeLong(null, XML_ATTR_REMAINING_CONSUMABLE_CAKES,
-                        mRemainingConsumableCakes);
-                out.endTag(null, XML_TAG_HIGH_LEVEL_STATE);
-
-                for (int uIdx = mLedgers.numMaps() - 1; uIdx >= 0; --uIdx) {
-                    final int userId = mLedgers.keyAt(uIdx);
-                    earliestStoredEndTime = Math.min(earliestStoredEndTime,
-                            writeUserLocked(out, userId));
-                }
-
-                List<Analyst.Report> reports = mAnalyst.getReports();
-                for (int i = 0, size = reports.size(); i < size; ++i) {
-                    writeReport(out, reports.get(i));
-                }
-
-                out.endTag(null, XML_TAG_TARE);
-
-                out.endDocument();
-                mStateFile.finishWrite(fos);
-            } catch (IOException e) {
-                Slog.e(TAG, "Error writing state to disk", e);
-            }
-            scheduleCleanup(earliestStoredEndTime);
-        }
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    private long writeUserLocked(@NonNull TypedXmlSerializer out, final int userId)
-            throws IOException {
-        final int uIdx = mLedgers.indexOfKey(userId);
-        long earliestStoredEndTime = Long.MAX_VALUE;
-
-        out.startTag(null, XML_TAG_USER);
-        out.attributeInt(null, XML_ATTR_USER_ID, userId);
-        out.attributeLong(null, XML_ATTR_TIME_SINCE_FIRST_SETUP_MS,
-                mRealtimeSinceUsersAddedOffsets.get(userId, mLoadedTimeSinceFirstSetup)
-                        + SystemClock.elapsedRealtime());
-        for (int pIdx = mLedgers.numElementsForKey(userId) - 1; pIdx >= 0; --pIdx) {
-            final String pkgName = mLedgers.keyAt(uIdx, pIdx);
-            final Ledger ledger = mLedgers.get(userId, pkgName);
-            // Remove old transactions so we don't waste space storing them.
-            ledger.removeOldTransactions(MAX_TRANSACTION_AGE_MS);
-
-            out.startTag(null, XML_TAG_LEDGER);
-            out.attribute(null, XML_ATTR_PACKAGE_NAME, pkgName);
-            out.attributeLong(null,
-                    XML_ATTR_CURRENT_BALANCE, ledger.getCurrentBalance());
-
-            final List<Ledger.Transaction> transactions = ledger.getTransactions();
-            for (int t = 0; t < transactions.size(); ++t) {
-                Ledger.Transaction transaction = transactions.get(t);
-                if (t == 0) {
-                    earliestStoredEndTime = Math.min(earliestStoredEndTime, transaction.endTimeMs);
-                }
-                writeTransaction(out, transaction);
-            }
-
-            final List<Ledger.RewardBucket> rewardBuckets = ledger.getRewardBuckets();
-            for (int r = 0; r < rewardBuckets.size(); ++r) {
-                writeRewardBucket(out, rewardBuckets.get(r));
-            }
-            out.endTag(null, XML_TAG_LEDGER);
-        }
-        out.endTag(null, XML_TAG_USER);
-
-        return earliestStoredEndTime;
-    }
-
-    private static void writeTransaction(@NonNull TypedXmlSerializer out,
-            @NonNull Ledger.Transaction transaction) throws IOException {
-        out.startTag(null, XML_TAG_TRANSACTION);
-        out.attributeLong(null, XML_ATTR_START_TIME, transaction.startTimeMs);
-        out.attributeLong(null, XML_ATTR_END_TIME, transaction.endTimeMs);
-        out.attributeInt(null, XML_ATTR_EVENT_ID, transaction.eventId);
-        if (transaction.tag != null) {
-            out.attribute(null, XML_ATTR_TAG, transaction.tag);
-        }
-        out.attributeLong(null, XML_ATTR_DELTA, transaction.delta);
-        out.attributeLong(null, XML_ATTR_CTP, transaction.ctp);
-        out.endTag(null, XML_TAG_TRANSACTION);
-    }
-
-    private static void writeRewardBucket(@NonNull TypedXmlSerializer out,
-            @NonNull Ledger.RewardBucket rewardBucket) throws IOException {
-        final int numEvents = rewardBucket.cumulativeDelta.size();
-        if (numEvents == 0) {
-            return;
-        }
-        out.startTag(null, XML_TAG_REWARD_BUCKET);
-        out.attributeLong(null, XML_ATTR_START_TIME, rewardBucket.startTimeMs);
-        for (int i = 0; i < numEvents; ++i) {
-            out.startTag(null, XML_ATTR_DELTA);
-            out.attributeInt(null, XML_ATTR_EVENT_ID, rewardBucket.cumulativeDelta.keyAt(i));
-            out.attributeLong(null, XML_ATTR_DELTA, rewardBucket.cumulativeDelta.valueAt(i));
-            out.endTag(null, XML_ATTR_DELTA);
-        }
-        out.endTag(null, XML_TAG_REWARD_BUCKET);
-    }
-
-    private static void writeReport(@NonNull TypedXmlSerializer out,
-            @NonNull Analyst.Report report) throws IOException {
-        out.startTag(null, XML_TAG_PERIOD_REPORT);
-        out.attributeInt(null, XML_ATTR_PR_DISCHARGE, report.cumulativeBatteryDischarge);
-        out.attributeInt(null, XML_ATTR_PR_BATTERY_LEVEL, report.currentBatteryLevel);
-        out.attributeLong(null, XML_ATTR_PR_PROFIT, report.cumulativeProfit);
-        out.attributeInt(null, XML_ATTR_PR_NUM_PROFIT, report.numProfitableActions);
-        out.attributeLong(null, XML_ATTR_PR_LOSS, report.cumulativeLoss);
-        out.attributeInt(null, XML_ATTR_PR_NUM_LOSS, report.numUnprofitableActions);
-        out.attributeLong(null, XML_ATTR_PR_REWARDS, report.cumulativeRewards);
-        out.attributeInt(null, XML_ATTR_PR_NUM_REWARDS, report.numRewards);
-        out.attributeLong(null, XML_ATTR_PR_POS_REGULATIONS, report.cumulativePositiveRegulations);
-        out.attributeInt(null, XML_ATTR_PR_NUM_POS_REGULATIONS, report.numPositiveRegulations);
-        out.attributeLong(null, XML_ATTR_PR_NEG_REGULATIONS, report.cumulativeNegativeRegulations);
-        out.attributeInt(null, XML_ATTR_PR_NUM_NEG_REGULATIONS, report.numNegativeRegulations);
-        out.attributeLong(null, XML_ATTR_PR_SCREEN_OFF_DURATION_MS, report.screenOffDurationMs);
-        out.attributeLong(null, XML_ATTR_PR_SCREEN_OFF_DISCHARGE_MAH, report.screenOffDischargeMah);
-        out.endTag(null, XML_TAG_PERIOD_REPORT);
-    }
-
-    @GuardedBy("mIrs.getLock()")
-    void dumpLocked(IndentingPrintWriter pw, boolean dumpAll) {
-        pw.println("Ledgers:");
-        pw.increaseIndent();
-        mLedgers.forEach((userId, pkgName, ledger) -> {
-            pw.print(appToString(userId, pkgName));
-            if (mIrs.isSystem(userId, pkgName)) {
-                pw.print(" (system)");
-            }
-            pw.println();
-            pw.increaseIndent();
-            ledger.dump(pw, dumpAll ? Integer.MAX_VALUE : MAX_NUM_TRANSACTION_DUMP);
-            pw.decreaseIndent();
-        });
-        pw.decreaseIndent();
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/TEST_MAPPING b/apex/jobscheduler/service/java/com/android/server/tare/TEST_MAPPING
deleted file mode 100644
index e194b8d..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/TEST_MAPPING
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-    "presubmit": [
-        {
-            "name": "FrameworksMockingServicesTests",
-            "options": [
-                {"include-filter": "com.android.server.tare"},
-                {"exclude-annotation": "androidx.test.filters.FlakyTest"}
-            ]
-        },
-        {
-            "name": "FrameworksServicesTests",
-            "options": [
-                {"include-filter": "com.android.server.tare"},
-                {"exclude-annotation": "androidx.test.filters.FlakyTest"}
-            ]
-        }
-    ],
-    "postsubmit": [
-        {
-            "name": "FrameworksMockingServicesTests",
-            "options": [
-                {"include-filter": "com.android.server.tare"}
-            ]
-        },
-        {
-            "name": "FrameworksServicesTests",
-            "options": [
-                {"include-filter": "com.android.server.tare"}
-            ]
-        }
-    ]
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/TareHandlerThread.java b/apex/jobscheduler/service/java/com/android/server/tare/TareHandlerThread.java
deleted file mode 100644
index 65ef8bf..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/TareHandlerThread.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import android.os.Handler;
-import android.os.HandlerExecutor;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Trace;
-
-import java.util.concurrent.Executor;
-
-/**
- * Singleton thread for all of TARE.
- *
- * @see com.android.internal.os.BackgroundThread
- */
-final class TareHandlerThread extends HandlerThread {
-
-    private static TareHandlerThread sInstance;
-    private static Executor sHandlerExecutor;
-    private static Handler sHandler;
-
-    private TareHandlerThread() {
-        super("tare");
-    }
-
-    private static void ensureThreadLocked() {
-        if (sInstance == null) {
-            sInstance = new TareHandlerThread();
-            sInstance.start();
-            final Looper looper = sInstance.getLooper();
-            looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
-            sHandler = new Handler(sInstance.getLooper());
-            sHandlerExecutor = new HandlerExecutor(sHandler);
-        }
-    }
-
-    static TareHandlerThread get() {
-        synchronized (TareHandlerThread.class) {
-            ensureThreadLocked();
-        }
-        return sInstance;
-    }
-
-    /** Returns the singleton handler executor for TareHandlerThread */
-    public static Executor getExecutor() {
-        synchronized (TareHandlerThread.class) {
-            ensureThreadLocked();
-            return sHandlerExecutor;
-        }
-    }
-
-    /** Returns the singleton handler for TareHandlerThread. */
-    public static Handler getHandler() {
-        synchronized (TareHandlerThread.class) {
-            ensureThreadLocked();
-        }
-        return sHandler;
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/TareShellCommand.java b/apex/jobscheduler/service/java/com/android/server/tare/TareShellCommand.java
deleted file mode 100644
index 5e380b40..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/TareShellCommand.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.content.pm.PackageManager;
-import android.os.Binder;
-
-import com.android.modules.utils.BasicShellCommandHandler;
-
-import java.io.PrintWriter;
-
-/**
- * Shell command handler for TARE.
- */
-public class TareShellCommand extends BasicShellCommandHandler {
-    static final int COMMAND_ERROR = -1;
-    static final int COMMAND_SUCCESS = 0;
-
-    private final InternalResourceService mIrs;
-
-    public TareShellCommand(@NonNull InternalResourceService irs) {
-        mIrs = irs;
-    }
-
-    @Override
-    public int onCommand(String cmd) {
-        final PrintWriter pw = getOutPrintWriter();
-        try {
-            switch (cmd != null ? cmd : "") {
-                case "clear-vip":
-                    return runClearVip(pw);
-                case "set-vip":
-                    return runSetVip(pw);
-                default:
-                    return handleDefaultCommands(cmd);
-            }
-        } catch (Exception e) {
-            pw.println("Exception: " + e);
-        }
-        return COMMAND_ERROR;
-    }
-
-    @Override
-    public void onHelp() {
-        final PrintWriter pw = getOutPrintWriter();
-
-        pw.println("TARE commands:");
-        pw.println("  help");
-        pw.println("    Print this help text.");
-        pw.println("  clear-vip");
-        pw.println("    Clears all VIP settings resulting from previous calls using `set-vip` and");
-        pw.println("    resets them all to default.");
-        pw.println("  set-vip <USER_ID> <PACKAGE> <true|false|default>");
-        pw.println("    Designate the app as a Very Important Package or not. A VIP is allowed to");
-        pw.println("    do as much work as it wants, regardless of TARE state.");
-        pw.println("    The user ID must be an explicit user ID. USER_ALL, CURRENT, etc. are not");
-        pw.println("    supported.");
-        pw.println();
-    }
-
-    private void checkPermission(@NonNull String operation) throws Exception {
-        final int perm = mIrs.getContext()
-                .checkCallingOrSelfPermission(Manifest.permission.CHANGE_APP_IDLE_STATE);
-        if (perm != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("Uid " + Binder.getCallingUid()
-                    + " not permitted to " + operation);
-        }
-    }
-
-    private int runClearVip(@NonNull PrintWriter pw) throws Exception {
-        checkPermission("clear vip");
-
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            return mIrs.executeClearVip(pw);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    private int runSetVip(@NonNull PrintWriter pw) throws Exception {
-        checkPermission("modify vip");
-
-        final int userId = Integer.parseInt(getNextArgRequired());
-        final String pkgName = getNextArgRequired();
-        final String vipState = getNextArgRequired();
-        final Boolean isVip = "default".equals(vipState) ? null : Boolean.valueOf(vipState);
-
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            return mIrs.executeSetVip(pw, userId, pkgName, isVip);
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java b/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java
deleted file mode 100644
index aa4c75a..0000000
--- a/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static android.app.tare.EconomyManager.CAKE_IN_ARC;
-
-import android.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.time.Clock;
-
-class TareUtils {
-    @VisibleForTesting
-    static Clock sSystemClock = Clock.systemUTC();
-
-    static long getCurrentTimeMillis() {
-        return sSystemClock.millis();
-    }
-
-    static int cakeToArc(long cakes) {
-        return (int) (cakes / CAKE_IN_ARC);
-    }
-
-    @NonNull
-    static String cakeToString(long cakes) {
-        if (cakes == 0) {
-            return "0 ARCs";
-        }
-        final long sub = cakes % CAKE_IN_ARC;
-        final long arcs = cakeToArc(cakes);
-        if (arcs == 0) {
-            return sub == 1
-                    ? sub + " cake"
-                    : sub + " cakes";
-        }
-        StringBuilder sb = new StringBuilder();
-        sb.append(arcs);
-        if (sub != 0) {
-            sb.append(".").append(String.format("%03d", Math.abs(sub) / (CAKE_IN_ARC / 1000)));
-        }
-        sb.append(" ARC");
-        if (arcs != 1 || sub != 0) {
-            sb.append("s");
-        }
-        return sb.toString();
-    }
-
-    /** Returns a standardized format for printing userId+pkgName combinations. */
-    @NonNull
-    static String appToString(int userId, String pkgName) {
-        return "<" + userId + ">" + pkgName;
-    }
-}
diff --git a/api/Android.bp b/api/Android.bp
index 010a2a5..3fa9c60 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -382,6 +382,18 @@
     ],
 }
 
+soong_config_module_type {
+    name: "non_updatable_exportable_droidstubs",
+    module_type: "droidstubs",
+    config_namespace: "ANDROID",
+    bool_variables: [
+        "release_hidden_api_exportable_stubs",
+    ],
+    properties: [
+        "dists",
+    ],
+}
+
 // We resolve dependencies on APIs in modules by depending on a prebuilt of the whole
 // platform (sdk_system_current_android). That prebuilt does not include module-lib APIs,
 // so use the prebuilt module-lib stubs for modules that export module-lib stubs that the
diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp
index c1add03..1b1bc6b 100644
--- a/api/StubLibraries.bp
+++ b/api/StubLibraries.bp
@@ -27,7 +27,12 @@
 // These modules provide source files for the stub libraries
 /////////////////////////////////////////////////////////////////////
 
-droidstubs {
+soong_config_module_type_import {
+    from: "frameworks/base/api/Android.bp",
+    module_types: ["non_updatable_exportable_droidstubs"],
+}
+
+non_updatable_exportable_droidstubs {
     name: "api-stubs-docs-non-updatable",
     defaults: [
         "android-non-updatable-stubs-defaults",
@@ -54,15 +59,35 @@
             targets: ["sdk"],
             dir: "apistubs/android/public/api",
             dest: "android-non-updatable.txt",
-            tag: ".api.txt",
         },
         {
             targets: ["sdk"],
             dir: "apistubs/android/public/api",
             dest: "android-non-updatable-removed.txt",
-            tag: ".removed-api.txt",
         },
     ],
+    soong_config_variables: {
+        release_hidden_api_exportable_stubs: {
+            dists: [
+                {
+                    tag: ".exportable.api.txt",
+                },
+                {
+                    tag: ".exportable.removed-api.txt",
+                },
+            ],
+            conditions_default: {
+                dists: [
+                    {
+                        tag: ".api.txt",
+                    },
+                    {
+                        tag: ".removed-api.txt",
+                    },
+                ],
+            },
+        },
+    },
     api_surface: "public",
 }
 
@@ -86,7 +111,7 @@
         "\\)",
 ]
 
-droidstubs {
+non_updatable_exportable_droidstubs {
     name: "system-api-stubs-docs-non-updatable",
     defaults: [
         "android-non-updatable-stubs-defaults",
@@ -114,19 +139,39 @@
             targets: ["sdk"],
             dir: "apistubs/android/system/api",
             dest: "android-non-updatable.txt",
-            tag: ".api.txt",
         },
         {
             targets: ["sdk"],
             dir: "apistubs/android/system/api",
             dest: "android-non-updatable-removed.txt",
-            tag: ".removed-api.txt",
         },
     ],
+    soong_config_variables: {
+        release_hidden_api_exportable_stubs: {
+            dists: [
+                {
+                    tag: ".exportable.api.txt",
+                },
+                {
+                    tag: ".exportable.removed-api.txt",
+                },
+            ],
+            conditions_default: {
+                dists: [
+                    {
+                        tag: ".api.txt",
+                    },
+                    {
+                        tag: ".removed-api.txt",
+                    },
+                ],
+            },
+        },
+    },
     api_surface: "system",
 }
 
-droidstubs {
+non_updatable_exportable_droidstubs {
     name: "test-api-stubs-docs-non-updatable",
     defaults: [
         "android-non-updatable-stubs-defaults",
@@ -149,31 +194,61 @@
             targets: ["sdk"],
             dir: "apistubs/android/test/api",
             dest: "android.txt",
-            tag: ".api.txt",
         },
         {
             targets: ["sdk"],
             dir: "apistubs/android/test/api",
             dest: "removed.txt",
-            tag: ".removed-api.txt",
         },
         {
             targets: ["sdk"],
             dir: "apistubs/android/test/api",
             dest: "android-non-updatable.txt",
-            tag: ".api.txt",
         },
         {
             targets: ["sdk"],
             dir: "apistubs/android/test/api",
             dest: "android-non-updatable-removed.txt",
-            tag: ".removed-api.txt",
         },
     ],
+    soong_config_variables: {
+        release_hidden_api_exportable_stubs: {
+            dists: [
+                {
+                    tag: ".exportable.api.txt",
+                },
+                {
+                    tag: ".exportable.removed-api.txt",
+                },
+                {
+                    tag: ".exportable.api.txt",
+                },
+                {
+                    tag: ".exportable.removed-api.txt",
+                },
+            ],
+            conditions_default: {
+                dists: [
+                    {
+                        tag: ".api.txt",
+                    },
+                    {
+                        tag: ".removed-api.txt",
+                    },
+                    {
+                        tag: ".api.txt",
+                    },
+                    {
+                        tag: ".removed-api.txt",
+                    },
+                ],
+            },
+        },
+    },
     api_surface: "test",
 }
 
-droidstubs {
+non_updatable_exportable_droidstubs {
     name: "module-lib-api-stubs-docs-non-updatable",
     defaults: [
         "android-non-updatable-stubs-defaults",
@@ -201,15 +276,35 @@
             targets: ["sdk"],
             dir: "apistubs/android/module-lib/api",
             dest: "android-non-updatable.txt",
-            tag: ".api.txt",
         },
         {
             targets: ["sdk"],
             dir: "apistubs/android/module-lib/api",
             dest: "android-non-updatable-removed.txt",
-            tag: ".removed-api.txt",
         },
     ],
+    soong_config_variables: {
+        release_hidden_api_exportable_stubs: {
+            dists: [
+                {
+                    tag: ".exportable.api.txt",
+                },
+                {
+                    tag: ".exportable.removed-api.txt",
+                },
+            ],
+            conditions_default: {
+                dists: [
+                    {
+                        tag: ".api.txt",
+                    },
+                    {
+                        tag: ".removed-api.txt",
+                    },
+                ],
+            },
+        },
+    },
     api_surface: "module-lib",
 }
 
diff --git a/api/coverage/tools/ExtractFlaggedApis.kt b/api/coverage/tools/ExtractFlaggedApis.kt
index caa1929..d5adfd0 100644
--- a/api/coverage/tools/ExtractFlaggedApis.kt
+++ b/api/coverage/tools/ExtractFlaggedApis.kt
@@ -16,51 +16,69 @@
 
 package android.platform.coverage
 
+import com.android.tools.metalava.model.ClassItem
+import com.android.tools.metalava.model.MethodItem
 import com.android.tools.metalava.model.text.ApiFile
 import java.io.File
 import java.io.FileWriter
 
 /** Usage: extract-flagged-apis <api text file> <output .pb file> */
 fun main(args: Array<String>) {
-    var cb = ApiFile.parseApi(listOf(File(args[0])))
-    var builder = FlagApiMap.newBuilder()
+    val cb = ApiFile.parseApi(listOf(File(args[0])))
+    val builder = FlagApiMap.newBuilder()
     for (pkg in cb.getPackages().packages) {
-        var packageName = pkg.qualifiedName()
+        val packageName = pkg.qualifiedName()
         pkg.allClasses()
             .filter { it.methods().size > 0 }
             .forEach {
-                for (method in it.methods()) {
-                    val flagValue =
-                        method.modifiers
-                            .findAnnotation("android.annotation.FlaggedApi")
-                            ?.findAttribute("value")
-                            ?.value
-                            ?.value()
-                    if (flagValue != null && flagValue is String) {
-                        var api =
-                            JavaMethod.newBuilder()
-                                .setPackageName(packageName)
-                                .setClassName(it.fullName())
-                                .setMethodName(method.name())
-                        for (param in method.parameters()) {
-                            api.addParameters(param.type().toTypeString())
-                        }
-                        if (builder.containsFlagToApi(flagValue)) {
-                            var updatedApis =
-                                builder
-                                    .getFlagToApiOrThrow(flagValue)
-                                    .toBuilder()
-                                    .addJavaMethods(api)
-                                    .build()
-                            builder.putFlagToApi(flagValue, updatedApis)
-                        } else {
-                            var apis = FlaggedApis.newBuilder().addJavaMethods(api).build()
-                            builder.putFlagToApi(flagValue, apis)
-                        }
-                    }
-                }
+                extractFlaggedApisFromClass(it, it.methods(), packageName, builder)
+                extractFlaggedApisFromClass(it, it.constructors(), packageName, builder)
             }
     }
     val flagApiMap = builder.build()
     FileWriter(args[1]).use { it.write(flagApiMap.toString()) }
 }
+
+fun extractFlaggedApisFromClass(
+    classItem: ClassItem,
+    methods: List<MethodItem>,
+    packageName: String,
+    builder: FlagApiMap.Builder
+) {
+    val classFlag =
+        classItem.modifiers
+            .findAnnotation("android.annotation.FlaggedApi")
+            ?.findAttribute("value")
+            ?.value
+            ?.value() as? String
+    for (method in methods) {
+        val methodFlag =
+            method.modifiers
+                .findAnnotation("android.annotation.FlaggedApi")
+                ?.findAttribute("value")
+                ?.value
+                ?.value() as? String
+                ?: classFlag
+        val api =
+            JavaMethod.newBuilder()
+                .setPackageName(packageName)
+                .setClassName(classItem.fullName())
+                .setMethodName(method.name())
+        for (param in method.parameters()) {
+            api.addParameters(param.type().toTypeString())
+        }
+        if (methodFlag != null) {
+            addFlaggedApi(builder, api, methodFlag)
+        }
+    }
+}
+
+fun addFlaggedApi(builder: FlagApiMap.Builder, api: JavaMethod.Builder, flag: String) {
+    if (builder.containsFlagToApi(flag)) {
+        val updatedApis = builder.getFlagToApiOrThrow(flag).toBuilder().addJavaMethods(api).build()
+        builder.putFlagToApi(flag, updatedApis)
+    } else {
+        val apis = FlaggedApis.newBuilder().addJavaMethods(api).build()
+        builder.putFlagToApi(flag, apis)
+    }
+}
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 0d3dc49..6310d32 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -1280,6 +1280,24 @@
                 return "START_PACKAGE_RESTORE";
             case BackupManagerMonitor.LOG_EVENT_ID_AGENT_FAILURE:
                 return "AGENT_FAILURE";
+            case BackupManagerMonitor.LOG_EVENT_ID_RESTORE_AT_INSTALL_INVOKED:
+                return "RESTORE_AT_INSTALL_INVOKED";
+            case BackupManagerMonitor.LOG_EVENT_ID_SKIP_RESTORE_AT_INSTALL:
+                return "SKIP_RESTORE_AT_INSTALL";
+            case BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_ACCEPTED_FOR_RESTORE:
+                return "PACKAGE_ACCEPTED_FOR_RESTORE";
+            case BackupManagerMonitor.LOG_EVENT_ID_RESTORE_DATA_DOES_NOT_BELONG_TO_PACKAGE:
+                return "RESTORE_DATA_DOES_NOT_BELONG_TO_PACKAGE";
+            case BackupManagerMonitor.LOG_EVENT_ID_UNABLE_TO_CREATE_AGENT_FOR_RESTORE:
+                return "UNABLE_TO_CREATE_AGENT_FOR_RESTORE";
+            case BackupManagerMonitor.LOG_EVENT_ID_AGENT_CRASHED_BEFORE_RESTORE_DATA_IS_SENT:
+                return "AGENT_CRASHED_BEFORE_RESTORE_DATA_IS_SEN";
+            case BackupManagerMonitor.LOG_EVENT_ID_FAILED_TO_SEND_DATA_TO_AGENT_DURING_RESTORE:
+                return "FAILED_TO_SEND_DATA_TO_AGENT_DURING_RESTORE";
+            case BackupManagerMonitor.LOG_EVENT_ID_AGENT_FAILURE_DURING_RESTORE:
+                return "AGENT_FAILURE_DURING_RESTORE";
+            case BackupManagerMonitor.LOG_EVENT_ID_FAILED_TO_READ_DATA_FROM_TRANSPORT:
+                return "FAILED_TO_READ_DATA_FROM_TRANSPORT";
             default:
                 return "UNKNOWN_ID";
         }
diff --git a/cmds/incident_helper/OWNERS b/cmds/incident_helper/OWNERS
index cede4ea..29f44ab 100644
--- a/cmds/incident_helper/OWNERS
+++ b/cmds/incident_helper/OWNERS
@@ -1,3 +1,2 @@
 joeo@google.com
-kwekua@google.com
 yanmin@google.com
diff --git a/cmds/incidentd/src/PrivacyFilter.cpp b/cmds/incidentd/src/PrivacyFilter.cpp
index 0d427d1..b273fd4 100644
--- a/cmds/incidentd/src/PrivacyFilter.cpp
+++ b/cmds/incidentd/src/PrivacyFilter.cpp
@@ -195,7 +195,9 @@
         ProtoOutputStream proto(mEncodedBuffer);
 
         // Optimization when no strip happens.
-        if (mRestrictions == NULL || spec.RequireAll()) {
+        if (mRestrictions == NULL || spec.RequireAll()
+                // Do not iterate through fields if primitive data
+                || !mRestrictions->children /* != FieldDescriptor::TYPE_MESSAGE */) {
             if (spec.CheckPremission(mRestrictions)) {
                 mSize = mData->size();
             }
diff --git a/core/api/current.txt b/core/api/current.txt
index 1cfc025..b19c3ab 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -10147,17 +10147,17 @@
 
   public interface ComponentCallbacks {
     method public void onConfigurationChanged(@NonNull android.content.res.Configuration);
-    method public void onLowMemory();
+    method @Deprecated public void onLowMemory();
   }
 
   public interface ComponentCallbacks2 extends android.content.ComponentCallbacks {
     method public void onTrimMemory(int);
     field public static final int TRIM_MEMORY_BACKGROUND = 40; // 0x28
-    field public static final int TRIM_MEMORY_COMPLETE = 80; // 0x50
-    field public static final int TRIM_MEMORY_MODERATE = 60; // 0x3c
-    field public static final int TRIM_MEMORY_RUNNING_CRITICAL = 15; // 0xf
-    field public static final int TRIM_MEMORY_RUNNING_LOW = 10; // 0xa
-    field public static final int TRIM_MEMORY_RUNNING_MODERATE = 5; // 0x5
+    field @Deprecated public static final int TRIM_MEMORY_COMPLETE = 80; // 0x50
+    field @Deprecated public static final int TRIM_MEMORY_MODERATE = 60; // 0x3c
+    field @Deprecated public static final int TRIM_MEMORY_RUNNING_CRITICAL = 15; // 0xf
+    field @Deprecated public static final int TRIM_MEMORY_RUNNING_LOW = 10; // 0xa
+    field @Deprecated public static final int TRIM_MEMORY_RUNNING_MODERATE = 5; // 0x5
     field public static final int TRIM_MEMORY_UI_HIDDEN = 20; // 0x14
   }
 
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 501203e..b767c52 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -319,9 +319,8 @@
     field public static final String RECEIVE_DATA_ACTIVITY_CHANGE = "android.permission.RECEIVE_DATA_ACTIVITY_CHANGE";
     field public static final String RECEIVE_DEVICE_CUSTOMIZATION_READY = "android.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY";
     field public static final String RECEIVE_EMERGENCY_BROADCAST = "android.permission.RECEIVE_EMERGENCY_BROADCAST";
-    field @FlaggedApi("android.permission.flags.voice_activation_permission_apis") public static final String RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA = "android.permission.RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA";
     field @FlaggedApi("android.permission.flags.voice_activation_permission_apis") public static final String RECEIVE_SANDBOX_TRIGGER_AUDIO = "android.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO";
-    field @FlaggedApi("com.android.server.notification.flags.redact_otp_notifications_from_untrusted_listeners") public static final String RECEIVE_SENSITIVE_NOTIFICATIONS = "android.permission.RECEIVE_SENSITIVE_NOTIFICATIONS";
+    field @FlaggedApi("android.view.flags.sensitive_content_app_protection_api") public static final String RECEIVE_SENSITIVE_NOTIFICATIONS = "android.permission.RECEIVE_SENSITIVE_NOTIFICATIONS";
     field public static final String RECEIVE_WIFI_CREDENTIAL_CHANGE = "android.permission.RECEIVE_WIFI_CREDENTIAL_CHANGE";
     field public static final String RECORD_BACKGROUND_AUDIO = "android.permission.RECORD_BACKGROUND_AUDIO";
     field public static final String RECOVERY = "android.permission.RECOVERY";
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index ca5d3eb..f36aeab 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -486,12 +486,16 @@
   }
 
   public final class UiAutomation {
+    method public void addOverridePermissionState(int, @NonNull String, int);
+    method public void clearAllOverridePermissionStates();
+    method public void clearOverridePermissionStates(int);
     method public void destroy();
     method @NonNull public java.util.Set<java.lang.String> getAdoptedShellPermissions();
     method @Deprecated public boolean grantRuntimePermission(String, String, android.os.UserHandle);
     method public boolean injectInputEvent(@NonNull android.view.InputEvent, boolean, boolean);
     method public void injectInputEventToInputFilter(@NonNull android.view.InputEvent);
     method public boolean isNodeInCache(@NonNull android.view.accessibility.AccessibilityNodeInfo);
+    method public void removeOverridePermissionState(int, @NonNull String);
     method @Deprecated public boolean revokeRuntimePermission(String, String, android.os.UserHandle);
     method public void syncInputTransactions();
     method public void syncInputTransactions(boolean);
@@ -846,17 +850,6 @@
 
 }
 
-package android.app.tare {
-
-  public class EconomyManager {
-    method public int getEnabledMode();
-    field public static final int ENABLED_MODE_OFF = 0; // 0x0
-    field public static final int ENABLED_MODE_SHADOW = 2; // 0x2
-    field public static final String KEY_ENABLE_TARE_MODE = "enable_tare_mode";
-  }
-
-}
-
 package android.app.usage {
 
   public class StorageStatsManager {
@@ -3676,6 +3669,10 @@
     field public static final int FLAG_IS_ACCESSIBILITY_EVENT = 2048; // 0x800
   }
 
+  public final class PointerIcon implements android.os.Parcelable {
+    method @FlaggedApi("android.view.flags.enable_vector_cursors") public void setDrawNativeDropShadow(boolean);
+  }
+
   @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface RemotableViewMethod {
     method public abstract String asyncImpl() default "";
   }
diff --git a/core/java/Android.bp b/core/java/Android.bp
index db5888e..fae411d 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -582,7 +582,9 @@
     srcs: [
         "com/android/internal/protolog/ProtoLogImpl.java",
         "com/android/internal/protolog/ProtoLogViewerConfigReader.java",
-        ":perfetto_trace_javastream_protos",
+    ],
+    static_libs: [
+        "perfetto_trace_javastream_protos_jarjar",
     ],
 }
 
diff --git a/core/java/android/adaptiveauth/flags.aconfig b/core/java/android/adaptiveauth/flags.aconfig
index de4e607..b9cf29c 100644
--- a/core/java/android/adaptiveauth/flags.aconfig
+++ b/core/java/android/adaptiveauth/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.adaptiveauth"
+container: "system"
 
 flag {
   name: "enable_adaptive_auth"
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 8913d6d..3575545 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1082,6 +1082,8 @@
         public boolean managed;
         public boolean mallocInfo;
         public boolean runGc;
+        // compression format to dump bitmaps, null if no bitmaps to be dumped
+        public String dumpBitmaps;
         String path;
         ParcelFileDescriptor fd;
         RemoteCallback finishCallback;
@@ -1486,11 +1488,12 @@
         }
 
         @Override
-        public void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc, String path,
-                ParcelFileDescriptor fd, RemoteCallback finishCallback) {
+        public void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc, String dumpBitmaps,
+                String path, ParcelFileDescriptor fd, RemoteCallback finishCallback) {
             DumpHeapData dhd = new DumpHeapData();
             dhd.managed = managed;
             dhd.mallocInfo = mallocInfo;
+            dhd.dumpBitmaps = dumpBitmaps;
             dhd.runGc = runGc;
             dhd.path = path;
             try {
@@ -6859,6 +6862,9 @@
             System.runFinalization();
             System.gc();
         }
+        if (dhd.dumpBitmaps != null) {
+            Bitmap.dumpAll(dhd.dumpBitmaps);
+        }
         try (ParcelFileDescriptor fd = dhd.fd) {
             if (dhd.managed) {
                 Debug.dumpHprofData(dhd.path, fd.getFileDescriptor());
@@ -6886,6 +6892,9 @@
         if (dhd.finishCallback != null) {
             dhd.finishCallback.sendResult(null);
         }
+        if (dhd.dumpBitmaps != null) {
+            Bitmap.dumpAll(null); // clear dump
+        }
     }
 
     final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
@@ -6982,7 +6991,7 @@
                             }
                         } else {
                             // No package, perhaps it was removed?
-                            Slog.e(TAG, "Package [" + packages[i] + "] reported as REPLACED,"
+                            Slog.d(TAG, "Package [" + packages[i] + "] reported as REPLACED,"
                                     + " but missing application info. Assuming REMOVED.");
                             mPackages.remove(packages[i]);
                             mResourcePackages.remove(packages[i]);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 0ed25eb..7ae514a 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -18,7 +18,7 @@
 
 
 import static android.location.flags.Flags.FLAG_LOCATION_BYPASS;
-import static android.media.audio.Flags.foregroundAudioControl;
+import static android.media.audio.Flags.roForegroundAudioControl;
 import static android.permission.flags.Flags.FLAG_OP_ENABLE_MOBILE_DATA_BY_USER;
 import static android.view.contentprotection.flags.Flags.FLAG_CREATE_ACCESSIBILITY_OVERLAY_APP_OP_ENABLED;
 import static android.view.contentprotection.flags.Flags.FLAG_RAPID_CLEAR_NOTIFICATIONS_BY_LISTENER_APP_OP_ENABLED;
@@ -1502,12 +1502,10 @@
             AppProtoEnums.APP_OP_RECEIVE_SANDBOX_TRIGGER_AUDIO;
 
     /**
-     * Allows the privileged assistant app to receive the training data from the sandboxed hotword
-     * detection service.
+     * This op has been deprecated.
      *
-     * @hide
      */
-    public static final int OP_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA =
+    private static final int OP_DEPRECATED_3 =
             AppProtoEnums.APP_OP_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA;
 
     /**
@@ -1735,7 +1733,6 @@
             OPSTR_CAMERA_SANDBOXED,
             OPSTR_RECORD_AUDIO_SANDBOXED,
             OPSTR_RECEIVE_SANDBOX_TRIGGER_AUDIO,
-            OPSTR_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA,
             OPSTR_CREATE_ACCESSIBILITY_OVERLAY,
             OPSTR_MEDIA_ROUTING_CONTROL,
             OPSTR_ENABLE_MOBILE_DATA_BY_USER,
@@ -2395,13 +2392,10 @@
             "android:receive_sandbox_trigger_audio";
 
     /**
-     * Allows the privileged assistant app to receive training data from the sandboxed hotword
-     * detection service.
-     *
+     * App op has been deprecated.
      * @hide
      */
-    public static final String OPSTR_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA =
-            "android:RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA";
+    public static final String OPSTR_DEPRECATED_3 = "android:deprecated_3";
 
     /**
      * Creation of an overlay using accessibility services
@@ -2582,7 +2576,6 @@
             OP_CAPTURE_CONSENTLESS_BUGREPORT_ON_USERDEBUG_BUILD,
             OP_USE_FULL_SCREEN_INTENT,
             OP_RECEIVE_SANDBOX_TRIGGER_AUDIO,
-            OP_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA,
             OP_MEDIA_ROUTING_CONTROL,
             OP_READ_SYSTEM_GRAMMATICAL_GENDER,
             OP_RUN_BACKUP_JOBS,
@@ -3021,11 +3014,8 @@
                 "RECEIVE_SANDBOX_TRIGGER_AUDIO")
                 .setPermission(Manifest.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO)
                 .setDefaultMode(AppOpsManager.MODE_DEFAULT).build(),
-        new AppOpInfo.Builder(OP_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA,
-                OPSTR_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA,
-                "RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA")
-                .setPermission(Manifest.permission.RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA)
-                .setDefaultMode(AppOpsManager.MODE_DEFAULT).build(),
+        new AppOpInfo.Builder(OP_DEPRECATED_3, OPSTR_DEPRECATED_3, "DEPRECATED_3")
+                .setDefaultMode(AppOpsManager.MODE_IGNORED).build(),
         new AppOpInfo.Builder(OP_CREATE_ACCESSIBILITY_OVERLAY,
                 OPSTR_CREATE_ACCESSIBILITY_OVERLAY,
                 "CREATE_ACCESSIBILITY_OVERLAY")
@@ -3246,7 +3236,7 @@
      * @hide
      */
     public static @Mode int opToDefaultMode(int op) {
-        if (op == OP_TAKE_AUDIO_FOCUS && foregroundAudioControl()) {
+        if (op == OP_TAKE_AUDIO_FOCUS && roForegroundAudioControl()) {
             // when removing the flag, change the entry in sAppOpInfos for OP_TAKE_AUDIO_FOCUS
             return AppOpsManager.MODE_FOREGROUND;
         }
diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java
index 8daee58..f8a8f5d 100644
--- a/core/java/android/app/AppOpsManagerInternal.java
+++ b/core/java/android/app/AppOpsManagerInternal.java
@@ -53,9 +53,10 @@
          * @param superImpl The super implementation.
          * @return The app op check result.
          */
-        int checkOperation(int code, int uid, String packageName, @Nullable String attributionTag,
-                int virtualDeviceId, boolean raw, HexFunction<Integer, Integer, String, String,
-                Integer, Boolean, Integer> superImpl);
+        int checkOperation(int code, int uid, @Nullable String packageName,
+                @Nullable String attributionTag, int virtualDeviceId, boolean raw,
+                @NonNull HexFunction<Integer, Integer, String, String, Integer, Boolean, Integer>
+                        superImpl);
 
         /**
          * Allows overriding check audio operation behavior.
@@ -67,8 +68,8 @@
          * @param superImpl The super implementation.
          * @return The app op check result.
          */
-        int checkAudioOperation(int code, int usage, int uid, String packageName,
-                QuadFunction<Integer, Integer, Integer, String, Integer> superImpl);
+        int checkAudioOperation(int code, int usage, int uid, @Nullable String packageName,
+                @NonNull QuadFunction<Integer, Integer, Integer, String, Integer> superImpl);
 
         /**
          * Allows overriding note operation behavior.
@@ -125,7 +126,7 @@
          * @param superImpl The super implementation.
          * @return The app op note result.
          */
-        SyncNotedAppOp startOperation(IBinder token, int code, int uid,
+        SyncNotedAppOp startOperation(@NonNull IBinder token, int code, int uid,
                 @Nullable String packageName, @Nullable String attributionTag, int virtualDeviceId,
                 boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
                 @Nullable String message, boolean shouldCollectMessage,
@@ -152,8 +153,9 @@
          */
         SyncNotedAppOp startProxyOperation(@NonNull IBinder clientId, int code,
                 @NonNull AttributionSource attributionSource, boolean startIfModeDefault,
-                boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
-                boolean skipProxyOperation, @AttributionFlags int proxyAttributionFlags,
+                boolean shouldCollectAsyncNotedOp, @Nullable String message,
+                boolean shouldCollectMessage, boolean skipProxyOperation,
+                @AttributionFlags int proxyAttributionFlags,
                 @AttributionFlags int proxiedAttributionFlags, int attributionChainId,
                 @NonNull UndecFunction<IBinder, Integer, AttributionSource, Boolean,
                         Boolean, String, Boolean, Boolean, Integer, Integer, Integer,
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 716dee4..ee0225f 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -3114,6 +3114,14 @@
         if (mIsExplicitDeviceId) {
             return;
         }
+
+        if ((displayId == Display.DEFAULT_DISPLAY || displayId == Display.INVALID_DISPLAY)
+                && mDeviceId == DEVICE_ID_DEFAULT) {
+            // DEFAULT_DISPLAY & INVALID_DISPLAY are associated with default device.
+            // Return early avoiding instantiating VDM when it's not needed.
+            return;
+        }
+
         VirtualDeviceManager vdm = getSystemService(VirtualDeviceManager.class);
         if (vdm != null) {
             int deviceId = vdm.getDeviceIdForDisplayId(displayId);
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 84bc6ce..ffecd67 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -394,7 +394,7 @@
     oneway void getMimeTypeFilterAsync(in Uri uri, int userId, in RemoteCallback resultCallback);
     // Cause the specified process to dump the specified heap.
     boolean dumpHeap(in String process, int userId, boolean managed, boolean mallocInfo,
-            boolean runGc, in String path, in ParcelFileDescriptor fd,
+            boolean runGc, in String dumpBitmaps, in String path, in ParcelFileDescriptor fd,
             in RemoteCallback finishCallback);
     @UnsupportedAppUsage
     boolean isUserRunning(int userid, int flags);
@@ -970,4 +970,40 @@
      * time in the past.
      */
     long getUidLastIdleElapsedTime(int uid, in String callingPackage);
+
+    /**
+     * Adds permission to be overridden to the given state. Must be called from root user.
+     *
+     * @param originatingUid The UID of the instrumented app that initialized the override
+     * @param uid The UID of the app whose permission will be overridden
+     * @param permission The permission whose state will be overridden
+     * @param result The state to override the permission to
+     *
+     * @see PackageManager.PermissionResult
+     */
+    void addOverridePermissionState(int originatingUid, int uid, String permission, int result);
+
+    /**
+     * Removes overridden permission. Must be called from root user.
+     *
+     * @param originatingUid The UID of the instrumented app that initialized the override
+     * @param uid The UID of the app whose permission is overridden
+     * @param permission The permission whose state will no longer be overridden
+     */
+    void removeOverridePermissionState(int originatingUid, int uid, String permission);
+
+    /**
+     * Clears all overridden permissions for the given UID. Must be called from root user.
+     *
+     * @param originatingUid The UID of the instrumented app that initialized the override
+     * @param uid The UID of the app whose permissions will no longer be overridden
+     */
+    void clearOverridePermissionStates(int originatingUid, int uid);
+
+    /**
+     * Clears all overridden permissions on the device. Must be called from root user.
+     *
+     * @param originatingUid The UID of the instrumented app that initialized the override
+     */
+    void clearAllOverridePermissionStates(int originatingUid);
 }
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 08636ae..55ce90d 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -157,7 +157,6 @@
     ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
             int userId);
     boolean isTopActivityImmersive();
-    ActivityManager.TaskDescription getTaskDescription(int taskId);
     void reportAssistContextExtras(in IBinder assistToken, in Bundle extras,
             in AssistStructure structure, in AssistContent content, in Uri referrer);
 
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 251e4e8..a64261a 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -119,7 +119,8 @@
     void scheduleSuicide();
     void dispatchPackageBroadcast(int cmd, in String[] packages);
     void scheduleCrash(in String msg, int typeId, in Bundle extras);
-    void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc, in String path,
+    void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc,
+            in String dumpBitmaps, in String path,
             in ParcelFileDescriptor fd, in RemoteCallback finishCallback);
     void dumpActivity(in ParcelFileDescriptor fd, IBinder servicetoken, in String prefix,
             in String[] args);
diff --git a/core/java/android/app/IUiAutomationConnection.aidl b/core/java/android/app/IUiAutomationConnection.aidl
index 63cae63..69c3bd3 100644
--- a/core/java/android/app/IUiAutomationConnection.aidl
+++ b/core/java/android/app/IUiAutomationConnection.aidl
@@ -62,4 +62,8 @@
     void executeShellCommandWithStderr(String command, in ParcelFileDescriptor sink,
                 in ParcelFileDescriptor source, in ParcelFileDescriptor stderrSink);
     List<String> getAdoptedShellPermissions();
+    void addOverridePermissionState(int uid, String permission, int result);
+    void removeOverridePermissionState(int uid, String permission);
+    void clearOverridePermissionStates(int uid);
+    void clearAllOverridePermissionStates();
 }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index d7b9a2c..fe261be 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3807,6 +3807,13 @@
     }
 
     /**
+     * @hide
+     */
+    public void setTimeoutAfter(long timeout) {
+        mTimeout = timeout;
+    }
+
+    /**
      * Returns what icon should be shown for this notification if it is being displayed in a
      * Launcher that supports badging. Will be one of {@link #BADGE_ICON_NONE},
      * {@link #BADGE_ICON_SMALL}, or {@link #BADGE_ICON_LARGE}.
@@ -3910,6 +3917,13 @@
     /**
      * @hide
      */
+    public boolean hasAppProvidedWhen() {
+        return when != 0 && when != creationTime;
+    }
+
+    /**
+     * @hide
+     */
     @UnsupportedAppUsage
     public boolean isGroupSummary() {
         return mGroupKey != null && (flags & FLAG_GROUP_SUMMARY) != 0;
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 7c803eb..193c524 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -434,6 +434,40 @@
     /**
      * @hide
      */
+    public NotificationChannel copy() {
+        NotificationChannel copy = new NotificationChannel(mId, mName, mImportance);
+        copy.setDescription(mDesc);
+        copy.setBypassDnd(mBypassDnd);
+        copy.setLockscreenVisibility(mLockscreenVisibility);
+        copy.setSound(mSound, mAudioAttributes);
+        copy.setLightColor(mLightColor);
+        copy.enableLights(mLights);
+        copy.setVibrationPattern(mVibrationPattern);
+        if (Flags.notificationChannelVibrationEffectApi()) {
+            copy.setVibrationEffect(mVibrationEffect);
+        }
+        copy.lockFields(mUserLockedFields);
+        copy.setUserVisibleTaskShown(mUserVisibleTaskShown);
+        copy.enableVibration(mVibrationEnabled);
+        copy.setShowBadge(mShowBadge);
+        copy.setDeleted(mDeleted);
+        copy.setGroup(mGroup);
+        copy.setBlockable(mBlockableSystem);
+        copy.setAllowBubbles(mAllowBubbles);
+        copy.setOriginalImportance(mOriginalImportance);
+        copy.setConversationId(mParentId, mConversationId);
+        copy.setDemoted(mDemoted);
+        copy.setImportantConversation(mImportantConvo);
+        copy.setDeletedTimeMs(mDeletedTime);
+        copy.setImportanceLockedByCriticalDeviceFunction(mImportanceLockedDefaultApp);
+        copy.setLastNotificationUpdateTimeMs(mLastNotificationUpdateTimeMs);
+
+        return copy;
+    }
+
+    /**
+     * @hide
+     */
     @TestApi
     public void lockFields(int field) {
         mUserLockedFields |= field;
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index b0edc3d..348d4d8f 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -33,6 +33,7 @@
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -653,6 +654,81 @@
     }
 
     /**
+     * Adds permission to be overridden to the given state. UiAutomation must be connected to
+     * root user.
+     *
+     * @param uid The UID of the app whose permission will be overridden
+     * @param permission The permission whose state will be overridden
+     * @param result The state to override the permission to
+     *
+     * @see PackageManager#PERMISSION_GRANTED
+     * @see PackageManager#PERMISSION_DENIED
+     *
+     * @hide
+     */
+    @TestApi
+    @SuppressLint("UnflaggedApi")
+    public void addOverridePermissionState(int uid, @NonNull String permission,
+            @PackageManager.PermissionResult int result) {
+        try {
+            mUiAutomationConnection.addOverridePermissionState(uid, permission, result);
+        } catch (RemoteException re) {
+            re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Removes overridden permission. UiAutomation must be connected to root user.
+     *
+     * @param uid The UID of the app whose permission is overridden
+     * @param permission The permission whose state will no longer be overridden
+     *
+     * @hide
+     */
+    @TestApi
+    @SuppressLint("UnflaggedApi")
+    public void removeOverridePermissionState(int uid, @NonNull String permission) {
+        try {
+            mUiAutomationConnection.removeOverridePermissionState(uid, permission);
+        } catch (RemoteException re) {
+            re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Clears all overridden permissions for the given UID. UiAutomation must be connected to
+     * root user.
+     *
+     * @param uid The UID of the app whose permissions will no longer be overridden
+     *
+     * @hide
+     */
+    @TestApi
+    @SuppressLint("UnflaggedApi")
+    public void clearOverridePermissionStates(int uid) {
+        try {
+            mUiAutomationConnection.clearOverridePermissionStates(uid);
+        } catch (RemoteException re) {
+            re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Clears all overridden permissions on the device. UiAutomation must be connected to root user.
+     *
+     * @hide
+     */
+    @TestApi
+    @SuppressLint("UnflaggedApi")
+    public void clearAllOverridePermissionStates() {
+        try {
+            mUiAutomationConnection.clearAllOverridePermissionStates();
+        } catch (RemoteException re) {
+            re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Performs a global action. Such an action can be performed at any moment
      * regardless of the current application or user location in that application.
      * For example going back, going home, opening recents, etc.
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 33e260f..3c4bd9e 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -437,6 +437,71 @@
         }
     }
 
+    @Override
+    public void addOverridePermissionState(int uid, String permission, int result)
+            throws RemoteException {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            throwIfNotConnectedLocked();
+        }
+        final int callingUid = Binder.getCallingUid();
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            mActivityManager.addOverridePermissionState(callingUid, uid, permission, result);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void removeOverridePermissionState(int uid, String permission) throws RemoteException {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            throwIfNotConnectedLocked();
+        }
+        final int callingUid = Binder.getCallingUid();
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            mActivityManager.removeOverridePermissionState(callingUid, uid, permission);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void clearOverridePermissionStates(int uid) throws RemoteException {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            throwIfNotConnectedLocked();
+        }
+        final int callingUid = Binder.getCallingUid();
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            mActivityManager.clearOverridePermissionStates(callingUid, uid);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    @Override
+    public void clearAllOverridePermissionStates() throws RemoteException {
+        synchronized (mLock) {
+            throwIfCalledByNotTrustedUidLocked();
+            throwIfShutdownLocked();
+            throwIfNotConnectedLocked();
+        }
+        final int callingUid = Binder.getCallingUid();
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            mActivityManager.clearAllOverridePermissionStates(callingUid);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     public class Repeater implements Runnable {
         // Continuously read readFrom and write back to writeTo until EOF is encountered
         private final InputStream readFrom;
diff --git a/core/java/android/app/activity_manager.aconfig b/core/java/android/app/activity_manager.aconfig
index b9aa18c..e4425ca 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"
@@ -39,11 +40,3 @@
      description: "Add a new callback in Service to indicate a FGS has reached its timeout."
      bug: "317799821"
 }
-
-flag {
-    name: "bcast_event_timestamps"
-    is_exported: true
-    namespace: "backstage_power"
-    description: "Add APIs for clients to provide broadcast event trigger timestamps"
-    bug: "325136414"
-}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 411f7f7..ea6f45e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -10284,6 +10284,16 @@
      * get the list of app restrictions set by each admin via
      * {@link android.content.RestrictionsManager#getApplicationRestrictionsPerAdmin}.
      *
+     * <p>Starting from Android Version {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM},
+     * the device policy management role holder can also set app restrictions on any applications
+     * in the calling user, as well as the parent user of an organization-owned managed profile via
+     * the {@link DevicePolicyManager} instance returned by
+     * {@link #getParentProfileInstance(ComponentName)}. App restrictions set by the device policy
+     * management role holder are not returned by
+     * {@link UserManager#getApplicationRestrictions(String)}. The target application should use
+     * {@link android.content.RestrictionsManager#getApplicationRestrictionsPerAdmin} to retrieve
+     * them, alongside any app restrictions the profile or device owner might have set.
+     *
      * <p>NOTE: The method performs disk I/O and shouldn't be called on the main thread
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or
@@ -10299,11 +10309,14 @@
     @WorkerThread
     public void setApplicationRestrictions(@Nullable ComponentName admin, String packageName,
             Bundle settings) {
-        throwIfParentInstance("setApplicationRestrictions");
+        if (!Flags.dmrhCanSetAppRestriction()) {
+            throwIfParentInstance("setApplicationRestrictions");
+        }
+
         if (mService != null) {
             try {
                 mService.setApplicationRestrictions(admin, mContext.getPackageName(), packageName,
-                        settings);
+                        settings, mParentInstance);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -11704,11 +11717,14 @@
     @WorkerThread
     public @NonNull Bundle getApplicationRestrictions(
             @Nullable ComponentName admin, String packageName) {
-        throwIfParentInstance("getApplicationRestrictions");
+        if (!Flags.dmrhCanSetAppRestriction()) {
+            throwIfParentInstance("getApplicationRestrictions");
+        }
+
         if (mService != null) {
             try {
                 return mService.getApplicationRestrictions(admin, mContext.getPackageName(),
-                        packageName);
+                        packageName, mParentInstance);
             } catch (RemoteException e) {
                 throw e.rethrowFromSystemServer();
             }
@@ -12731,7 +12747,6 @@
     @StringDef({
             Settings.System.SCREEN_BRIGHTNESS_MODE,
             Settings.System.SCREEN_BRIGHTNESS,
-            Settings.System.SCREEN_BRIGHTNESS_FLOAT,
             Settings.System.SCREEN_OFF_TIMEOUT
     })
     @Retention(RetentionPolicy.SOURCE)
@@ -13987,8 +14002,15 @@
     public @NonNull DevicePolicyManager getParentProfileInstance(@NonNull ComponentName admin) {
         throwIfParentInstance("getParentProfileInstance");
         try {
-            if (!mService.isManagedProfile(admin)) {
-                throw new SecurityException("The current user does not have a parent profile.");
+            if (Flags.dmrhCanSetAppRestriction()) {
+                UserManager um = mContext.getSystemService(UserManager.class);
+                if (!um.isManagedProfile()) {
+                    throw new SecurityException("The current user does not have a parent profile.");
+                }
+            } else {
+                if (!mService.isManagedProfile(admin)) {
+                    throw new SecurityException("The current user does not have a parent profile.");
+                }
             }
             return new DevicePolicyManager(mContext, mService, true);
         } catch (RemoteException e) {
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index d4589dc..2002326 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -244,8 +244,8 @@
     void setDefaultSmsApplication(in ComponentName admin, String callerPackageName, String packageName, boolean parent);
     void setDefaultDialerApplication(String packageName);
 
-    void setApplicationRestrictions(in ComponentName who, in String callerPackage, in String packageName, in Bundle settings);
-    Bundle getApplicationRestrictions(in ComponentName who, in String callerPackage, in String packageName);
+    void setApplicationRestrictions(in ComponentName who, in String callerPackage, in String packageName, in Bundle settings, in boolean parent);
+    Bundle getApplicationRestrictions(in ComponentName who, in String callerPackage, in String packageName, in boolean parent);
     boolean setApplicationRestrictionsManagingPackage(in ComponentName admin, in String packageName);
     String getApplicationRestrictionsManagingPackage(in ComponentName admin);
     boolean isCallerApplicationRestrictionsManagingPackage(in String callerPackage);
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index 25697c5..56fb4aa 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -2,6 +2,7 @@
 # proto-message: flag_declarations
 
 package: "android.app.admin.flags"
+container: "system"
 
 flag {
   name: "policy_engine_migration_v2_enabled"
@@ -35,10 +36,11 @@
 }
 
 flag {
-  name: "cross_user_suspension_enabled"
+  name: "cross_user_suspension_enabled_ro"
   namespace: "enterprise"
   description: "Allow holders of INTERACT_ACROSS_USERS_FULL to suspend apps in different users."
   bug: "263464464"
+  is_fixed_read_only: true
 }
 
 flag {
@@ -202,6 +204,13 @@
 }
 
 flag {
+  name: "dmrh_can_set_app_restriction"
+  namespace: "enterprise"
+  description: "Allow DMRH to set application restrictions (both on the profile and the parent)"
+  bug: "328758346"
+}
+
+flag {
   name: "allow_screen_brightness_control_on_cope"
   namespace: "enterprise"
   description: "Allow COPE admin to control screen brightness and timeout."
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 7548562..508077e 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -2655,13 +2655,12 @@
             );
         }
         GetCredentialRequest getCredentialRequest = node.getPendingCredentialRequest();
-        if (getCredentialRequest == null) {
-            Log.i(TAG, prefix + " No Credential Manager Request");
-        } else {
-            Log.i(TAG, prefix + "  GetCredentialRequest: no. of options= "
-                    + getCredentialRequest.getCredentialOptions().size()
-            );
-        }
+        Log.i(TAG, prefix + "  Credential Manager info:"
+                + " hasCredentialManagerRequest=" + (getCredentialRequest != null)
+                + (getCredentialRequest != null
+                        ? ", sizeOfOptions=" + getCredentialRequest.getCredentialOptions().size()
+                        : "")
+        );
 
         final int NCHILDREN = node.getChildCount();
         if (NCHILDREN > 0) {
diff --git a/core/java/android/app/background_install_control_manager.aconfig b/core/java/android/app/background_install_control_manager.aconfig
index 5f3bb07..d29c5b5 100644
--- a/core/java/android/app/background_install_control_manager.aconfig
+++ b/core/java/android/app/background_install_control_manager.aconfig
@@ -1,4 +1,5 @@
 package: "android.app"
+container: "system"
 
 flag {
      namespace: "preload_safety"
diff --git a/core/java/android/app/backup/BackupManagerMonitor.java b/core/java/android/app/backup/BackupManagerMonitor.java
index c66478f..e741bc2 100644
--- a/core/java/android/app/backup/BackupManagerMonitor.java
+++ b/core/java/android/app/backup/BackupManagerMonitor.java
@@ -269,6 +269,33 @@
   /** V to U restore attempt, allowlist and denlist are set
    @hide */
   public static final int LOG_EVENT_ID_V_TO_U_RESTORE_SET_LIST = 72;
+  /** As part of package install, {@link PackageManager} invoked restore.
+   @hide */
+  public static final int LOG_EVENT_ID_RESTORE_AT_INSTALL_INVOKED = 73;
+  /** Skipping restore at package install
+   @hide */
+  public static final int LOG_EVENT_ID_SKIP_RESTORE_AT_INSTALL = 74;
+  /** Package is eligible and is accepted for restore
+   @hide */
+  public static final int LOG_EVENT_ID_PACKAGE_ACCEPTED_FOR_RESTORE = 75;
+  /** Restore data doesn't belong to the package for which restore is started
+   @hide */
+  public static final int LOG_EVENT_ID_RESTORE_DATA_DOES_NOT_BELONG_TO_PACKAGE = 76;
+  /** Unable to create BackupAgent for package for restore
+   @hide */
+  public static final int LOG_EVENT_ID_UNABLE_TO_CREATE_AGENT_FOR_RESTORE = 77;
+  /** BackupAgent crashed after creation but before accepting any data
+   @hide */
+  public static final int LOG_EVENT_ID_AGENT_CRASHED_BEFORE_RESTORE_DATA_IS_SENT = 78;
+  /** Failure in streaming restore data to BackupAgent
+   @hide */
+  public static final int LOG_EVENT_ID_FAILED_TO_SEND_DATA_TO_AGENT_DURING_RESTORE = 79;
+  /** BackupAgent related failure during restore
+   @hide */
+  public static final int LOG_EVENT_ID_AGENT_FAILURE_DURING_RESTORE = 80;
+  /** Failure in reading data from TransportPackage during restore
+   @hide */
+  public static final int LOG_EVENT_ID_FAILED_TO_READ_DATA_FROM_TRANSPORT = 81;
 
   /**
    * This method will be called each time something important happens on BackupManager.
diff --git a/core/java/android/app/contextualsearch/flags.aconfig b/core/java/android/app/contextualsearch/flags.aconfig
index 5ab0762..3385b2b 100644
--- a/core/java/android/app/contextualsearch/flags.aconfig
+++ b/core/java/android/app/contextualsearch/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.app.contextualsearch.flags"
+container: "system"
 
 flag {
   name: "enable_service"
diff --git a/core/java/android/app/grammatical_inflection_manager.aconfig b/core/java/android/app/grammatical_inflection_manager.aconfig
index 0d7bf65..ea494f4 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/multitasking.aconfig b/core/java/android/app/multitasking.aconfig
index dbf3173..9a64519 100644
--- a/core/java/android/app/multitasking.aconfig
+++ b/core/java/android/app/multitasking.aconfig
@@ -1,4 +1,5 @@
 package: "android.app"
+container: "system"
 
 flag {
     name: "enable_pip_ui_state_callback_on_entering"
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 29ffdc5..0082732 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"
@@ -81,4 +82,32 @@
   metadata {
     purpose: PURPOSE_BUGFIX
   }
+}
+
+flag {
+  name: "sort_section_by_time"
+  namespace: "systemui"
+  description: "Changes notification sort order to be by time within a section"
+  bug: "330193582"
+}
+
+flag {
+  name: "restrict_audio_attributes_call"
+  namespace: "systemui"
+  description: "Only CallStyle notifs can use USAGE_NOTIFICATION_RINGTONE"
+  bug: "331793339"
+}
+
+flag {
+  name: "restrict_audio_attributes_alarm"
+  namespace: "systemui"
+  description: "Only alarm category notifs can use USAGE_ALARM"
+  bug: "331793339"
+}
+
+flag {
+  name: "restrict_audio_attributes_media"
+  namespace: "systemui"
+  description: "No notifs can use USAGE_UNKNOWN or USAGE_MEDIA"
+  bug: "331793339"
 }
\ No newline at end of file
diff --git a/core/java/android/app/ondeviceintelligence/IDownloadCallback.aidl b/core/java/android/app/ondeviceintelligence/IDownloadCallback.aidl
index 8fc269e..2d7ea1a 100644
--- a/core/java/android/app/ondeviceintelligence/IDownloadCallback.aidl
+++ b/core/java/android/app/ondeviceintelligence/IDownloadCallback.aidl
@@ -23,7 +23,7 @@
  *
  * @hide
  */
-interface IDownloadCallback {
+oneway interface IDownloadCallback {
   void onDownloadStarted(long bytesToDownload) = 1;
   void onDownloadProgress(long bytesDownloaded) = 2;
   void onDownloadFailed(int failureStatus, String errorMessage, in PersistableBundle errorParams) = 3;
diff --git a/core/java/android/app/ondeviceintelligence/IFeatureCallback.aidl b/core/java/android/app/ondeviceintelligence/IFeatureCallback.aidl
index 93a84ec..2e05692 100644
--- a/core/java/android/app/ondeviceintelligence/IFeatureCallback.aidl
+++ b/core/java/android/app/ondeviceintelligence/IFeatureCallback.aidl
@@ -8,7 +8,7 @@
   *
   * @hide
   */
-interface IFeatureCallback {
+oneway interface IFeatureCallback {
     void onSuccess(in Feature result) = 1;
     void onFailure(int errorCode, in String errorMessage, in PersistableBundle errorParams) = 2;
 }
diff --git a/core/java/android/app/ondeviceintelligence/IFeatureDetailsCallback.aidl b/core/java/android/app/ondeviceintelligence/IFeatureDetailsCallback.aidl
index d950290..8688028 100644
--- a/core/java/android/app/ondeviceintelligence/IFeatureDetailsCallback.aidl
+++ b/core/java/android/app/ondeviceintelligence/IFeatureDetailsCallback.aidl
@@ -8,7 +8,7 @@
   *
   * @hide
   */
-interface IFeatureDetailsCallback {
+oneway interface IFeatureDetailsCallback {
     void onSuccess(in FeatureDetails result) = 1;
     void onFailure(int errorCode, in String errorMessage, in PersistableBundle errorParams) = 2;
 }
diff --git a/core/java/android/app/ondeviceintelligence/IListFeaturesCallback.aidl b/core/java/android/app/ondeviceintelligence/IListFeaturesCallback.aidl
index 374cb71..7e5eb57 100644
--- a/core/java/android/app/ondeviceintelligence/IListFeaturesCallback.aidl
+++ b/core/java/android/app/ondeviceintelligence/IListFeaturesCallback.aidl
@@ -9,7 +9,7 @@
   *
   * @hide
   */
-interface IListFeaturesCallback {
+oneway interface IListFeaturesCallback {
     void onSuccess(in List<Feature> result) = 1;
     void onFailure(int errorCode, in String errorMessage, in PersistableBundle errorParams) = 2;
 }
diff --git a/core/java/android/app/ondeviceintelligence/IOnDeviceIntelligenceManager.aidl b/core/java/android/app/ondeviceintelligence/IOnDeviceIntelligenceManager.aidl
index 8bf288a..470b1ec 100644
--- a/core/java/android/app/ondeviceintelligence/IOnDeviceIntelligenceManager.aidl
+++ b/core/java/android/app/ondeviceintelligence/IOnDeviceIntelligenceManager.aidl
@@ -39,7 +39,7 @@
   *
   * @hide
   */
- interface IOnDeviceIntelligenceManager {
+interface IOnDeviceIntelligenceManager {
       @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.USE_ON_DEVICE_INTELLIGENCE)")
       void getVersion(in RemoteCallback remoteCallback) = 1;
 
diff --git a/core/java/android/app/ondeviceintelligence/IResponseCallback.aidl b/core/java/android/app/ondeviceintelligence/IResponseCallback.aidl
index 45963d2..270b600 100644
--- a/core/java/android/app/ondeviceintelligence/IResponseCallback.aidl
+++ b/core/java/android/app/ondeviceintelligence/IResponseCallback.aidl
@@ -9,7 +9,7 @@
   *
   * @hide
   */
-interface IResponseCallback {
+oneway interface IResponseCallback {
     void onSuccess(in Bundle resultBundle) = 1;
     void onFailure(int errorCode, in String errorMessage, in PersistableBundle errorParams) = 2;
     void onDataAugmentRequest(in Bundle processedContent, in RemoteCallback responseCallback) = 3;
diff --git a/core/java/android/app/ondeviceintelligence/IStreamingResponseCallback.aidl b/core/java/android/app/ondeviceintelligence/IStreamingResponseCallback.aidl
index 671abe3..3e90240 100644
--- a/core/java/android/app/ondeviceintelligence/IStreamingResponseCallback.aidl
+++ b/core/java/android/app/ondeviceintelligence/IStreamingResponseCallback.aidl
@@ -10,7 +10,7 @@
   *
   * @hide
   */
-interface IStreamingResponseCallback {
+oneway interface IStreamingResponseCallback {
     void onNewContent(in Bundle processedResult) = 1;
     void onSuccess(in Bundle result) = 2;
     void onFailure(int errorCode, in String errorMessage, in PersistableBundle errorParams) = 3;
diff --git a/core/java/android/app/ondeviceintelligence/ITokenInfoCallback.aidl b/core/java/android/app/ondeviceintelligence/ITokenInfoCallback.aidl
index 9219a89..958bef0 100644
--- a/core/java/android/app/ondeviceintelligence/ITokenInfoCallback.aidl
+++ b/core/java/android/app/ondeviceintelligence/ITokenInfoCallback.aidl
@@ -8,7 +8,7 @@
   *
   * @hide
   */
-interface ITokenInfoCallback {
+oneway interface ITokenInfoCallback {
     void onSuccess(in TokenInfo tokenInfo) = 1;
     void onFailure(int errorCode, in String errorMessage, in PersistableBundle errorParams) = 2;
 }
diff --git a/core/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java b/core/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java
index bc50d2e4..5e1c1e0 100644
--- a/core/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java
+++ b/core/java/android/app/ondeviceintelligence/OnDeviceIntelligenceManager.java
@@ -365,7 +365,6 @@
      *                           associated params.
      */
     @RequiresPermission(Manifest.permission.USE_ON_DEVICE_INTELLIGENCE)
-
     public void processRequest(@NonNull Feature feature, @NonNull @InferenceParams Bundle request,
             @RequestType int requestType,
             @Nullable CancellationSignal cancellationSignal,
@@ -423,16 +422,16 @@
      * when the final response contains an enhanced aggregation of the contents already
      * streamed.
      *
-     * @param feature                   feature associated with the request.
-     * @param request                   request and associated params represented by the Bundle
-     *                                  data.
-     * @param requestType               type of request being sent for processing the content.
-     * @param cancellationSignal        signal to invoke cancellation.
-     * @param processingSignal          signal to send custom signals in the
-     *                                  remote implementation.
-     * @param streamingResponseCallback streaming callback to populate the response content and
-     *                                  associated params.
-     * @param callbackExecutor          executor to run the callback on.
+     * @param feature                     feature associated with the request.
+     * @param request                     request and associated params represented by the Bundle
+     *                                    data.
+     * @param requestType                 type of request being sent for processing the content.
+     * @param cancellationSignal          signal to invoke cancellation.
+     * @param processingSignal            signal to send custom signals in the
+     *                                    remote implementation.
+     * @param streamingProcessingCallback streaming callback to populate the response content and
+     *                                    associated params.
+     * @param callbackExecutor            executor to run the callback on.
      */
     @RequiresPermission(Manifest.permission.USE_ON_DEVICE_INTELLIGENCE)
     public void processRequestStreaming(@NonNull Feature feature,
@@ -528,19 +527,18 @@
 
     /**
      * {@link Bundle}s annotated with this type will be validated that they are in-effect read-only
-     * when passed to inference service via Binder IPC. Following restrictions apply :
+     * when passed via Binder IPC. Following restrictions apply :
      * <ul>
+     * <li> No Nested Bundles are allowed.</li>
+     * <li> {@link PersistableBundle}s are allowed.</li>
      * <li> Any primitive types or their collections can be added as usual.</li>
      * <li>IBinder objects should *not* be added.</li>
      * <li>Parcelable data which has no active-objects, should be added as
      * {@link Bundle#putByteArray}</li>
      * <li>Parcelables have active-objects, only following types will be allowed</li>
      * <ul>
-     *  <li>{@link Bitmap} set as {@link Bitmap#setImmutable()}</li>
-     *  <li>{@link android.database.CursorWindow}</li>
      *  <li>{@link android.os.ParcelFileDescriptor} opened in
      *  {@link android.os.ParcelFileDescriptor#MODE_READ_ONLY}</li>
-     *  <li>{@link android.os.SharedMemory} set to {@link OsConstants#PROT_READ}</li>
      * </ul>
      * </ul>
      *
@@ -550,9 +548,40 @@
      * @hide
      */
     @Target({ElementType.PARAMETER, ElementType.FIELD})
+    public @interface StateParams {
+    }
+
+    /**
+     * This is an extension of {@link StateParams} but for purpose of inference few other types are
+     * also allowed as read-only, as listed below.
+     *
+     * <li>{@link Bitmap} set as immutable.</li>
+     * <li>{@link android.database.CursorWindow}</li>
+     * <li>{@link android.os.SharedMemory} set to {@link OsConstants#PROT_READ}</li>
+     * </ul>
+     * </ul>
+     *
+     * In all other scenarios the system-server might throw a
+     * {@link android.os.BadParcelableException} if the Bundle validation fails.
+     *
+     * @hide
+     */
+    @Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.TYPE_USE})
     public @interface InferenceParams {
     }
 
+    /**
+     * This is an extension of {@link StateParams} with the exception that it allows writing
+     * {@link Bitmap} as part of the response.
+     *
+     * In all other scenarios the system-server might throw a
+     * {@link android.os.BadParcelableException} if the Bundle validation fails.
+     *
+     * @hide
+     */
+    @Target({ElementType.PARAMETER, ElementType.FIELD})
+    public @interface ResponseParams {
+    }
 
     @Nullable
     private static AndroidFuture<IBinder> configureRemoteCancellationFuture(
diff --git a/core/java/android/app/ondeviceintelligence/ProcessingCallback.java b/core/java/android/app/ondeviceintelligence/ProcessingCallback.java
index 4d936ea..e50d6b1 100644
--- a/core/java/android/app/ondeviceintelligence/ProcessingCallback.java
+++ b/core/java/android/app/ondeviceintelligence/ProcessingCallback.java
@@ -23,6 +23,7 @@
 import android.annotation.SystemApi;
 import android.os.Bundle;
 import android.app.ondeviceintelligence.OnDeviceIntelligenceManager.InferenceParams;
+import android.app.ondeviceintelligence.OnDeviceIntelligenceManager.ResponseParams;
 
 import java.util.function.Consumer;
 
@@ -43,7 +44,7 @@
      *
      * @param result Response to be passed as a result.
      */
-    void onResult(@NonNull @InferenceParams Bundle result);
+    void onResult(@NonNull @ResponseParams Bundle result);
 
     /**
      * Called when the request processing fails. The failure details are indicated by the
@@ -64,8 +65,8 @@
      *                         expected to be non-null or EMPTY when there is no response.
      */
     default void onDataAugmentRequest(
-            @NonNull @InferenceParams Bundle processedContent,
-            @NonNull Consumer<Bundle> contentConsumer) {
+            @NonNull @ResponseParams Bundle processedContent,
+            @NonNull Consumer<@InferenceParams Bundle> contentConsumer) {
         contentConsumer.accept(Bundle.EMPTY);
     }
 }
diff --git a/core/java/android/app/ondeviceintelligence/StreamingProcessingCallback.java b/core/java/android/app/ondeviceintelligence/StreamingProcessingCallback.java
index 41f1807..7ee2af7 100644
--- a/core/java/android/app/ondeviceintelligence/StreamingProcessingCallback.java
+++ b/core/java/android/app/ondeviceintelligence/StreamingProcessingCallback.java
@@ -22,7 +22,7 @@
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.os.Bundle;
-import android.app.ondeviceintelligence.OnDeviceIntelligenceManager.InferenceParams;
+import android.app.ondeviceintelligence.OnDeviceIntelligenceManager.ResponseParams;
 
 /**
  * Streaming variant of {@link ProcessingCallback} to populate response while processing a given
@@ -37,5 +37,5 @@
      * Callback that would be invoked when a part of the response i.e. some response is
      * already processed, and needs to be passed onto the caller.
      */
-    void onPartialResult(@NonNull @InferenceParams Bundle partialResult);
+    void onPartialResult(@NonNull @ResponseParams Bundle partialResult);
 }
diff --git a/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig b/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig
index dd9210f..8b6441a 100644
--- a/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig
+++ b/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig
@@ -1,4 +1,5 @@
 package: "android.app.ondeviceintelligence.flags"
+container: "system"
 
 flag {
     name: "enable_on_device_intelligence"
diff --git a/core/java/android/app/pinner-client.aconfig b/core/java/android/app/pinner-client.aconfig
index 0f7fa14..696fd38 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/smartspace/flags.aconfig b/core/java/android/app/smartspace/flags.aconfig
index e90ba67..df71924 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/ui_mode_manager.aconfig b/core/java/android/app/ui_mode_manager.aconfig
index 27a38cc..9f44a4d 100644
--- a/core/java/android/app/ui_mode_manager.aconfig
+++ b/core/java/android/app/ui_mode_manager.aconfig
@@ -1,4 +1,5 @@
 package: "android.app"
+container: "system"
 
 flag {
      namespace: "systemui"
diff --git a/core/java/android/app/usage/flags.aconfig b/core/java/android/app/usage/flags.aconfig
index 9a2d2e5..c7b168a 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/app/wearable/IWearableSensingCallback.aidl b/core/java/android/app/wearable/IWearableSensingCallback.aidl
new file mode 100644
index 0000000..d76b32d
--- /dev/null
+++ b/core/java/android/app/wearable/IWearableSensingCallback.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.wearable;
+
+import android.os.ParcelFileDescriptor;
+
+import com.android.internal.infra.AndroidFuture;
+
+/**
+ * Interface for callbacks coming from the WearableSensingService.
+ *
+ * @hide
+ */
+oneway interface IWearableSensingCallback {
+
+    /**
+     * Opens the requested file and returns the resulting ParcelFileDescriptor to the provided
+     * future.
+     */
+    void openFile(in String filename, in AndroidFuture<ParcelFileDescriptor> future);
+}
\ No newline at end of file
diff --git a/core/java/android/app/wearable/IWearableSensingManager.aidl b/core/java/android/app/wearable/IWearableSensingManager.aidl
index 7d3b285..c0d06ea 100644
--- a/core/java/android/app/wearable/IWearableSensingManager.aidl
+++ b/core/java/android/app/wearable/IWearableSensingManager.aidl
@@ -17,6 +17,7 @@
 package android.app.wearable;
 
 import android.app.PendingIntent;
+import android.app.wearable.IWearableSensingCallback;
 import android.content.ComponentName;
 import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
@@ -30,9 +31,9 @@
  */
 interface IWearableSensingManager {
      @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE)")
-     void provideConnection(in ParcelFileDescriptor parcelFileDescriptor, in RemoteCallback callback);
+     void provideConnection(in ParcelFileDescriptor parcelFileDescriptor, in IWearableSensingCallback wearableSensingCallback, in RemoteCallback statusCallback);
      @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE)")
-     void provideDataStream(in ParcelFileDescriptor parcelFileDescriptor, in RemoteCallback callback);
+     void provideDataStream(in ParcelFileDescriptor parcelFileDescriptor, in @nullable IWearableSensingCallback wearableSensingCallback, in RemoteCallback statusCallback);
      @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE)")
      void provideData(in PersistableBundle data, in SharedMemory sharedMemory, in RemoteCallback callback);
      @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE)")
diff --git a/core/java/android/app/wearable/WearableSensingManager.java b/core/java/android/app/wearable/WearableSensingManager.java
index df6d2a6..4b77c74 100644
--- a/core/java/android/app/wearable/WearableSensingManager.java
+++ b/core/java/android/app/wearable/WearableSensingManager.java
@@ -27,11 +27,15 @@
 import android.annotation.SystemService;
 import android.app.PendingIntent;
 import android.app.ambientcontext.AmbientContextEvent;
+import android.app.compat.CompatChanges;
 import android.companion.CompanionDeviceManager;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Binder;
+import android.os.Build;
 import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
 import android.os.RemoteCallback;
@@ -39,7 +43,13 @@
 import android.os.SharedMemory;
 import android.service.wearable.WearableSensingService;
 import android.system.OsConstants;
+import android.util.Slog;
 
+import com.android.internal.infra.AndroidFuture;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.lang.annotation.Retention;
@@ -155,6 +165,17 @@
     public @interface StatusCode {}
 
     /**
+     * If the WearableSensingService implementation belongs to the same APK as the caller, calling
+     * {@link #provideDataStream(ParcelFileDescriptor, Executor, Consumer)} will allow
+     * WearableSensingService to read from the caller's file directory via {@link
+     * Context#openFileInput(String)}. The read will be proxied via the caller's process and
+     * executed by the {@code executor} provided to this method.
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
+    static final long ALLOW_WEARABLE_SENSING_SERVICE_FILE_READ = 330701114L;
+
+    /**
      * Retrieves a {@link WearableSensingDataRequest} from the Intent sent to the PendingIntent
      * provided to {@link #registerDataRequestObserver(int, PendingIntent, Executor, Consumer)}.
      *
@@ -169,6 +190,7 @@
                 EXTRA_WEARABLE_SENSING_DATA_REQUEST, WearableSensingDataRequest.class);
     }
 
+    private static final String TAG = WearableSensingManager.class.getSimpleName();
     private final Context mContext;
     private final IWearableSensingManager mService;
 
@@ -216,6 +238,11 @@
      * dropped during the restart. The caller is responsible for ensuring other method calls are
      * queued until a success status is returned from the {@code statusConsumer}.
      *
+     * <p>If the WearableSensingService implementation belongs to the same APK as the caller,
+     * calling this method will allow WearableSensingService to read from the caller's file
+     * directory via {@link Context#openFileInput(String)}. The read will be proxied via the
+     * caller's process and executed by the {@code executor} provided to this method.
+     *
      * @param wearableConnection The connection to provide
      * @param executor Executor on which to run the consumer callback
      * @param statusConsumer A consumer that handles the status codes for providing the connection
@@ -227,9 +254,14 @@
             @NonNull ParcelFileDescriptor wearableConnection,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull @StatusCode Consumer<Integer> statusConsumer) {
+        RemoteCallback statusCallback = createStatusCallback(executor, statusConsumer);
         try {
-            RemoteCallback callback = createStatusCallback(executor, statusConsumer);
-            mService.provideConnection(wearableConnection, callback);
+            // The wearableSensingCallback is included in this method call even though it is not
+            // semantically related to the connection because we want to avoid race conditions
+            // during the process restart triggered by this method call. See
+            // com.android.server.wearable.RemoteWearableSensingService for details.
+            mService.provideConnection(
+                    wearableConnection, createWearableSensingCallback(executor), statusCallback);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -237,15 +269,21 @@
 
     /**
      * Provides a data stream to the WearableSensingService that's backed by the
-     * parcelFileDescriptor, and sends the result to the {@link Consumer} right after the call.
-     * This is used by applications that will also provide an implementation of
-     * an isolated WearableSensingService. If the data stream was provided successfully
-     * {@link WearableSensingManager#STATUS_SUCCESS} will be provided.
+     * parcelFileDescriptor, and sends the result to the {@link Consumer} right after the call. This
+     * is used by applications that will also provide an implementation of an isolated
+     * WearableSensingService. If the data stream was provided successfully {@link
+     * WearableSensingManager#STATUS_SUCCESS} will be provided.
+     *
+     * <p>Starting from target SDK level 35, if the WearableSensingService implementation belongs to
+     * the same APK as the caller, calling this method will allow WearableSensingService to read
+     * from the caller's file directory via {@link Context#openFileInput(String)}. The read will be
+     * proxied via the caller's process and executed by the {@code executor} provided to this
+     * method.
      *
      * @param parcelFileDescriptor The data stream to provide
      * @param executor Executor on which to run the consumer callback
-     * @param statusConsumer A consumer that handles the status codes, which is returned
-     *                 right after the call.
+     * @param statusConsumer A consumer that handles the status codes, which is returned right after
+     *     the call.
      * @deprecated Use {@link #provideConnection(ParcelFileDescriptor, Executor, Consumer)} instead
      *     to provide a remote wearable device connection to the WearableSensingService
      */
@@ -255,9 +293,14 @@
             @NonNull ParcelFileDescriptor parcelFileDescriptor,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull @StatusCode Consumer<Integer> statusConsumer) {
+        RemoteCallback statusCallback = createStatusCallback(executor, statusConsumer);
+        IWearableSensingCallback wearableSensingCallback = null;
+        if (CompatChanges.isChangeEnabled(ALLOW_WEARABLE_SENSING_SERVICE_FILE_READ)) {
+            wearableSensingCallback = createWearableSensingCallback(executor);
+        }
         try {
-            RemoteCallback callback = createStatusCallback(executor, statusConsumer);
-            mService.provideDataStream(parcelFileDescriptor, callback);
+            mService.provideDataStream(
+                    parcelFileDescriptor, wearableSensingCallback, statusCallback);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -480,4 +523,47 @@
                     }
                 });
     }
+
+    private IWearableSensingCallback createWearableSensingCallback(Executor executor) {
+        return new IWearableSensingCallback.Stub() {
+
+            @Override
+            public void openFile(String filename, AndroidFuture<ParcelFileDescriptor> future) {
+                Slog.d(TAG, "IWearableSensingCallback#openFile " + filename);
+                Binder.withCleanCallingIdentity(
+                        () ->
+                                executor.execute(
+                                        () -> {
+                                            File file = new File(mContext.getFilesDir(), filename);
+                                            ParcelFileDescriptor pfd = null;
+                                            try {
+                                                pfd =
+                                                        ParcelFileDescriptor.open(
+                                                                file,
+                                                                ParcelFileDescriptor
+                                                                        .MODE_READ_ONLY);
+                                                Slog.d(
+                                                        TAG,
+                                                        "Successfully opened a file with"
+                                                                + " ParcelFileDescriptor.");
+                                            } catch (FileNotFoundException e) {
+                                                Slog.e(TAG, "Cannot open file.", e);
+                                            } finally {
+                                                future.complete(pfd);
+                                                if (pfd != null) {
+                                                    try {
+                                                        pfd.close();
+                                                    } catch (IOException ex) {
+                                                        Slog.e(
+                                                                TAG,
+                                                                "Error closing"
+                                                                        + " ParcelFileDescriptor.",
+                                                                ex);
+                                                    }
+                                                }
+                                            }
+                                        }));
+            }
+        };
+    }
 }
diff --git a/core/java/android/app/wearable/flags.aconfig b/core/java/android/app/wearable/flags.aconfig
index d1d7b5d..b68bafe 100644
--- a/core/java/android/app/wearable/flags.aconfig
+++ b/core/java/android/app/wearable/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.app.wearable"
+container: "system"
 
 flag {
     name: "enable_unsupported_operation_status_code"
diff --git a/core/java/android/appwidget/OWNERS b/core/java/android/appwidget/OWNERS
index 554b0de..1910833 100644
--- a/core/java/android/appwidget/OWNERS
+++ b/core/java/android/appwidget/OWNERS
@@ -1,4 +1,5 @@
-pinyaoting@google.com
+fengjial@google.com
 sihua@google.com
+pinyaoting@google.com
 suprabh@google.com
 sunnygoyal@google.com
diff --git a/core/java/android/appwidget/flags.aconfig b/core/java/android/appwidget/flags.aconfig
index 4511954..3bcc7c7 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 ecc5e1b..8458857 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/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index ec59cf6..ed55a3f 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -66,6 +66,7 @@
 import android.os.RemoteException;
 import android.util.ArraySet;
 import android.util.Log;
+import android.view.Display;
 import android.view.Surface;
 import android.view.WindowManager;
 
@@ -338,6 +339,10 @@
     @TestApi
     public @VirtualDeviceParams.DevicePolicy int getDevicePolicy(
             int deviceId, @VirtualDeviceParams.PolicyType int policyType) {
+        if (deviceId == Context.DEVICE_ID_DEFAULT) {
+            // Avoid unnecessary binder call, for default device, policy will be always default.
+            return VirtualDeviceParams.DEVICE_POLICY_DEFAULT;
+        }
         if (mService == null) {
             Log.w(TAG, "Failed to retrieve device policy; no virtual device manager service.");
             return VirtualDeviceParams.DEVICE_POLICY_DEFAULT;
@@ -357,6 +362,10 @@
     @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
     @TestApi
     public int getDeviceIdForDisplayId(int displayId) {
+        if (displayId == Display.DEFAULT_DISPLAY || displayId == Display.INVALID_DISPLAY) {
+            // Avoid unnecessary binder call for default / invalid display id.
+            return Context.DEVICE_ID_DEFAULT;
+        }
         if (mService == null) {
             Log.w(TAG, "Failed to retrieve virtual devices; no virtual device manager service.");
             return Context.DEVICE_ID_DEFAULT;
diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig
index a6a4f5e..18c81a2 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 2904e7c..006226e 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/ComponentCallbacks.java b/core/java/android/content/ComponentCallbacks.java
index 428545d..fb9536f 100644
--- a/core/java/android/content/ComponentCallbacks.java
+++ b/core/java/android/content/ComponentCallbacks.java
@@ -55,15 +55,11 @@
      * That is, before reaching the point of killing processes hosting
      * service and foreground UI that we would like to avoid killing.
      *
-     * <p>You should implement this method to release
-     * any caches or other unnecessary resources you may be holding on to.
-     * The system will perform a garbage collection for you after returning from this method.
-     * <p>Preferably, you should implement {@link ComponentCallbacks2#onTrimMemory} from
-     * {@link ComponentCallbacks2} to incrementally unload your resources based on various
-     * levels of memory demands.  That API is available for API level 14 and higher, so you should
-     * only use this {@link #onLowMemory} method as a fallback for older versions, which can be
-     * treated the same as {@link ComponentCallbacks2#onTrimMemory} with the {@link
-     * ComponentCallbacks2#TRIM_MEMORY_COMPLETE} level.</p>
+     * @deprecated Since API level 14 this is superseded by
+     *             {@link ComponentCallbacks2#onTrimMemory}.
+     *             Since API level 34 this is never called.
+     *             Apps targeting API level 34 and above may provide an empty implementation.
      */
+    @Deprecated
     void onLowMemory();
 }
diff --git a/core/java/android/content/ComponentCallbacks2.java b/core/java/android/content/ComponentCallbacks2.java
index 6576c0f..a165b18 100644
--- a/core/java/android/content/ComponentCallbacks2.java
+++ b/core/java/android/content/ComponentCallbacks2.java
@@ -105,14 +105,20 @@
      * Level for {@link #onTrimMemory(int)}: the process is nearing the end
      * of the background LRU list, and if more memory isn't found soon it will
      * be killed.
+     *
+     * @deprecated Apps are not notified of this level since API level 34
      */
+    @Deprecated
     static final int TRIM_MEMORY_COMPLETE = 80;
     
     /**
      * Level for {@link #onTrimMemory(int)}: the process is around the middle
      * of the background LRU list; freeing memory can help the system keep
      * other processes running later in the list for better overall performance.
+     *
+     * @deprecated Apps are not notified of this level since API level 34
      */
+    @Deprecated
     static final int TRIM_MEMORY_MODERATE = 60;
     
     /**
@@ -139,7 +145,10 @@
      * will happen after this is {@link #onLowMemory()} called to report that
      * nothing at all can be kept in the background, a situation that can start
      * to notably impact the user.
+     *
+     * @deprecated Apps are not notified of this level since API level 34
      */
+    @Deprecated
     static final int TRIM_MEMORY_RUNNING_CRITICAL = 15;
 
     /**
@@ -147,7 +156,10 @@
      * background process, but the device is running low on memory.
      * Your running process should free up unneeded resources to allow that
      * memory to be used elsewhere.
+     *
+     * @deprecated Apps are not notified of this level since API level 34
      */
+    @Deprecated
     static final int TRIM_MEMORY_RUNNING_LOW = 10;
 
     /**
@@ -155,17 +167,19 @@
      * background process, but the device is running moderately low on memory.
      * Your running process may want to release some unneeded resources for
      * use elsewhere.
+     *
+     * @deprecated Apps are not notified of this level since API level 34
      */
+    @Deprecated
     static final int TRIM_MEMORY_RUNNING_MODERATE = 5;
 
     /**
      * Called when the operating system has determined that it is a good
-     * time for a process to trim unneeded memory from its process.  This will
-     * happen for example when it goes in the background and there is not enough
-     * memory to keep as many background processes running as desired.  You
-     * should never compare to exact values of the level, since new intermediate
-     * values may be added -- you will typically want to compare if the value
-     * is greater or equal to a level you are interested in.
+     * time for a process to trim unneeded memory from its process.
+     *
+     * You should never compare to exact values of the level, since new
+     * intermediate values may be added -- you will typically want to compare if
+     * the value is greater or equal to a level you are interested in.
      *
      * <p>To retrieve the processes current trim level at any point, you can
      * use {@link android.app.ActivityManager#getMyMemoryState
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index c0c91cb..b706cae 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5914,15 +5914,6 @@
     public static final String JOB_SCHEDULER_SERVICE = "jobscheduler";
 
     /**
-     * Use with {@link #getSystemService(String)} to retrieve a
-     * {@link android.app.tare.EconomyManager} instance for understanding economic standing.
-     * @see #getSystemService(String)
-     * @hide
-     * @see android.app.tare.EconomyManager
-     */
-    public static final String RESOURCE_ECONOMY_SERVICE = "tare";
-
-    /**
      * Use with {@link #getSystemService(String)} to retrieve a {@link
      * android.service.persistentdata.PersistentDataBlockManager} instance
      * for interacting with a storage device that lives across factory resets.
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 8bc5e8c..9e316a2 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3771,6 +3771,10 @@
      *   <li><em>{@link android.content.Intent#EXTRA_PHONE_NUMBER}</em> -
      *       the phone number originally intended to be dialed.</li>
      * </ul>
+     * <p class="note">Starting in Android 15, this broadcast is no longer sent as an ordered
+     * broadcast.  The <code>resultData</code> no longer has any effect and will not determine the
+     * actual routing of the call.  Further, receivers of this broadcast do not get foreground
+     * priority and cannot launch background activities.</p>
      * <p>Once the broadcast is finished, the resultData is used as the actual
      * number to call.  If  <code>null</code>, no call will be placed.</p>
      * <p>It is perfectly acceptable for multiple receivers to process the
@@ -3811,8 +3815,8 @@
      * {@link android.telecom.CallRedirectionService} API.  Apps that perform call screening
      * should use the {@link android.telecom.CallScreeningService} API.  Apps which need to be
      * notified of basic call state should use
-     * {@link android.telephony.PhoneStateListener#onCallStateChanged(int, String)} to determine
-     * when a new outgoing call is placed.
+     * {@link android.telephony.TelephonyCallback.CallStateListener} to determine when a new
+     * outgoing call is placed.
      */
     @Deprecated
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
diff --git a/core/java/android/content/flags/flags.aconfig b/core/java/android/content/flags/flags.aconfig
index 27bce5b..aac04b3a 100644
--- a/core/java/android/content/flags/flags.aconfig
+++ b/core/java/android/content/flags/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.content.flags"
+container: "system"
 
 flag {
     name: "enable_bind_package_isolated_process"
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 4c0da7c..f5bff9d 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -4844,6 +4844,16 @@
     public static final String FEATURE_ROTARY_ENCODER_LOW_RES =
             "android.hardware.rotaryencoder.lowres";
 
+  /**
+   * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device has
+   * support for contextual search helper.
+   *
+   * @hide
+   */
+  @SdkConstant(SdkConstantType.FEATURE)
+  public static final String FEATURE_CONTEXTUAL_SEARCH_HELPER =
+      "android.software.contextualsearch";
+
     /** @hide */
     public static final boolean APP_ENUMERATION_ENABLED_BY_DEFAULT = true;
 
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index cde565b..6158917 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 4963a4f..0c0da31 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/FontScaleConverterFactory.java b/core/java/android/content/res/FontScaleConverterFactory.java
index 625d7cb..c7237ea 100644
--- a/core/java/android/content/res/FontScaleConverterFactory.java
+++ b/core/java/android/content/res/FontScaleConverterFactory.java
@@ -58,6 +58,16 @@
         synchronized (LOOKUP_TABLES_WRITE_LOCK) {
             putInto(
                     sLookupTables,
+                    /* scaleKey= */ 1.05f,
+                    new FontScaleConverterImpl(
+                            /* fromSp= */
+                            new float[] {   8f,   10f,   12f,   14f,   18f,   20f,   24f,   30f,  100},
+                            /* toDp=   */
+                            new float[] { 8.4f, 10.5f, 12.6f, 14.8f, 18.6f, 20.6f, 24.4f,   30f,  100})
+            );
+
+            putInto(
+                    sLookupTables,
                     /* scaleKey= */ 1.1f,
                     new FontScaleConverterImpl(
                             /* fromSp= */
@@ -78,6 +88,16 @@
 
             putInto(
                     sLookupTables,
+                    /* scaleKey= */ 1.2f,
+                    new FontScaleConverterImpl(
+                            /* fromSp= */
+                            new float[] {   8f,   10f,   12f,   14f,   18f,   20f,   24f,   30f,  100},
+                            /* toDp=   */
+                            new float[] { 9.6f,   12f, 14.4f, 17.2f, 20.4f, 22.4f, 25.6f,   30f,  100})
+            );
+
+            putInto(
+                    sLookupTables,
                     /* scaleKey= */ 1.3f,
                     new FontScaleConverterImpl(
                             /* fromSp= */
@@ -117,7 +137,7 @@
             );
         }
 
-        sMinScaleBeforeCurvesApplied = getScaleFromKey(sLookupTables.keyAt(0)) - 0.02f;
+        sMinScaleBeforeCurvesApplied = getScaleFromKey(sLookupTables.keyAt(0)) - 0.01f;
         if (sMinScaleBeforeCurvesApplied <= 1.0f) {
             throw new IllegalStateException(
                     "You should only apply non-linear scaling to font scales > 1"
diff --git a/core/java/android/content/res/flags.aconfig b/core/java/android/content/res/flags.aconfig
index 8f5c912..a475cc8 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/CredentialManager.java b/core/java/android/credentials/CredentialManager.java
index 3a9a0f91..93fa5d8 100644
--- a/core/java/android/credentials/CredentialManager.java
+++ b/core/java/android/credentials/CredentialManager.java
@@ -74,6 +74,11 @@
                 PROVIDER_FILTER_ALL_PROVIDERS,
                 PROVIDER_FILTER_SYSTEM_PROVIDERS_ONLY,
                 PROVIDER_FILTER_USER_PROVIDERS_ONLY,
+                // By default the returned list of providers will not include any providers that
+                // have been hidden by device policy. However, there are some cases where we want
+                // them to show up (e.g. settings) so this will return the list of providers with
+                // the hidden ones included.
+                PROVIDER_FILTER_USER_PROVIDERS_INCLUDING_HIDDEN,
             })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ProviderFilter {}
@@ -99,6 +104,14 @@
      */
     @TestApi public static final int PROVIDER_FILTER_USER_PROVIDERS_ONLY = 2;
 
+    /**
+     * Returns user credential providers only. This will include providers that
+     * have been disabled by the device policy.
+     *
+     * @hide
+     */
+    public static final int PROVIDER_FILTER_USER_PROVIDERS_INCLUDING_HIDDEN = 3;
+
     private final Context mContext;
     private final ICredentialManager mService;
 
diff --git a/core/java/android/credentials/flags.aconfig b/core/java/android/credentials/flags.aconfig
index d077329..d243575 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 7ecffaf..3073e25 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/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index 90b7869..a0e40f6 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -52,6 +52,7 @@
 import android.util.Log;
 
 import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FrameworkStatsLog;
 
 import java.lang.annotation.Retention;
@@ -70,7 +71,8 @@
 public class BiometricPrompt implements BiometricAuthenticator, BiometricConstants {
 
     private static final String TAG = "BiometricPrompt";
-    private static final int MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER = 30;
+    @VisibleForTesting
+    static final int MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER = 30;
 
     /**
      * Error/help message will show for this amount of time.
@@ -223,8 +225,8 @@
          *
          * @param logoDescription The logo description text that will be shown on the prompt.
          * @return This builder.
-         * @throws IllegalStateException If logo description is null or exceeds certain character
-         *                               limit.
+         * @throws IllegalArgumentException If logo description is null or exceeds certain character
+         *                                  limit.
          */
         @FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT)
         @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
@@ -232,7 +234,7 @@
         public BiometricPrompt.Builder setLogoDescription(@NonNull String logoDescription) {
             if (logoDescription == null
                     || logoDescription.length() > MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER) {
-                throw new IllegalStateException(
+                throw new IllegalArgumentException(
                         "Logo description passed in can not be null or exceed "
                                 + MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER + " character number.");
             }
@@ -240,7 +242,6 @@
             return this;
         }
 
-
         /**
          * Required: Sets the title that will be shown on the prompt.
          * @param title The title to display.
diff --git a/core/java/android/hardware/biometrics/PromptContentViewWithMoreOptionsButton.java b/core/java/android/hardware/biometrics/PromptContentViewWithMoreOptionsButton.java
index 853d86c..a9eca3f 100644
--- a/core/java/android/hardware/biometrics/PromptContentViewWithMoreOptionsButton.java
+++ b/core/java/android/hardware/biometrics/PromptContentViewWithMoreOptionsButton.java
@@ -29,19 +29,22 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.util.concurrent.Executor;
 
 /**
- * Contains the information of the template of content view with a more options button for Biometric
- * Prompt.
+ * Contains the information of the template of content view with a more options button for
+ * Biometric Prompt.
+ * <p>
  * This button should be used to provide more options for sign in or other purposes, such as when a
  * user needs to select between multiple app-specific accounts or profiles that are available for
- * sign in. This is not common and apps should avoid using it if there is only one choice available
- * or if the user has already selected the appropriate account to use before invoking
- * BiometricPrompt because it will create additional steps that the user must navigate through.
- * Clicking the more options button will dismiss the prompt, provide the app an opportunity to ask
- * the user for the correct account, and finally allow the app to decide how to proceed once
- * selected.
+ * sign in.
+ * <p>
+ * Apps should avoid using this when possible because it will create additional steps that the user
+ * must navigate through - clicking the more options button will dismiss the prompt, provide the app
+ * an opportunity to ask the user for the correct option, and finally allow the app to decide how to
+ * proceed once selected.
  *
  * <p>
  * Here's how you'd set a <code>PromptContentViewWithMoreOptionsButton</code> on a Biometric
@@ -59,7 +62,8 @@
  */
 @FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT)
 public final class PromptContentViewWithMoreOptionsButton implements PromptContentViewParcelable {
-    private static final int MAX_DESCRIPTION_CHARACTER_NUMBER = 225;
+    @VisibleForTesting
+    static final int MAX_DESCRIPTION_CHARACTER_NUMBER = 225;
 
     private final String mDescription;
     private DialogInterface.OnClickListener mListener;
@@ -132,14 +136,16 @@
         }
     };
 
+    /**
+     * A builder that collects arguments to be shown on the content view with more options button.
+     */
     public static final class Builder {
         private String mDescription;
         private Executor mExecutor;
         private DialogInterface.OnClickListener mListener;
 
         /**
-         * Optional: Sets a description that will be shown on the content view.  Note that there are
-         * limits on the number of characters allowed for description.
+         * Optional: Sets a description that will be shown on the content view.
          *
          * @param description The description to display.
          * @return This builder.
@@ -149,7 +155,7 @@
         @RequiresPermission(SET_BIOMETRIC_DIALOG_ADVANCED)
         public Builder setDescription(@NonNull String description) {
             if (description.length() > MAX_DESCRIPTION_CHARACTER_NUMBER) {
-                throw new IllegalStateException("The character number of description exceeds "
+                throw new IllegalArgumentException("The character number of description exceeds "
                         + MAX_DESCRIPTION_CHARACTER_NUMBER);
             }
             mDescription = description;
diff --git a/core/java/android/hardware/biometrics/PromptVerticalListContentView.java b/core/java/android/hardware/biometrics/PromptVerticalListContentView.java
index 02b2a50..d8b2867 100644
--- a/core/java/android/hardware/biometrics/PromptVerticalListContentView.java
+++ b/core/java/android/hardware/biometrics/PromptVerticalListContentView.java
@@ -24,6 +24,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -47,9 +49,12 @@
  */
 @FlaggedApi(FLAG_CUSTOM_BIOMETRIC_PROMPT)
 public final class PromptVerticalListContentView implements PromptContentViewParcelable {
-    private static final int MAX_ITEM_NUMBER = 20;
-    private static final int MAX_EACH_ITEM_CHARACTER_NUMBER = 640;
-    private static final int MAX_DESCRIPTION_CHARACTER_NUMBER = 225;
+    @VisibleForTesting
+    static final int MAX_ITEM_NUMBER = 20;
+    @VisibleForTesting
+    static final int MAX_EACH_ITEM_CHARACTER_NUMBER = 640;
+    @VisibleForTesting
+    static final int MAX_DESCRIPTION_CHARACTER_NUMBER = 225;
 
     private final List<PromptContentItemParcelable> mContentList;
     private final String mDescription;
@@ -155,7 +160,7 @@
         @NonNull
         public Builder setDescription(@NonNull String description) {
             if (description.length() > MAX_DESCRIPTION_CHARACTER_NUMBER) {
-                throw new IllegalStateException("The character number of description exceeds "
+                throw new IllegalArgumentException("The character number of description exceeds "
                         + MAX_DESCRIPTION_CHARACTER_NUMBER);
             }
             mDescription = description;
@@ -195,12 +200,12 @@
 
         private void checkItemLimits(@NonNull PromptContentItem listItem) {
             if (doesListItemExceedsCharLimit(listItem)) {
-                throw new IllegalStateException(
+                throw new IllegalArgumentException(
                         "The character number of list item exceeds "
                                 + MAX_EACH_ITEM_CHARACTER_NUMBER);
             }
             if (mContentList.size() > MAX_ITEM_NUMBER) {
-                throw new IllegalStateException(
+                throw new IllegalArgumentException(
                         "The number of list items exceeds " + MAX_ITEM_NUMBER);
             }
         }
diff --git a/core/java/android/hardware/biometrics/flags.aconfig b/core/java/android/hardware/biometrics/flags.aconfig
index 9836eec..4284ad0 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/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 21c7004..c6a8762 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -19,8 +19,6 @@
 import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.companion.virtual.VirtualDeviceManager;
-import android.companion.virtual.camera.VirtualCameraConfig;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.hardware.camera2.impl.CameraMetadataNative;
 import android.hardware.camera2.impl.ExtensionKey;
@@ -41,7 +39,9 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * <p>The properties describing a
@@ -569,10 +569,23 @@
     @NonNull
     @FlaggedApi(Flags.FLAG_FEATURE_COMBINATION_QUERY)
     public List<CameraCharacteristics.Key<?>> getAvailableSessionCharacteristicsKeys() {
-        if (mAvailableSessionCharacteristicsKeys == null) {
-            mAvailableSessionCharacteristicsKeys =
-                    Arrays.asList(CONTROL_ZOOM_RATIO_RANGE, SCALER_AVAILABLE_MAX_DIGITAL_ZOOM);
+        if (mAvailableSessionCharacteristicsKeys != null) {
+            return mAvailableSessionCharacteristicsKeys;
         }
+
+        Integer queryVersion = get(INFO_SESSION_CONFIGURATION_QUERY_VERSION);
+        if (queryVersion == null) {
+            mAvailableSessionCharacteristicsKeys = List.of();
+            return mAvailableSessionCharacteristicsKeys;
+        }
+
+        mAvailableSessionCharacteristicsKeys =
+                AVAILABLE_SESSION_CHARACTERISTICS_KEYS_MAP.entrySet().stream()
+                        .filter(e -> e.getKey() <= queryVersion)
+                        .map(Map.Entry::getValue)
+                        .flatMap(Arrays::stream)
+                        .collect(Collectors.toUnmodifiableList());
+
         return mAvailableSessionCharacteristicsKeys;
     }
 
@@ -5334,10 +5347,9 @@
      * <p>Id of the device that owns this camera.</p>
      * <p>In case of a virtual camera, this would be the id of the virtual device
      * owning the camera. For any other camera, this key would not be present.
-     * Callers should assume {@link android.content.Context#DEVICE_ID_DEFAULT}
+     * Callers should assume {@link android.content.Context#DEVICE_ID_DEFAULT }
      * in case this key is not present.</p>
      * <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
-     *  @see VirtualDeviceManager.VirtualDevice#createVirtualCamera(VirtualCameraConfig)
      * @hide
      */
     public static final Key<Integer> INFO_DEVICE_ID =
@@ -6117,16 +6129,22 @@
     public static final Key<android.util.Range<Float>> EFV_PADDING_ZOOM_FACTOR_RANGE =
             new Key<android.util.Range<Float>>("android.efv.paddingZoomFactorRange", new TypeReference<android.util.Range<Float>>() {{ }});
 
+
+    /**
+     * Mapping from INFO_SESSION_CONFIGURATION_QUERY_VERSION to session characteristics key.
+     */
+    private static final Map<Integer, Key<?>[]> AVAILABLE_SESSION_CHARACTERISTICS_KEYS_MAP =
+            Map.ofEntries(
+                Map.entry(
+                    35,
+                    new Key<?>[] {
+                        CONTROL_ZOOM_RATIO_RANGE,
+                        SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
+                    }
+                )
+            );
+
     /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
      * End generated code
      *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
-
-
-
-
-
-
-
-
-
 }
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index ec9b013..dca663d 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -23,12 +23,14 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.graphics.SurfaceTexture;
 import android.hardware.camera2.params.ExtensionSessionConfiguration;
 import android.hardware.camera2.params.InputConfiguration;
 import android.hardware.camera2.params.OutputConfiguration;
 import android.hardware.camera2.params.SessionConfiguration;
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.os.Handler;
+import android.util.Size;
 import android.view.Surface;
 
 import com.android.internal.camera.flags.Flags;
@@ -530,9 +532,10 @@
      *   SurfaceTexture}: Set the size of the SurfaceTexture with {@link
      *   android.graphics.SurfaceTexture#setDefaultBufferSize} to be one of the sizes returned by
      *   {@link StreamConfigurationMap#getOutputSizes(Class) getOutputSizes(SurfaceTexture.class)}
-     *   before creating a Surface from the SurfaceTexture with {@link Surface#Surface}. If the size
-     *   is not set by the application, it will be set to be the smallest supported size less than
-     *   1080p, by the camera device.</li>
+     *   before creating a Surface from the SurfaceTexture with
+     *   {@link Surface#Surface(SurfaceTexture)}. If the size is not set by the application,
+     *   it will be set to be the smallest supported size less than 1080p, by the camera
+     *   device.</li>
      *
      * <li>For recording with {@link android.media.MediaCodec}: Call
      *   {@link android.media.MediaCodec#createInputSurface} after configuring
@@ -1405,10 +1408,16 @@
      *
      * <p><b>NOTE:</b>
      * For apps targeting {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM} and above,
-     * this method will ensure session parameters set through calls to
-     * {@link SessionConfiguration#setSessionParameters} are also supported if the Camera Device
-     * supports it. For apps targeting {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and
-     * below, session parameters will be ignored.</p>
+     * this method will automatically delegate to
+     * {@link CameraDeviceSetup#isSessionConfigurationSupported} whenever possible. This
+     * means that the output of this method will consider parameters set through
+     * {@link SessionConfiguration#setSessionParameters} as well.
+     * </p>
+     *
+     * <p>Session Parameters will be ignored for apps targeting <=
+     * {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, or if
+     * {@link CameraManager#isCameraDeviceSetupSupported} returns false for the camera id
+     * associated with this {@code CameraDevice}.</p>
      *
      * @return {@code true} if the given session configuration is supported by the camera device
      *         {@code false} otherwise.
@@ -1419,6 +1428,8 @@
      *                               encountered a fatal error
      * @throws IllegalStateException if the camera device has been closed
      *
+     * @see CameraManager#isCameraDeviceSetupSupported(String)
+     * @see CameraDeviceSetup#isSessionConfigurationSupported(SessionConfiguration)
      */
     public boolean isSessionConfigurationSupported(
             @NonNull SessionConfiguration sessionConfig) throws CameraAccessException {
@@ -1703,7 +1714,7 @@
          * SessionConfiguration} can then be created using the OutputConfiguration objects and
          * be used to query whether it's supported by the camera device. To create the
          * CameraCaptureSession, the application still needs to make sure all output surfaces
-         * are added via {@link OutputConfiguration#addSurfaces} with the exception of deferred
+         * are added via {@link OutputConfiguration#addSurface} with the exception of deferred
          * surfaces for {@link android.view.SurfaceView} and
          * {@link android.graphics.SurfaceTexture}.</li>
          * </ul>
@@ -1751,7 +1762,7 @@
          * SessionConfiguration} can then be created using the OutputConfiguration objects and
          * be used for this function. To create the CameraCaptureSession, the application still
          * needs to make sure all output surfaces are added via {@link
-         * OutputConfiguration#addSurfaces} with the exception of deferred surfaces for {@link
+         * OutputConfiguration#addSurface} with the exception of deferred surfaces for {@link
          * android.view.SurfaceView} and {@link android.graphics.SurfaceTexture}.</p>
          *
          * @param sessionConfig The session configuration for which characteristics are fetched.
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 8feb133..4cd40ea 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -112,6 +112,34 @@
     private static final int CAMERA_TYPE_BACKWARD_COMPATIBLE = 0;
     private static final int CAMERA_TYPE_ALL = 1;
 
+    /**
+     * Caches the mapping between a logical camera ID and 'MultiResolutionStreamConfigurationMap'
+     * that is calculated by {@link #getPhysicalCameraMultiResolutionConfigs} as the calculation
+     * might take many binder calls.
+     * <p>
+     * Note, this is a map of maps. The structure is:
+     * <pre>
+     * {
+     *     logicalCameraId_1 -> {
+     *         physicalCameraId_1 -> [
+     *             streamConfiguration_1,
+     *             streamConfiguration_2,
+     *             ...
+     *         ],
+     *         physicalCameraId_2 -> [...],
+     *         ...
+     *     },
+     *     logicalCameraId_2 -> {
+     *         ...
+     *     },
+     *     ...
+     * }
+     * </pre>
+     * </p>
+     */
+    private final Map<String, Map<String, StreamConfiguration[]>>
+            mCameraIdToMultiResolutionStreamConfigurationMap = new HashMap<>();
+
     private final Context mContext;
     private final Object mLock = new Object();
 
@@ -566,8 +594,14 @@
     private Map<String, StreamConfiguration[]> getPhysicalCameraMultiResolutionConfigs(
             String cameraId, CameraMetadataNative info, ICameraService cameraService)
             throws CameraAccessException {
+        if (mCameraIdToMultiResolutionStreamConfigurationMap.containsKey(cameraId)) {
+            return mCameraIdToMultiResolutionStreamConfigurationMap.get(cameraId);
+        }
+
         HashMap<String, StreamConfiguration[]> multiResolutionStreamConfigurations =
-                new HashMap<String, StreamConfiguration[]>();
+                new HashMap<>();
+        mCameraIdToMultiResolutionStreamConfigurationMap.put(cameraId,
+                multiResolutionStreamConfigurations);
 
         Boolean multiResolutionStreamSupported = info.get(
                 CameraCharacteristics.SCALER_MULTI_RESOLUTION_STREAM_SUPPORTED);
@@ -676,30 +710,10 @@
                         "Camera service is currently unavailable");
             }
             try {
-                Size displaySize = getDisplaySize();
-
                 CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId,
                         mContext.getApplicationInfo().targetSdkVersion, overrideToPortrait,
                         mContext.getDeviceId(), getDevicePolicyFromContext(mContext));
-                try {
-                    info.setCameraId(Integer.parseInt(cameraId));
-                } catch (NumberFormatException e) {
-                    Log.v(TAG, "Failed to parse camera Id " + cameraId + " to integer");
-                }
-
-                boolean hasConcurrentStreams =
-                        CameraManagerGlobal.get().cameraIdHasConcurrentStreamsLocked(cameraId,
-                                mContext.getDeviceId());
-                info.setHasMandatoryConcurrentStreams(hasConcurrentStreams);
-                info.setDisplaySize(displaySize);
-
-                Map<String, StreamConfiguration[]> multiResolutionSizeMap =
-                        getPhysicalCameraMultiResolutionConfigs(cameraId, info, cameraService);
-                if (multiResolutionSizeMap.size() > 0) {
-                    info.setMultiResolutionStreamConfigurationMap(multiResolutionSizeMap);
-                }
-
-                characteristics = new CameraCharacteristics(info);
+                characteristics = prepareCameraCharacteristics(cameraId, info, cameraService);
             } catch (ServiceSpecificException e) {
                 throw ExceptionUtils.throwAsPublicException(e);
             } catch (RemoteException e) {
@@ -712,6 +726,48 @@
         return characteristics;
     }
 
+
+    /**
+     * Utility method to take a {@link CameraMetadataNative} object and wrap it into a
+     * {@link CameraCharacteristics} object that has all required fields and keys set and is fit
+     * for apps to consume.
+     *
+     * @param cameraId      camera Id that the CameraMetadataNative was fetched for.
+     * @param metadata      base CameraMetadataNative to be wrapped
+     * @param cameraService remote cameraservice instance to be used if binder calls need
+     *                      to be made.
+     * @return A CameraCharacteristics object that can be used by the apps.
+     * @hide
+     */
+    @NonNull
+    public CameraCharacteristics prepareCameraCharacteristics(
+            @NonNull String cameraId, CameraMetadataNative metadata, ICameraService cameraService)
+            throws CameraAccessException {
+        synchronized (mLock) {
+            try {
+                metadata.setCameraId(Integer.parseInt(cameraId));
+            } catch (NumberFormatException e) {
+                Log.v(TAG, "Failed to parse camera Id " + cameraId + " to integer");
+            }
+
+            boolean hasConcurrentStreams =
+                    CameraManagerGlobal.get().cameraIdHasConcurrentStreamsLocked(cameraId,
+                            mContext.getDeviceId());
+            metadata.setHasMandatoryConcurrentStreams(hasConcurrentStreams);
+
+            Size displaySize = getDisplaySize();
+            metadata.setDisplaySize(displaySize);
+
+            Map<String, StreamConfiguration[]> multiResolutionSizeMap =
+                    getPhysicalCameraMultiResolutionConfigs(cameraId, metadata, cameraService);
+            if (!multiResolutionSizeMap.isEmpty()) {
+                metadata.setMultiResolutionStreamConfigurationMap(multiResolutionSizeMap);
+            }
+
+            return new CameraCharacteristics(metadata);
+        }
+    }
+
     /**
      * <p>Query the camera extension capabilities of a camera device.</p>
      *
@@ -1081,6 +1137,12 @@
      * {@link java.util.concurrent.Executor} as an argument instead of
      * {@link android.os.Handler}.</p>
      *
+     * <p>Do note that typically callbacks are expected to be dispatched
+     * by the executor in a single thread. If the executor uses two or
+     * more threads to dispatch callbacks, then clients must ensure correct
+     * synchronization and must also be able to handle potentially different
+     * ordering of the incoming callbacks.</p>
+     *
      * @param cameraId
      *             The unique identifier of the camera device to open
      * @param executor
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 6f901d7..735b20f 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -4454,13 +4454,4 @@
     /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
      * End generated code
      *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
-
-
-
-
-
-
-
-
-
 }
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 69b1c34..76287ca 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -6133,14 +6133,4 @@
     /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
      * End generated code
      *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
-
-
-
-
-
-
-
-
-
-
 }
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index 97c03ed..81bb9ac 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -290,6 +290,55 @@
         }
     };
 
+    private class ClientStateCallback extends StateCallback {
+        private final Executor mClientExecutor;
+        private final StateCallback mClientStateCallback;
+
+        private ClientStateCallback(@NonNull Executor clientExecutor,
+                @NonNull StateCallback clientStateCallback) {
+            mClientExecutor = clientExecutor;
+            mClientStateCallback = clientStateCallback;
+        }
+
+        public void onClosed(@NonNull CameraDevice camera) {
+            mClientExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    mClientStateCallback.onClosed(camera);
+                }
+            });
+        }
+        @Override
+        public void onOpened(@NonNull CameraDevice camera) {
+            mClientExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    mClientStateCallback.onOpened(camera);
+                }
+            });
+        }
+
+        @Override
+        public void onDisconnected(@NonNull CameraDevice camera) {
+            mClientExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    mClientStateCallback.onDisconnected(camera);
+                }
+            });
+        }
+
+        @Override
+        public void onError(@NonNull CameraDevice camera, int error) {
+            mClientExecutor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    mClientStateCallback.onError(camera, error);
+                }
+            });
+        }
+    }
+
     public CameraDeviceImpl(String cameraId, StateCallback callback, Executor executor,
                         CameraCharacteristics characteristics,
                         Map<String, CameraCharacteristics> physicalIdsToChars,
@@ -300,8 +349,13 @@
             throw new IllegalArgumentException("Null argument given");
         }
         mCameraId = cameraId;
-        mDeviceCallback = callback;
-        mDeviceExecutor = executor;
+        if (Flags.singleThreadExecutor()) {
+            mDeviceCallback = new ClientStateCallback(executor, callback);
+            mDeviceExecutor = Executors.newSingleThreadExecutor();
+        } else {
+            mDeviceCallback = callback;
+            mDeviceExecutor = executor;
+        }
         mCharacteristics = characteristics;
         mPhysicalIdsToChars = physicalIdsToChars;
         mAppTargetSdkVersion = appTargetSdkVersion;
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
index 24ac0b5..81d0976 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceSetupImpl.java
@@ -132,13 +132,14 @@
             }
 
             try {
-                CameraMetadataNative metadataNative = cameraService.getSessionCharacteristics(
+                CameraMetadataNative metadata = cameraService.getSessionCharacteristics(
                         mCameraId, mTargetSdkVersion,
                         CameraManager.shouldOverrideToPortrait(mContext), sessionConfig,
                         mContext.getDeviceId(),
                         mCameraManager.getDevicePolicyFromContext(mContext));
 
-                return new CameraCharacteristics(metadataNative);
+                return mCameraManager.prepareCameraCharacteristics(mCameraId, metadata,
+                        cameraService);
             } catch (ServiceSpecificException e) {
                 switch (e.errorCode) {
                     case ICameraService.ERROR_INVALID_OPERATION ->
diff --git a/core/java/android/hardware/devicestate/DeviceState.java b/core/java/android/hardware/devicestate/DeviceState.java
index 64fc4c2..e583627 100644
--- a/core/java/android/hardware/devicestate/DeviceState.java
+++ b/core/java/android/hardware/devicestate/DeviceState.java
@@ -399,16 +399,8 @@
         public void writeToParcel(@NonNull Parcel dest, int flags) {
             dest.writeInt(mIdentifier);
             dest.writeString8(mName);
-
-            dest.writeInt(mSystemProperties.size());
-            for (int i = 0; i < mSystemProperties.size(); i++) {
-                dest.writeInt(mSystemProperties.valueAt(i));
-            }
-
-            dest.writeInt(mPhysicalProperties.size());
-            for (int i = 0; i < mPhysicalProperties.size(); i++) {
-                dest.writeInt(mPhysicalProperties.valueAt(i));
-            }
+            dest.writeArraySet(mSystemProperties);
+            dest.writeArraySet(mPhysicalProperties);
         }
 
         @NonNull
@@ -417,16 +409,11 @@
             public DeviceState.Configuration createFromParcel(Parcel source) {
                 int identifier = source.readInt();
                 String name = source.readString8();
-                ArraySet<@DeviceStateProperties Integer> systemProperties = new ArraySet<>();
-                int systemPropertySize = source.readInt();
-                for (int i = 0; i < systemPropertySize; i++) {
-                    systemProperties.add(source.readInt());
-                }
-                ArraySet<@DeviceStateProperties Integer> physicalProperties = new ArraySet<>();
-                int physicalPropertySize = source.readInt();
-                for (int j = 0; j < physicalPropertySize; j++) {
-                    physicalProperties.add(source.readInt());
-                }
+                ArraySet<@SystemDeviceStateProperties Integer> systemProperties =
+                        (ArraySet<Integer>) source.readArraySet(null /* classLoader */);
+                ArraySet<@PhysicalDeviceStateProperties Integer> physicalProperties =
+                        (ArraySet<Integer>) source.readArraySet(null /* classLoader */);
+
                 return new DeviceState.Configuration(identifier, name, systemProperties,
                         physicalProperties);
             }
diff --git a/core/java/android/hardware/devicestate/OWNERS b/core/java/android/hardware/devicestate/OWNERS
new file mode 100644
index 0000000..d9b0e2e
--- /dev/null
+++ b/core/java/android/hardware/devicestate/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/devicestate/OWNERS
diff --git a/core/java/android/hardware/devicestate/feature/flags.aconfig b/core/java/android/hardware/devicestate/feature/flags.aconfig
index e474603..12d3f94 100644
--- a/core/java/android/hardware/devicestate/feature/flags.aconfig
+++ b/core/java/android/hardware/devicestate/feature/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.hardware.devicestate.feature.flags"
+container: "system"
 
 flag {
     name: "device_state_property_api"
diff --git a/core/java/android/hardware/face/FaceSensorConfigurations.java b/core/java/android/hardware/face/FaceSensorConfigurations.java
index 6ef692f..1247168 100644
--- a/core/java/android/hardware/face/FaceSensorConfigurations.java
+++ b/core/java/android/hardware/face/FaceSensorConfigurations.java
@@ -22,11 +22,12 @@
 import android.content.Context;
 import android.hardware.biometrics.face.IFace;
 import android.hardware.biometrics.face.SensorProps;
+import android.os.Binder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.util.Log;
-import android.util.Pair;
 import android.util.Slog;
 
 import androidx.annotation.NonNull;
@@ -36,7 +37,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
-import java.util.function.Function;
 
 /**
  * Provides the sensor props for face sensor, if available.
@@ -74,22 +74,10 @@
     /**
      * Process AIDL instances to extract sensor props and add it to the sensor map.
      * @param aidlInstances available face AIDL instances
-     * @param getIFace function that provides the daemon for the specific instance
      */
-    public void addAidlConfigs(@NonNull String[] aidlInstances,
-            @NonNull Function<String, IFace> getIFace) {
+    public void addAidlConfigs(@NonNull String[] aidlInstances) {
         for (String aidlInstance : aidlInstances) {
-            final String fqName = IFace.DESCRIPTOR + "/" + aidlInstance;
-            IFace face = getIFace.apply(fqName);
-            try {
-                if (face != null) {
-                    mSensorPropsMap.put(aidlInstance, face.getSensorProps());
-                } else {
-                    Slog.e(TAG, "Unable to get declared service: " + fqName);
-                }
-            } catch (RemoteException e) {
-                Log.d(TAG, "Unable to get sensor properties!");
-            }
+            mSensorPropsMap.put(aidlInstance, null);
         }
     }
 
@@ -131,38 +119,31 @@
     }
 
     /**
-     * Return sensor props for the given instance. If instance is not available,
-     * then null is returned.
+     * Checks if {@param instance} exists.
      */
     @Nullable
-    public Pair<String, SensorProps[]> getSensorPairForInstance(String instance) {
-        if (mSensorPropsMap.containsKey(instance)) {
-            return new Pair<>(instance, mSensorPropsMap.get(instance));
-        }
-
-        return null;
+    public boolean doesInstanceExist(String instance) {
+        return mSensorPropsMap.containsKey(instance);
     }
 
     /**
-     * Return the first pair of instance and sensor props, which does not correspond to the given
-     * If instance is not available, then null is returned.
+     * Return the first HAL instance, which does not correspond to the given {@param instance}.
+     * If another instance is not available, then null is returned.
      */
     @Nullable
-    public Pair<String, SensorProps[]> getSensorPairNotForInstance(String instance) {
+    public String getSensorNameNotForInstance(String instance) {
         Optional<String> notAVirtualInstance = mSensorPropsMap.keySet().stream().filter(
                 (instanceName) -> !instanceName.equals(instance)).findFirst();
-        return notAVirtualInstance.map(this::getSensorPairForInstance).orElseGet(
-                this::getSensorPair);
+        return notAVirtualInstance.orElse(null);
     }
 
     /**
-     * Returns the first pair of instance and sensor props that has been added to the map.
+     * Returns the first instance that has been added to the map.
      */
     @Nullable
-    public Pair<String, SensorProps[]> getSensorPair() {
+    public String getSensorInstance() {
         Optional<String> optionalInstance = mSensorPropsMap.keySet().stream().findFirst();
-        return optionalInstance.map(this::getSensorPairForInstance).orElse(null);
-
+        return optionalInstance.orElse(null);
     }
 
     public boolean getResetLockoutRequiresChallenge() {
@@ -179,4 +160,31 @@
         dest.writeByte((byte) (mResetLockoutRequiresChallenge ? 1 : 0));
         dest.writeMap(mSensorPropsMap);
     }
+
+    /**
+     * Returns face sensor props for the HAL {@param instance}.
+     */
+    @Nullable
+    public SensorProps[] getSensorPropForInstance(String instance) {
+        SensorProps[] props = mSensorPropsMap.get(instance);
+
+        //Props should not be null for HIDL configs
+        if (props != null) {
+            return props;
+        }
+
+        final String fqName = IFace.DESCRIPTOR + "/" + instance;
+        IFace face = IFace.Stub.asInterface(Binder.allowBlocking(
+                ServiceManager.waitForDeclaredService(fqName)));
+        try {
+            if (face != null) {
+                props = face.getSensorProps();
+            } else {
+                Slog.e(TAG, "Unable to get declared service: " + fqName);
+            }
+        } catch (RemoteException e) {
+            Log.d(TAG, "Unable to get sensor properties!");
+        }
+        return props;
+    }
 }
diff --git a/core/java/android/hardware/fingerprint/FingerprintSensorConfigurations.java b/core/java/android/hardware/fingerprint/FingerprintSensorConfigurations.java
index f214494a..43c0da9 100644
--- a/core/java/android/hardware/fingerprint/FingerprintSensorConfigurations.java
+++ b/core/java/android/hardware/fingerprint/FingerprintSensorConfigurations.java
@@ -23,18 +23,18 @@
 import android.content.Context;
 import android.hardware.biometrics.fingerprint.IFingerprint;
 import android.hardware.biometrics.fingerprint.SensorProps;
+import android.os.Binder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.util.Log;
-import android.util.Pair;
 
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
-import java.util.function.Function;
 
 /**
  * Provides the sensor props for fingerprint sensor, if available.
@@ -68,23 +68,10 @@
     /**
      * Process AIDL instances to extract sensor props and add it to the sensor map.
      * @param aidlInstances available face AIDL instances
-     * @param getIFingerprint function that provides the daemon for the specific instance
      */
-    public void addAidlSensors(@NonNull String[] aidlInstances,
-            @NonNull Function<String, IFingerprint> getIFingerprint) {
+    public void addAidlSensors(@NonNull String[] aidlInstances) {
         for (String aidlInstance : aidlInstances) {
-            try {
-                final String fqName = IFingerprint.DESCRIPTOR + "/" + aidlInstance;
-                final IFingerprint fp = getIFingerprint.apply(fqName);
-                if (fp != null) {
-                    SensorProps[] props = fp.getSensorProps();
-                    mSensorPropsMap.put(aidlInstance, props);
-                } else {
-                    Log.d(TAG, "IFingerprint null for instance " + aidlInstance);
-                }
-            } catch (RemoteException e) {
-                Log.d(TAG, "Unable to get sensor properties!");
-            }
+            mSensorPropsMap.put(aidlInstance, null);
         }
     }
 
@@ -133,38 +120,31 @@
     }
 
     /**
-     * Return sensor props for the given instance. If instance is not available,
-     * then null is returned.
+     * Checks if {@param instance} exists.
      */
     @Nullable
-    public Pair<String, SensorProps[]> getSensorPairForInstance(String instance) {
-        if (mSensorPropsMap.containsKey(instance)) {
-            return new Pair<>(instance, mSensorPropsMap.get(instance));
-        }
-
-        return null;
+    public boolean doesInstanceExist(String instance) {
+        return mSensorPropsMap.containsKey(instance);
     }
 
     /**
-     * Return the first pair of instance and sensor props, which does not correspond to the given
-     * If instance is not available, then null is returned.
+     * Return the first HAL instance, which does not correspond to the given {@param instance}.
+     * If another instance is not available, then null is returned.
      */
     @Nullable
-    public Pair<String, SensorProps[]> getSensorPairNotForInstance(String instance) {
+    public String getSensorNameNotForInstance(String instance) {
         Optional<String> notAVirtualInstance = mSensorPropsMap.keySet().stream().filter(
                 (instanceName) -> !instanceName.equals(instance)).findFirst();
-        return notAVirtualInstance.map(this::getSensorPairForInstance).orElseGet(
-                this::getSensorPair);
+        return notAVirtualInstance.orElse(null);
     }
 
     /**
-     * Returns the first pair of instance and sensor props that has been added to the map.
+     * Returns the first instance that has been added to the map.
      */
     @Nullable
-    public Pair<String, SensorProps[]> getSensorPair() {
+    public String getSensorInstance() {
         Optional<String> optionalInstance = mSensorPropsMap.keySet().stream().findFirst();
-        return optionalInstance.map(this::getSensorPairForInstance).orElse(null);
-
+        return optionalInstance.orElse(null);
     }
 
     public boolean getResetLockoutRequiresHardwareAuthToken() {
@@ -181,4 +161,31 @@
         dest.writeByte((byte) (mResetLockoutRequiresHardwareAuthToken ? 1 : 0));
         dest.writeMap(mSensorPropsMap);
     }
+
+    /**
+     * Returns fingerprint sensor props for the HAL {@param instance}.
+     */
+    @Nullable
+    public SensorProps[] getSensorPropForInstance(String instance) {
+        SensorProps[] props = mSensorPropsMap.get(instance);
+
+        //Props should not be null for HIDL configs
+        if (props != null) {
+            return props;
+        }
+
+        try {
+            final String fqName = IFingerprint.DESCRIPTOR + "/" + instance;
+            final IFingerprint fp = IFingerprint.Stub.asInterface(Binder.allowBlocking(
+                    ServiceManager.waitForDeclaredService(fqName)));
+            if (fp != null) {
+                props = fp.getSensorProps();
+            } else {
+                Log.d(TAG, "IFingerprint null for instance " + instance);
+            }
+        } catch (RemoteException e) {
+            Log.d(TAG, "Unable to get sensor properties!");
+        }
+        return props;
+    }
 }
diff --git a/core/java/android/hardware/flags/overlayproperties_flags.aconfig b/core/java/android/hardware/flags/overlayproperties_flags.aconfig
index 1165e65..6c86108 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/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java
index 09741e52..ac043d3 100644
--- a/core/java/android/hardware/hdmi/HdmiControlManager.java
+++ b/core/java/android/hardware/hdmi/HdmiControlManager.java
@@ -139,6 +139,16 @@
     public static final String EXTRA_LOCALE = "android.hardware.hdmi.extra.LOCALE";
 
     /**
+     * Broadcast Action: Active Source status was recovered by the device.
+     * <p>Send when device becomes the current active source such that the activity
+     * HdmiCecActiveSourceLostActivity can be finished and cleared from the screen.
+     * <p>Requires {@link android.Manifest.permission#HDMI_CEC} to receive.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_ON_ACTIVE_SOURCE_RECOVERED_DISMISS_UI =
+            "android.hardware.hdmi.action.ON_ACTIVE_SOURCE_RECOVERED_DISMISS_UI";
+    /**
      * Volume value for mute state.
      */
     public static final int AVR_VOLUME_MUTED = 101;
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index 9684e64..ed536ce 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 d0d10c1..c9ab62d 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 fac02ce..967fc42 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/hardware/usb/flags/usb_framework_flags.aconfig b/core/java/android/hardware/usb/flags/usb_framework_flags.aconfig
index 3dd746c..94df160 100644
--- a/core/java/android/hardware/usb/flags/usb_framework_flags.aconfig
+++ b/core/java/android/hardware/usb/flags/usb_framework_flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.hardware.usb.flags"
+container: "system"
 
 flag {
     name: "enable_is_pd_compliant_api"
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 2cd7aeb..cbfc5d1 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -56,6 +56,7 @@
 import static android.view.inputmethod.ConnectionlessHandwritingCallback.CONNECTIONLESS_HANDWRITING_ERROR_OTHER;
 import static android.view.inputmethod.ConnectionlessHandwritingCallback.CONNECTIONLESS_HANDWRITING_ERROR_UNSUPPORTED;
 import static android.view.inputmethod.Flags.FLAG_CONNECTIONLESS_HANDWRITING;
+import static android.view.inputmethod.Flags.ctrlShiftShortcut;
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
@@ -400,9 +401,14 @@
     private long mStylusHwSessionsTimeout = STYLUS_HANDWRITING_IDLE_TIMEOUT_MS;
     private Runnable mStylusWindowIdleTimeoutRunnable;
     private long mStylusWindowIdleTimeoutForTest;
-    /** Tracks last {@link MotionEvent#getToolType(int)} used for {@link MotionEvent#ACTION_DOWN}.
+    /**
+     * Tracks last {@link MotionEvent#getToolType(int)} used for {@link MotionEvent#ACTION_DOWN}.
      **/
     private int mLastUsedToolType;
+    /**
+     * Tracks the ctrl+shift shortcut
+     **/
+    private boolean mUsingCtrlShiftShortcut = false;
 
     /**
      * Returns whether {@link InputMethodService} is responsible for rendering the back button and
@@ -3612,7 +3618,8 @@
             // any KeyEvent keyDown should reset last toolType.
             updateEditorToolTypeInternal(MotionEvent.TOOL_TYPE_UNKNOWN);
         }
-        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
             final ExtractEditText eet = getExtractEditTextIfVisible();
             if (eet != null && eet.handleBackInTextActionModeIfNeeded(event)) {
                 return true;
@@ -3622,14 +3629,33 @@
                 return true;
             }
             return false;
-        } else if (event.getKeyCode() == KeyEvent.KEYCODE_SPACE && KeyEvent.metaStateHasModifiers(
+        } else if (keyCode == KeyEvent.KEYCODE_SPACE && KeyEvent.metaStateHasModifiers(
                 event.getMetaState() & ~KeyEvent.META_SHIFT_MASK, KeyEvent.META_CTRL_ON)) {
             if (mDecorViewVisible && mWindowVisible) {
                 int direction = (event.getMetaState() & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
                 mPrivOps.switchKeyboardLayoutAsync(direction);
+                event.startTracking();
                 return true;
             }
         }
+
+        // Check if this may be a ctrl+shift shortcut
+        if (ctrlShiftShortcut()) {
+            if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT
+                    || keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT) {
+                // Potentially Ctrl+Shift shortcut if Ctrl is currently pressed
+                mUsingCtrlShiftShortcut = KeyEvent.metaStateHasModifiers(
+                    event.getMetaState() & ~KeyEvent.META_SHIFT_MASK, KeyEvent.META_CTRL_ON);
+            } else if (keyCode == KeyEvent.KEYCODE_CTRL_LEFT
+                    || keyCode == KeyEvent.KEYCODE_CTRL_RIGHT) {
+                // Potentially Ctrl+Shift shortcut if Shift is currently pressed
+                mUsingCtrlShiftShortcut = KeyEvent.metaStateHasModifiers(
+                    event.getMetaState() & ~KeyEvent.META_CTRL_MASK, KeyEvent.META_SHIFT_ON);
+            } else {
+                mUsingCtrlShiftShortcut = false;
+            }
+        }
+
         return doMovementKey(keyCode, event, MOVEMENT_DOWN);
     }
 
@@ -3671,7 +3697,27 @@
      * them to perform navigation in the underlying application.
      */
     public boolean onKeyUp(int keyCode, KeyEvent event) {
-        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+        if (ctrlShiftShortcut()) {
+            if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT
+                    || keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT
+                    || keyCode == KeyEvent.KEYCODE_CTRL_LEFT
+                    || keyCode == KeyEvent.KEYCODE_CTRL_RIGHT) {
+                if (mUsingCtrlShiftShortcut
+                        && event.hasNoModifiers()) {
+                    mUsingCtrlShiftShortcut = false;
+                    if (mDecorViewVisible && mWindowVisible) {
+                        // Move to the next IME
+                        switchToNextInputMethod(false /* onlyCurrentIme */);
+                        // TODO(b/332937629): Make the event stream consistent again
+                        return true;
+                    }
+                }
+            } else {
+                mUsingCtrlShiftShortcut = false;
+            }
+        }
+
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
             final ExtractEditText eet = getExtractEditTextIfVisible();
             if (eet != null && eet.handleBackInTextActionModeIfNeeded(event)) {
                 return true;
@@ -3679,7 +3725,12 @@
             if (event.isTracking() && !event.isCanceled()) {
                 return handleBack(true);
             }
+        } else if (keyCode == KeyEvent.KEYCODE_SPACE) {
+            if (event.isTracking() && !event.isCanceled()) {
+                return true;
+            }
         }
+
         return doMovementKey(keyCode, event, MOVEMENT_UP);
     }
 
diff --git a/core/java/android/net/IVpnManager.aidl b/core/java/android/net/IVpnManager.aidl
index f302378..5149967 100644
--- a/core/java/android/net/IVpnManager.aidl
+++ b/core/java/android/net/IVpnManager.aidl
@@ -60,6 +60,12 @@
     LegacyVpnInfo getLegacyVpnInfo(int userId);
     boolean updateLockdownVpn();
 
+    /** Profile store APIs */
+    byte[] getFromVpnProfileStore(String name);
+    boolean putIntoVpnProfileStore(String name, in byte[] blob);
+    boolean removeFromVpnProfileStore(String name);
+    String[] listFromVpnProfileStore(String prefix);
+
     /** General system APIs */
     VpnConfig getVpnConfig(int userId);
     void factoryReset();
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index ff47f3f..c50bc56 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -717,4 +717,81 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Get the vpn profile owned by the calling uid with the given name from the vpn database.
+     *
+     * <p>Note this method should not be used for platform VPN profiles. </p>
+     *
+     * @param name The name of the profile to retrieve.
+     * @return the unstructured blob for the matching vpn profile.
+     * Returns null if no profile with a matching name was found.
+     * @hide
+     */
+    @Nullable
+    public byte[] getFromVpnProfileStore(@NonNull String name) {
+        try {
+            return mService.getFromVpnProfileStore(name);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Put the given vpn profile owned by the calling uid with the given name into the vpn database.
+     * Existing profiles with the same name will be replaced.
+     *
+     * <p>Note this method should not be used for platform VPN profiles.
+     * To update a platform VPN, use provisionVpnProfile() instead. </p>
+     *
+     * @param name The name of the profile to put.
+     * @param blob The profile.
+     * @return true if the profile was successfully added. False otherwise.
+     * @hide
+     */
+    public boolean putIntoVpnProfileStore(@NonNull String name, @NonNull byte[] blob) {
+        try {
+            return mService.putIntoVpnProfileStore(name, blob);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Removes the vpn profile owned by the calling uid with the given name from the vpn database.
+     *
+     * <p>Note this method should not be used for platform VPN profiles.
+     * To remove a platform VPN, use deleteVpnProfile() instead.</p>
+     *
+     * @param name The name of the profile to be removed.
+     * @return true if a profile was removed. False if no profile with a matching name was found.
+     * @hide
+     */
+    public boolean removeFromVpnProfileStore(@NonNull String name) {
+        try {
+            return mService.removeFromVpnProfileStore(name);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns a list of the name suffixes of the vpn profiles owned by the calling uid in the vpn
+     * database matching the given prefix, sorted in ascending order.
+     *
+     * <p>Note this method should not be used for platform VPN profiles. </p>
+     *
+     * @param prefix The prefix to match.
+     * @return an array of strings representing the name suffixes stored in the profile database
+     * matching the given prefix. The return value may be empty but never null.
+     * @hide
+     */
+    @NonNull
+    public String[] listFromVpnProfileStore(@NonNull String prefix) {
+        try {
+            return mService.listFromVpnProfileStore(prefix);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
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 e64823a..15d671d 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"
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 04d6f61..f785cca 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -210,6 +210,7 @@
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         public boolean hasSwappedOutPss;
 
+        // LINT.IfChange
         /** @hide */
         public static final int HEAP_UNKNOWN = 0;
         /** @hide */
@@ -311,6 +312,7 @@
         public static final int OTHER_ART_APP = 30;
         /** @hide */
         public static final int OTHER_ART_BOOT = 31;
+        // LINT.ThenChange(/system/memory/libmeminfo/include/meminfo/androidprocheaps.h)
         /** @hide */
         public static final int OTHER_DVK_STAT_ART_START = OTHER_ART_APP - NUM_OTHER_STATS;
         /** @hide */
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index bcef815..35a3a5f 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -577,6 +577,11 @@
             }
             res.mReadWriteHelper = ReadWriteHelper.DEFAULT;
         }
+
+        if (res.mNativePtr == 0) {
+            Log.e(TAG, "Obtained Parcel object has null native pointer. Invalid state.");
+        }
+
         return res;
     }
 
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index f4795f8..406a1a6 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -184,6 +184,22 @@
     public static final int DRAW_WAKE_LOCK = OsProtoEnums.DRAW_WAKE_LOCK; // 0x00000080
 
     /**
+     * Wake lock level: Override the current screen timeout.
+     * <p>
+     *  This is used by the system to allow {@code PowerManagerService} to override the current
+     *  screen timeout by config value.
+     *
+     *  config_screenTimeoutOverride in config.xml determines the screen timeout override value.
+     * </p><p>
+     * Requires the {@link android.Manifest.permission#SCREEN_TIMEOUT_OVERRIDE} permission.
+     * </p>
+     *
+     * @hide
+     */
+    public static final int SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK =
+            OsProtoEnums.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK; // 0x00000100
+
+    /**
      * Mask for the wake lock level component of a combined wake lock level and flags integer.
      *
      * @hide
@@ -1369,6 +1385,7 @@
             case PROXIMITY_SCREEN_OFF_WAKE_LOCK:
             case DOZE_WAKE_LOCK:
             case DRAW_WAKE_LOCK:
+            case SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK:
                 break;
             default:
                 throw new IllegalArgumentException("Must specify a valid wake lock level.");
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 8a17742..bb74a3e 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -1436,10 +1436,10 @@
      * @throws IOException if the recovery system service could not be contacted
      */
     private boolean requestLskf(String packageName, IntentSender sender) throws IOException {
-        Log.i(TAG, String.format("<%s> is requesting LSFK", packageName));
+        Log.i(TAG, TextUtils.formatSimple("Package<%s> requesting LSKF", packageName));
         try {
             boolean validRequest = mService.requestLskf(packageName, sender);
-            Log.i(TAG, String.format("LSKF Request isValid = %b", validRequest));
+            Log.i(TAG, TextUtils.formatSimple("LSKF Request isValid = %b", validRequest));
             return validRequest;
         } catch (RemoteException | SecurityException e) {
             throw new IOException("could not request LSKF capture", e);
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index f26a797..fd955e2 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -1,5 +1,6 @@
 package: "android.os"
 container: "system"
+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 229d119..eda755c 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/TEST_MAPPING b/core/java/android/permission/TEST_MAPPING
index 69113ef..a15d9bc 100644
--- a/core/java/android/permission/TEST_MAPPING
+++ b/core/java/android/permission/TEST_MAPPING
@@ -11,5 +11,29 @@
                 }
             ]
         }
+    ],
+    "postsubmit": [
+        {
+            "name": "CtsVirtualDevicesAudioTestCases",
+            "options": [
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "include-filter": "android.virtualdevice.cts.audio.VirtualAudioPermissionTest"
+                }
+            ]
+        },
+        {
+            "name": "CtsVirtualDevicesAppLaunchTestCases",
+            "options": [
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "include-filter": "android.virtualdevice.cts.applaunch.VirtualDevicePermissionTest"
+                }
+            ]
+        }
     ]
 }
\ No newline at end of file
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index 2710df2..c26f351 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"
@@ -116,6 +117,15 @@
 }
 
 flag {
+  name: "sensitive_content_improvements"
+  namespace: "permissions"
+  description: "Improvements to sensitive content/notification features, such as the Toast UX."
+  bug: "301960090"
+  # Referenced in WM where WM starts before DeviceConfig
+  is_fixed_read_only: true
+}
+
+flag {
     name: "device_aware_permissions_enabled"
     is_fixed_read_only: true
     namespace: "permissions"
@@ -147,3 +157,13 @@
     bug: "266164193"
 }
 
+flag {
+    name: "ignore_apex_permissions"
+    is_fixed_read_only: true
+    namespace: "permissions"
+    description: "Ignore APEX pacakges for permissions on V+"
+    bug: "301320911"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 363e252..b7d421a 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1266,6 +1266,22 @@
             "android.settings.BLUETOOTH_PAIRING_SETTINGS";
 
     /**
+     * Activity Action: Show settings to allow pairing hearing devices.
+     * <p>
+     * In some cases, a matching Activity may not exist, so ensure you
+     * safeguard against this.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_HEARING_DEVICE_PAIRING_SETTINGS =
+            "android.settings.HEARING_DEVICES_PAIRING_SETTINGS";
+
+    /**
      * Activity Action: Show settings to configure input methods, in particular
      * allowing the user to enable input methods.
      * <p>
@@ -10209,6 +10225,13 @@
                 "screensaver_complications_enabled";
 
         /**
+         * Defines the enabled state for the glanceable hub.
+         *
+         * @hide
+         */
+        public static final String GLANCEABLE_HUB_ENABLED = "glanceable_hub_enabled";
+
+        /**
          * Whether home controls are enabled to be shown over the screensaver by the user.
          *
          * @hide
@@ -12451,7 +12474,7 @@
         /** @hide */
         public static final int PRIVATE_SPACE_AUTO_LOCK_AFTER_INACTIVITY = 1;
         /** @hide */
-        public static final int PRIVATE_SPACE_AUTO_LOCK_NEVER = 2;
+        public static final int PRIVATE_SPACE_AUTO_LOCK_AFTER_DEVICE_RESTART = 2;
 
         /**
          * The different auto lock options for private space.
@@ -12461,7 +12484,7 @@
         @IntDef(prefix = {"PRIVATE_SPACE_AUTO_LOCK_"}, value = {
                 PRIVATE_SPACE_AUTO_LOCK_ON_DEVICE_LOCK,
                 PRIVATE_SPACE_AUTO_LOCK_AFTER_INACTIVITY,
-                PRIVATE_SPACE_AUTO_LOCK_NEVER,
+                PRIVATE_SPACE_AUTO_LOCK_AFTER_DEVICE_RESTART,
         })
         @Retention(RetentionPolicy.SOURCE)
         public @interface PrivateSpaceAutoLockOption {
@@ -15922,41 +15945,6 @@
                 = "forced_app_standby_for_small_battery_enabled";
 
         /**
-         * Whether to enable the TARE subsystem or not.
-         * Valid values are
-         * {@link android.app.tare.EconomyManager#ENABLE_TARE_ON EconomyManager.ENABLE_TARE_*}.
-         *
-         * @hide
-         */
-        public static final String ENABLE_TARE = "enable_tare";
-
-        /**
-         * Whether to show the TARE page in Developer Options or not.
-         * 1 = true, everything else = false
-         *
-         * @hide
-         */
-        public static final String SHOW_TARE_DEVELOPER_OPTIONS = "show_tare_developer_options";
-
-        /**
-         * Settings for AlarmManager's TARE EconomicPolicy (list of its economic factors).
-         *
-         * Keys are listed in {@link android.app.tare.EconomyManager}.
-         *
-         * @hide
-         */
-        public static final String TARE_ALARM_MANAGER_CONSTANTS = "tare_alarm_manager_constants";
-
-        /**
-         * Settings for JobScheduler's TARE EconomicPolicy (list of its economic factors).
-         *
-         * Keys are listed in {@link android.app.tare.EconomyManager}.
-         *
-         * @hide
-         */
-        public static final String TARE_JOB_SCHEDULER_CONSTANTS = "tare_job_scheduler_constants";
-
-        /**
          * Whether or not to enable the User Absent, Radios Off feature on small battery devices.
          * Type: int (0 for false, 1 for true)
          * Default: 0
diff --git a/core/java/android/provider/flags.aconfig b/core/java/android/provider/flags.aconfig
index d0cef83..77353c2 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: "a11y_standalone_fab_enabled"
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
index 7f5b550..02e787b 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"
diff --git a/core/java/android/security/responsible_apis_flags.aconfig b/core/java/android/security/responsible_apis_flags.aconfig
index 548f8aa..c7d951b 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/appprediction/flags/flags.aconfig b/core/java/android/service/appprediction/flags/flags.aconfig
index 7f9764e..953bc44 100644
--- a/core/java/android/service/appprediction/flags/flags.aconfig
+++ b/core/java/android/service/appprediction/flags/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.service.appprediction.flags"
+container: "system"
 
 flag {
   name: "service_features_api"
diff --git a/core/java/android/service/autofill/AutofillServiceInfo.java b/core/java/android/service/autofill/AutofillServiceInfo.java
index 83f9662..0e67477 100644
--- a/core/java/android/service/autofill/AutofillServiceInfo.java
+++ b/core/java/android/service/autofill/AutofillServiceInfo.java
@@ -312,6 +312,7 @@
             final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
             try {
                 if (serviceInfo != null && isCredentialManagerAutofillService(
+                        context,
                         serviceInfo.getComponentName())) {
                     // Skip this service as it is for internal use only
                     continue;
@@ -325,11 +326,23 @@
         return services;
     }
 
-    private static boolean isCredentialManagerAutofillService(ComponentName componentName) {
+    private static boolean isCredentialManagerAutofillService(Context context,
+            ComponentName componentName) {
         if (componentName == null) {
             return false;
         }
-        return componentName.equals(CREDMAN_SERVICE_COMPONENT_NAME);
+        ComponentName credAutofillService = null;
+        String credentialManagerAutofillCompName = context.getResources().getString(
+                R.string.config_defaultCredentialManagerAutofillService);
+        if (credentialManagerAutofillCompName != null && !credentialManagerAutofillCompName
+                .isEmpty()) {
+            credAutofillService = ComponentName.unflattenFromString(
+                    credentialManagerAutofillCompName);
+        } else {
+            Log.w(TAG, "Invalid CredentialAutofillService");
+        }
+
+        return componentName.equals(credAutofillService);
     }
 
     @Override
diff --git a/core/java/android/service/chooser/flags.aconfig b/core/java/android/service/chooser/flags.aconfig
index a3eff3b..d6425c3 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: "chooser_album_text"
diff --git a/core/java/android/service/controls/flags/flags.aconfig b/core/java/android/service/controls/flags/flags.aconfig
index 197f1bc..6f3a67d 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/credentials/CredentialProviderInfoFactory.java b/core/java/android/service/credentials/CredentialProviderInfoFactory.java
index 514d722..c6d3d9b 100644
--- a/core/java/android/service/credentials/CredentialProviderInfoFactory.java
+++ b/core/java/android/service/credentials/CredentialProviderInfoFactory.java
@@ -480,8 +480,12 @@
             Set<ComponentName> primaryServices) {
         requireNonNull(context, "context must not be null");
 
-        // Get the device policy.
-        PackagePolicy pp = getDeviceManagerPolicy(context, userId);
+        // Get the device policy. If the client has asked for all providers then we
+        // should ignore the device policy.
+        PackagePolicy pp =
+                providerFilter != CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_INCLUDING_HIDDEN
+                        ? getDeviceManagerPolicy(context, userId)
+                        : null;
 
         // Generate the provider list.
         final boolean disableSystemAppVerificationForTests = false;
@@ -514,8 +518,12 @@
             Set<ComponentName> primaryServices) {
         requireNonNull(context, "context must not be null");
 
-        // Get the device policy.
-        PackagePolicy pp = getDeviceManagerPolicy(context, userId);
+        // Get the device policy. If the client has asked for all providers then we
+        // should ignore the device policy.
+        PackagePolicy pp =
+                providerFilter != CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_INCLUDING_HIDDEN
+                        ? getDeviceManagerPolicy(context, userId)
+                        : null;
 
         // Generate the provider list.
         final boolean disableSystemAppVerificationForTests = true;
@@ -593,7 +601,10 @@
             if (cpi.isSystemProvider()) {
                 return mProviderFilter == CredentialManager.PROVIDER_FILTER_SYSTEM_PROVIDERS_ONLY;
             } else {
-                return mProviderFilter == CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY;
+                return mProviderFilter == CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY
+                        || mProviderFilter
+                                == CredentialManager
+                                        .PROVIDER_FILTER_USER_PROVIDERS_INCLUDING_HIDDEN;
             }
         }
 
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index 6dcbc8e..353828c 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -17,6 +17,7 @@
 package android.service.dreams;
 
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.service.dreams.Flags.dreamHandlesConfirmKeys;
 
 import android.annotation.FlaggedApi;
 import android.annotation.IdRes;
@@ -29,6 +30,7 @@
 import android.annotation.TestApi;
 import android.app.Activity;
 import android.app.AlarmManager;
+import android.app.KeyguardManager;
 import android.app.Service;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
@@ -280,6 +282,8 @@
 
     private IDreamOverlayCallback mOverlayCallback;
 
+    private Integer mTrackingConfirmKey = null;
+
 
     public DreamService() {
         mDreamManager = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE));
@@ -296,7 +300,54 @@
     /** {@inheritDoc} */
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
-        // TODO: create more flexible version of mInteractive that allows use of KEYCODE_BACK
+        if (dreamHandlesConfirmKeys()) {
+            // In the case of an interactive dream that consumes the event, do not process further.
+            if (mInteractive && mWindow.superDispatchKeyEvent(event)) {
+                return true;
+            }
+
+            // If the key is a confirm key and on up, either unlock (no auth) or show bouncer.
+            if (KeyEvent.isConfirmKey(event.getKeyCode())) {
+                switch (event.getAction()) {
+                    case KeyEvent.ACTION_DOWN -> {
+                        if (mTrackingConfirmKey != null) {
+                            return true;
+                        }
+
+                        mTrackingConfirmKey = event.getKeyCode();
+                    }
+                    case KeyEvent.ACTION_UP -> {
+                        if (mTrackingConfirmKey != event.getKeyCode()) {
+                            return true;
+                        }
+
+                        mTrackingConfirmKey = null;
+
+                        final KeyguardManager keyguardManager =
+                                getSystemService(KeyguardManager.class);
+
+                        // Simply wake up in the case the device is not locked.
+                        if (!keyguardManager.isKeyguardLocked()) {
+                            wakeUp();
+                            return true;
+                        }
+
+                        keyguardManager.requestDismissKeyguard(getActivity(),
+                                new KeyguardManager.KeyguardDismissCallback() {
+                                    @Override
+                                    public void onDismissError() {
+                                        Log.e(TAG, "Could not dismiss keyguard on confirm key");
+                                    }
+                                });
+                    }
+                }
+
+                // All key events for matching key codes should be consumed to prevent other actions
+                // from triggering.
+                return true;
+            }
+        }
+
         if (!mInteractive) {
             if (mDebug) Slog.v(mTag, "Waking up on keyEvent");
             wakeUp();
@@ -1050,12 +1101,10 @@
                     overlay.endDream();
                     mOverlayConnection.unbind();
                     mOverlayConnection = null;
-                    finish();
                 } catch (RemoteException e) {
                     Log.e(mTag, "could not inform overlay of dream end:" + e);
                 }
             });
-            return;
         }
 
         if (mDebug) Slog.v(mTag, "finish(): mFinished=" + mFinished);
diff --git a/core/java/android/service/dreams/flags.aconfig b/core/java/android/service/dreams/flags.aconfig
index 91a713e..2f45f34 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"
@@ -7,3 +8,14 @@
       "relying on the dream's window"
   bug: "291990564"
 }
+
+flag {
+  name: "dream_handles_confirm_keys"
+  namespace: "dreams"
+  description: "This flag enables dreams processing confirm keys to show the bouncer or dismiss "
+       "the keyguard"
+  bug: "326975875"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
diff --git a/core/java/android/service/notification/flags.aconfig b/core/java/android/service/notification/flags.aconfig
index 35cd3ed..b0c55a9 100644
--- a/core/java/android/service/notification/flags.aconfig
+++ b/core/java/android/service/notification/flags.aconfig
@@ -1,5 +1,6 @@
 package: "android.service.notification"
 container: "system"
+container: "system"
 
 flag {
   name: "ranking_update_ashmem"
diff --git a/core/java/android/service/ondeviceintelligence/IOnDeviceIntelligenceService.aidl b/core/java/android/service/ondeviceintelligence/IOnDeviceIntelligenceService.aidl
index a708718..45c4350 100644
--- a/core/java/android/service/ondeviceintelligence/IOnDeviceIntelligenceService.aidl
+++ b/core/java/android/service/ondeviceintelligence/IOnDeviceIntelligenceService.aidl
@@ -42,7 +42,7 @@
     void getReadOnlyFileDescriptor(in String fileName, in AndroidFuture<ParcelFileDescriptor> future);
     void getReadOnlyFeatureFileDescriptorMap(in Feature feature, in RemoteCallback remoteCallback);
     void requestFeatureDownload(int callerUid, in Feature feature,
-                                in AndroidFuture<ICancellationSignal> cancellationSignal,
+                                in AndroidFuture cancellationSignal,
                                 in IDownloadCallback downloadCallback);
     void registerRemoteServices(in IRemoteProcessingService remoteProcessingService);
     void notifyInferenceServiceConnected();
diff --git a/core/java/android/service/ondeviceintelligence/IOnDeviceSandboxedInferenceService.aidl b/core/java/android/service/ondeviceintelligence/IOnDeviceSandboxedInferenceService.aidl
index 4213a09..2aa17c4 100644
--- a/core/java/android/service/ondeviceintelligence/IOnDeviceSandboxedInferenceService.aidl
+++ b/core/java/android/service/ondeviceintelligence/IOnDeviceSandboxedInferenceService.aidl
@@ -36,15 +36,15 @@
 oneway interface IOnDeviceSandboxedInferenceService {
     void registerRemoteStorageService(in IRemoteStorageService storageService);
     void requestTokenInfo(int callerUid, in Feature feature, in Bundle request,
-                            in AndroidFuture<ICancellationSignal> cancellationSignal,
+                            in AndroidFuture cancellationSignal,
                             in ITokenInfoCallback tokenInfoCallback);
     void processRequest(int callerUid, in Feature feature, in Bundle request, in int requestType,
-                        in AndroidFuture<ICancellationSignal> cancellationSignal,
-                        in AndroidFuture<IProcessingSignal> processingSignal,
+                        in AndroidFuture cancellationSignal,
+                        in AndroidFuture processingSignal,
                         in IResponseCallback callback);
     void processRequestStreaming(int callerUid, in Feature feature, in Bundle request, in int requestType,
-                                in AndroidFuture<ICancellationSignal> cancellationSignal,
-                                in AndroidFuture<IProcessingSignal> processingSignal,
+                                in AndroidFuture cancellationSignal,
+                                in AndroidFuture processingSignal,
                                 in IStreamingResponseCallback callback);
     void updateProcessingState(in Bundle processingState,
                                      in IProcessingUpdateStatusCallback callback);
diff --git a/core/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java b/core/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java
index 5dc540a..793e58a 100644
--- a/core/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java
+++ b/core/java/android/service/ondeviceintelligence/OnDeviceIntelligenceService.java
@@ -35,7 +35,7 @@
 import android.app.ondeviceintelligence.IListFeaturesCallback;
 import android.app.ondeviceintelligence.OnDeviceIntelligenceException;
 import android.app.ondeviceintelligence.OnDeviceIntelligenceManager;
-import android.app.ondeviceintelligence.OnDeviceIntelligenceManager.InferenceParams;
+import android.app.ondeviceintelligence.OnDeviceIntelligenceManager.StateParams;
 import android.content.Intent;
 import android.os.Binder;
 import android.os.Bundle;
@@ -245,13 +245,13 @@
      * service if there is a state change to be performed. State change could be config updates,
      * performing initialization or cleanup tasks in the remote inference service.
      * The Bundle passed in here is expected to be read-only and will be rejected if it has any
-     * writable fields as detailed under {@link InferenceParams}.
+     * writable fields as detailed under {@link StateParams}.
      *
      * @param processingState  the updated state to be applied.
      * @param callbackExecutor executor to the run status callback on.
      * @param statusReceiver   receiver to get status of the update state operation.
      */
-    public final void updateProcessingState(@NonNull @InferenceParams Bundle processingState,
+    public final void updateProcessingState(@NonNull @StateParams Bundle processingState,
             @NonNull @CallbackExecutor Executor callbackExecutor,
             @NonNull OutcomeReceiver<PersistableBundle, OnDeviceIntelligenceException> statusReceiver) {
         Objects.requireNonNull(callbackExecutor);
diff --git a/core/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java b/core/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java
index 96c45ee..29a6db6 100644
--- a/core/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java
+++ b/core/java/android/service/ondeviceintelligence/OnDeviceSandboxedInferenceService.java
@@ -35,6 +35,7 @@
 import android.app.ondeviceintelligence.OnDeviceIntelligenceException;
 import android.app.ondeviceintelligence.OnDeviceIntelligenceManager;
 import android.app.ondeviceintelligence.OnDeviceIntelligenceManager.InferenceParams;
+import android.app.ondeviceintelligence.OnDeviceIntelligenceManager.StateParams;
 import android.app.ondeviceintelligence.ProcessingCallback;
 import android.app.ondeviceintelligence.ProcessingSignal;
 import android.app.ondeviceintelligence.StreamingProcessingCallback;
@@ -293,7 +294,7 @@
      * @param callback        callback to populate the update status and if there are params
      *                        associated with the status.
      */
-    public abstract void onUpdateProcessingState(@NonNull @InferenceParams Bundle processingState,
+    public abstract void onUpdateProcessingState(@NonNull @StateParams Bundle processingState,
             @NonNull OutcomeReceiver<PersistableBundle,
                     OnDeviceIntelligenceException> callback);
 
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
index e6d8fd0..8a3f6ce 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
@@ -71,9 +71,11 @@
 
     @Nullable
     static QuickAccessWalletServiceInfo tryCreate(@NonNull Context context) {
-        String defaultAppPackageName = getDefaultWalletApp(context);
+        String defaultAppPackageName = null;
 
-        if (defaultAppPackageName == null) {
+        if (isWalletRoleAvailable(context)) {
+            defaultAppPackageName = getDefaultWalletApp(context);
+        } else {
             ComponentName defaultPaymentApp = getDefaultPaymentApp(context);
             if (defaultPaymentApp == null) {
                 return null;
@@ -103,14 +105,21 @@
         final long token = Binder.clearCallingIdentity();
         try {
             RoleManager roleManager = context.getSystemService(RoleManager.class);
-            if (roleManager.isRoleAvailable(RoleManager.ROLE_WALLET)) {
-                List<String> roleHolders = roleManager.getRoleHolders(RoleManager.ROLE_WALLET);
-                return roleHolders.isEmpty() ? null : roleHolders.get(0);
-            }
+            List<String> roleHolders = roleManager.getRoleHolders(RoleManager.ROLE_WALLET);
+            return roleHolders.isEmpty() ? null : roleHolders.get(0);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
-        return null;
+    }
+
+    private static boolean isWalletRoleAvailable(Context context) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            RoleManager roleManager = context.getSystemService(RoleManager.class);
+            return roleManager.isRoleAvailable(RoleManager.ROLE_WALLET);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     private static ComponentName getDefaultPaymentApp(Context context) {
diff --git a/core/java/android/service/voice/flags/flags.aconfig b/core/java/android/service/voice/flags/flags.aconfig
index 1ae7d8c..357cb47 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/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index f6d197c..0fc51e7 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -106,6 +106,7 @@
 import android.window.ClientWindowFrames;
 import android.window.ScreenCapture;
 
+import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.HandlerCaller;
@@ -1283,8 +1284,14 @@
                                     .build();
                             SurfaceControl.Transaction transaction =
                                     new SurfaceControl.Transaction();
+                            final int frameRateCompat = getResources().getInteger(
+                                    R.integer.config_wallpaperFrameRateCompatibility);
+                            if (DEBUG) {
+                                Log.d(TAG, "Set frame rate compatibility value for Wallpaper: "
+                                        + frameRateCompat);
+                            }
                             transaction.setDefaultFrameRateCompatibility(mBbqSurfaceControl,
-                                Surface.FRAME_RATE_COMPATIBILITY_MIN).apply();
+                                    frameRateCompat).apply();
                         }
                         // Propagate transform hint from WM, so we can use the right hint for the
                         // first frame.
diff --git a/core/java/android/service/wearable/IWearableSensingService.aidl b/core/java/android/service/wearable/IWearableSensingService.aidl
index dffadf0..9d9cacf 100644
--- a/core/java/android/service/wearable/IWearableSensingService.aidl
+++ b/core/java/android/service/wearable/IWearableSensingService.aidl
@@ -17,6 +17,7 @@
 package android.service.wearable;
 
 import android.app.ambientcontext.AmbientContextEventRequest;
+import android.app.wearable.IWearableSensingCallback;
 import android.os.PersistableBundle;
 import android.os.RemoteCallback;
 import android.os.SharedMemory;
@@ -28,8 +29,8 @@
  * @hide
  */
 oneway interface IWearableSensingService {
-    void provideSecureConnection(in ParcelFileDescriptor parcelFileDescriptor, in RemoteCallback callback);
-    void provideDataStream(in ParcelFileDescriptor parcelFileDescriptor, in RemoteCallback callback);
+    void provideSecureConnection(in ParcelFileDescriptor parcelFileDescriptor, in IWearableSensingCallback wearableSensingCallback, in RemoteCallback statusCallback);
+    void provideDataStream(in ParcelFileDescriptor parcelFileDescriptor, in IWearableSensingCallback wearableSensingCallback, in RemoteCallback statusCallback);
     void provideData(in PersistableBundle data, in SharedMemory sharedMemory, in RemoteCallback callback);
     void registerDataRequestObserver(int dataType, in RemoteCallback dataRequestCallback, int dataRequestObserverId, in String packageName, in RemoteCallback statusCallback);
     void unregisterDataRequestObserver(int dataType, int dataRequestObserverId, in String packageName, in RemoteCallback statusCallback);
diff --git a/core/java/android/service/wearable/WearableSensingService.java b/core/java/android/service/wearable/WearableSensingService.java
index a277017..ac22e70 100644
--- a/core/java/android/service/wearable/WearableSensingService.java
+++ b/core/java/android/service/wearable/WearableSensingService.java
@@ -20,13 +20,16 @@
 import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.app.Service;
 import android.app.ambientcontext.AmbientContextEvent;
 import android.app.ambientcontext.AmbientContextEventRequest;
 import android.app.wearable.Flags;
+import android.app.wearable.IWearableSensingCallback;
 import android.app.wearable.WearableSensingDataRequest;
 import android.app.wearable.WearableSensingManager;
+import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -34,18 +37,28 @@
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteCallback;
+import android.os.RemoteException;
 import android.os.SharedMemory;
 import android.service.ambientcontext.AmbientContextDetectionResult;
 import android.service.ambientcontext.AmbientContextDetectionServiceStatus;
 import android.service.voice.HotwordAudioStream;
+import android.text.TextUtils;
 import android.util.Slog;
 import android.util.SparseArray;
 
+import com.android.internal.infra.AndroidFuture;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.time.Duration;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 import java.util.function.Consumer;
 
 /**
@@ -102,9 +115,14 @@
     public static final String SERVICE_INTERFACE =
             "android.service.wearable.WearableSensingService";
 
+    // Timeout to prevent thread from waiting on the openFile future indefinitely.
+    private static final Duration OPEN_FILE_TIMEOUT = Duration.ofSeconds(5);
+
     private final SparseArray<WearableSensingDataRequester> mDataRequestObserverIdToRequesterMap =
             new SparseArray<>();
 
+    private IWearableSensingCallback mWearableSensingCallback;
+
     @Nullable
     @Override
     public final IBinder onBind(@NonNull Intent intent) {
@@ -113,8 +131,13 @@
                 /** {@inheritDoc} */
                 @Override
                 public void provideSecureConnection(
-                        ParcelFileDescriptor secureWearableConnection, RemoteCallback callback) {
+                        ParcelFileDescriptor secureWearableConnection,
+                        IWearableSensingCallback wearableSensingCallback,
+                        RemoteCallback callback) {
                     Objects.requireNonNull(secureWearableConnection);
+                    if (wearableSensingCallback != null) {
+                        mWearableSensingCallback = wearableSensingCallback;
+                    }
                     Consumer<Integer> consumer = createWearableStatusConsumer(callback);
                     WearableSensingService.this.onSecureConnectionProvided(
                             secureWearableConnection, consumer);
@@ -123,8 +146,13 @@
                 /** {@inheritDoc} */
                 @Override
                 public void provideDataStream(
-                        ParcelFileDescriptor parcelFileDescriptor, RemoteCallback callback) {
+                        ParcelFileDescriptor parcelFileDescriptor,
+                        IWearableSensingCallback wearableSensingCallback,
+                        RemoteCallback callback) {
                     Objects.requireNonNull(parcelFileDescriptor);
+                    if (wearableSensingCallback != null) {
+                        mWearableSensingCallback = wearableSensingCallback;
+                    }
                     Consumer<Integer> consumer = createWearableStatusConsumer(callback);
                     WearableSensingService.this.onDataStreamProvided(
                             parcelFileDescriptor, consumer);
@@ -570,6 +598,64 @@
             @NonNull String packageName,
             @NonNull Consumer<AmbientContextDetectionServiceStatus> consumer);
 
+    /**
+     * Overrides {@link Context#openFileInput} to read files with the given {@code fileName} under
+     * the internal app storage of the APK providing the implementation for this class. {@link
+     * Context#getFilesDir()} will be added as a prefix to the provided {@code fileName}.
+     *
+     * <p>This method is only functional after {@link
+     * #onSecureConnectionProvided(ParcelFileDescriptor, Consumer)} or {@link
+     * #onDataStreamProvided(ParcelFileDescriptor, Consumer)} has been called as a result of a
+     * process owned by the same APK calling {@link
+     * WearableSensingManager#provideConnection(ParcelFileDescriptor, Executor, Consumer)} or {@link
+     * WearableSensingManager#provideDataStream(ParcelFileDescriptor, Executor, Consumer)}.
+     * Otherwise, it will throw an {@link IllegalStateException}. This is because this method
+     * proxies the file read via that process. Also, the APK needs to have a targetSdkVersion of 35
+     * or newer.
+     *
+     * @param fileName Relative path of a file under {@link Context#getFilesDir()}.
+     * @throws IllegalStateException if the above condition is not satisfied.
+     * @throws FileNotFoundException if the file does not exist or cannot be opened, or an error
+     *     occurred during the RPC to proxy the file read via a non-isolated process.
+     */
+    // SuppressLint is needed because the parent Context class does not specify the nullability of
+    // the parameter filename. If we remove the @NonNull annotation, the linter will complain about
+    // MissingNullability
+    @Override
+    public @NonNull FileInputStream openFileInput(
+            @SuppressLint("InvalidNullabilityOverride") @NonNull String fileName)
+            throws FileNotFoundException {
+        if (fileName == null) {
+            throw new IllegalArgumentException("filename cannot be null");
+        }
+        try {
+            if (mWearableSensingCallback == null) {
+                throw new IllegalStateException(
+                        "Cannot open file from WearableSensingService. WearableSensingCallback is"
+                                + " not available.");
+            }
+            AndroidFuture<ParcelFileDescriptor> future = new AndroidFuture<>();
+            mWearableSensingCallback.openFile(fileName, future);
+            ParcelFileDescriptor pfd =
+                    future.get(OPEN_FILE_TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
+            if (pfd == null) {
+                throw new FileNotFoundException(
+                        TextUtils.formatSimple(
+                                "File %s not found or unable to be opened in read-only mode.",
+                                fileName));
+            }
+            return new FileInputStream(pfd.getFileDescriptor());
+        } catch (RemoteException | ExecutionException | TimeoutException e) {
+            throw (FileNotFoundException)
+                    new FileNotFoundException("Cannot open file due to remote service failure")
+                            .initCause(e);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw (FileNotFoundException)
+                    new FileNotFoundException("Interrupted when opening a file.").initCause(e);
+        }
+    }
+
     @NonNull
     private static Integer[] intArrayToIntegerArray(@NonNull int[] integerSet) {
         Integer[] intArray = new Integer[integerSet.length];
diff --git a/core/java/android/speech/flags/speech_flags.aconfig b/core/java/android/speech/flags/speech_flags.aconfig
index fa33592..2a42357 100644
--- a/core/java/android/speech/flags/speech_flags.aconfig
+++ b/core/java/android/speech/flags/speech_flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.speech.flags"
+container: "system"
 
 flag {
     name: "multilang_extra_launch"
diff --git a/core/java/android/text/flags/flags.aconfig b/core/java/android/text/flags/flags.aconfig
index 8e1ac63..a8a0c5b 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"
@@ -52,6 +53,19 @@
 }
 
 flag {
+  name: "complete_font_load_in_system_services_ready"
+  namespace: "text"
+  description: "Fix to ensure that font loading is complete on system-services-ready boot phase."
+  # Make read only, as font loading is in the critical boot path which happens before the read-write
+  # flags propagate to the device.
+  is_fixed_read_only: true
+  bug: "327941215"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
   name: "phrase_strict_fallback"
   namespace: "text"
   description: "Feature flag for automatic fallback from phrase based line break to strict line break."
@@ -146,3 +160,14 @@
   description: "Feature flag for showing error message when user tries stylus handwriting on a text field which doesn't support it"
   bug: "297962571"
 }
+
+flag {
+  name: "fix_font_update_failure"
+  namespace: "text"
+  description: "There was a bug of updating system font from Android 13 to 14. This flag for fixing the migration failure."
+  is_fixed_read_only: true
+  bug: "331717791"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
diff --git a/core/java/android/tracing/flags.aconfig b/core/java/android/tracing/flags.aconfig
index cedba85..c50c384 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"
@@ -14,3 +15,10 @@
     bug: "276432490"
     is_fixed_read_only: true
 }
+
+flag {
+    name: "perfetto_ime_tracing"
+    namespace: "windowing_tools"
+    description: "Migrate IME tracing to Perfetto"
+    bug: "276433199"
+}
diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java
index 9db1060..de5fc7f 100644
--- a/core/java/android/view/InputWindowHandle.java
+++ b/core/java/android/view/InputWindowHandle.java
@@ -67,6 +67,7 @@
             InputConfig.SPY,
             InputConfig.INTERCEPTS_STYLUS,
             InputConfig.CLONE,
+            InputConfig.SENSITIVE_FOR_TRACING,
     })
     public @interface InputConfigFlags {}
 
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 90aafbd..b52003f 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -31,7 +31,6 @@
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
 
-import android.animation.AnimationHandler;
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.TypeEvaluator;
@@ -69,7 +68,6 @@
 import android.view.inputmethod.InputMethodManager;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
 import com.android.internal.inputmethod.ImeTracing;
 import com.android.internal.inputmethod.SoftInputShowHideReason;
 import com.android.internal.util.function.TriFunction;
@@ -142,10 +140,6 @@
          */
         @Appearance int getSystemBarsAppearance();
 
-        default boolean isSystemBarsAppearanceControlled() {
-            return false;
-        }
-
         /**
          * @see WindowInsetsController#setSystemBarsBehavior
          */
@@ -156,10 +150,6 @@
          */
         @Behavior int getSystemBarsBehavior();
 
-        default boolean isSystemBarsBehaviorControlled() {
-            return false;
-        }
-
         /**
          * Releases a surface and ensure that this is done after {@link #applySurfaceParams} has
          * finished applying params.
@@ -387,16 +377,6 @@
         private final WindowInsetsAnimationControlListener mLoggingListener;
         private final InputMethodJankContext mInputMethodJankContext;
 
-        private final ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal =
-                new ThreadLocal<AnimationHandler>() {
-            @Override
-            protected AnimationHandler initialValue() {
-                AnimationHandler handler = new AnimationHandler();
-                handler.setProvider(new SfVsyncFrameCallbackProvider());
-                return handler;
-            }
-        };
-
         public InternalAnimationControlListener(boolean show, boolean hasAnimationCallbacks,
                 @InsetsType int requestedTypes, @Behavior int behavior, boolean disable,
                 int floatingImeBottomInset, WindowInsetsAnimationControlListener loggingListener,
@@ -478,9 +458,6 @@
                     ImeTracker.forJank().onFinishAnimation(getAnimationType());
                 }
             });
-            if (!mHasAnimationCallbacks) {
-                mAnimator.setAnimationHandler(mSfAnimationHandlerThreadLocal.get());
-            }
             mAnimator.start();
         }
 
@@ -672,6 +649,9 @@
     private int mImeCaptionBarInsetsHeight = 0;
     private boolean mAnimationsDisabled;
     private boolean mCompatSysUiVisibilityStaled;
+    private @Appearance int mAppearanceControlled;
+    private @Appearance int mAppearanceFromResource;
+    private boolean mBehaviorControlled;
 
     private final Runnable mPendingControlTimeout = this::abortPendingImeControlRequest;
     private final ArrayList<OnControllableInsetsChangedListener> mControllableInsetsChangedListeners
@@ -1884,20 +1864,28 @@
 
     @Override
     public void setSystemBarsAppearance(@Appearance int appearance, @Appearance int mask) {
+        mAppearanceControlled |= mask;
         mHost.setSystemBarsAppearance(appearance, mask);
     }
 
     @Override
+    public void setSystemBarsAppearanceFromResource(@Appearance int appearance,
+            @Appearance int mask) {
+        mAppearanceFromResource = (mAppearanceFromResource & ~mask) | (appearance & mask);
+
+        // Don't change the flags which are already controlled by setSystemBarsAppearance.
+        mHost.setSystemBarsAppearance(appearance, mask & ~mAppearanceControlled);
+    }
+
+    @Override
     public @Appearance int getSystemBarsAppearance() {
-        @Appearance int appearance = mHost.getSystemBarsAppearance();
-
         // We only return the requested appearance, not the implied one.
-        appearance &= ~APPEARANCE_FORCE_LIGHT_NAVIGATION_BARS;
-        if (!mHost.isSystemBarsAppearanceControlled()) {
-            appearance &= ~COMPATIBLE_APPEARANCE_FLAGS;
-        }
+        return (mHost.getSystemBarsAppearance() & mAppearanceControlled)
+                | (mAppearanceFromResource & ~mAppearanceControlled);
+    }
 
-        return appearance;
+    public @Appearance int getAppearanceControlled() {
+        return mAppearanceControlled;
     }
 
     @Override
@@ -1949,18 +1937,23 @@
 
     @Override
     public void setSystemBarsBehavior(@Behavior int behavior) {
+        mBehaviorControlled = true;
         mHost.setSystemBarsBehavior(behavior);
     }
 
     @Override
     public @Behavior int getSystemBarsBehavior() {
-        if (!mHost.isSystemBarsBehaviorControlled()) {
+        if (!mBehaviorControlled) {
             // We only return the requested behavior, not the implied one.
-            return 0;
+            return BEHAVIOR_DEFAULT;
         }
         return mHost.getSystemBarsBehavior();
     }
 
+    public boolean isBehaviorControlled() {
+        return mBehaviorControlled;
+    }
+
     @Override
     public void setAnimationsDisabled(boolean disable) {
         mAnimationsDisabled = disable;
diff --git a/core/java/android/view/PendingInsetsController.java b/core/java/android/view/PendingInsetsController.java
index a4cbc52..00a5806 100644
--- a/core/java/android/view/PendingInsetsController.java
+++ b/core/java/android/view/PendingInsetsController.java
@@ -37,6 +37,8 @@
     private final ArrayList<PendingRequest> mRequests = new ArrayList<>();
     private @Appearance int mAppearance;
     private @Appearance int mAppearanceMask;
+    private @Appearance int mAppearanceFromResource;
+    private @Appearance int mAppearanceFromResourceMask;
     private @Behavior int mBehavior = KEEP_BEHAVIOR;
     private boolean mAnimationsDisabled;
     private final InsetsState mDummyState = new InsetsState();
@@ -79,11 +81,21 @@
     }
 
     @Override
+    public void setSystemBarsAppearanceFromResource(int appearance, int mask) {
+        if (mReplayedInsetsController != null) {
+            mReplayedInsetsController.setSystemBarsAppearanceFromResource(appearance, mask);
+        } else {
+            mAppearanceFromResource = (mAppearanceFromResource & ~mask) | (appearance & mask);
+            mAppearanceFromResourceMask |= mask;
+        }
+    }
+
+    @Override
     public int getSystemBarsAppearance() {
         if (mReplayedInsetsController != null) {
             return mReplayedInsetsController.getSystemBarsAppearance();
         }
-        return mAppearance;
+        return mAppearance | (mAppearanceFromResource & ~mAppearanceMask);
     }
 
     @Override
@@ -171,6 +183,10 @@
         if (mAppearanceMask != 0) {
             controller.setSystemBarsAppearance(mAppearance, mAppearanceMask);
         }
+        if (mAppearanceFromResourceMask != 0) {
+            controller.setSystemBarsAppearanceFromResource(
+                    mAppearanceFromResource, mAppearanceFromResourceMask);
+        }
         if (mCaptionInsetsHeight != 0) {
             controller.setCaptionInsetsHeight(mCaptionInsetsHeight);
         }
@@ -199,6 +215,8 @@
         mBehavior = KEEP_BEHAVIOR;
         mAppearance = 0;
         mAppearanceMask = 0;
+        mAppearanceFromResource = 0;
+        mAppearanceFromResourceMask = 0;
         mAnimationsDisabled = false;
         mLoggingListener = null;
         mRequestedVisibleTypes = WindowInsets.Type.defaultVisible();
diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java
index 147d562..17d1404 100644
--- a/core/java/android/view/PointerIcon.java
+++ b/core/java/android/view/PointerIcon.java
@@ -16,8 +16,10 @@
 
 package android.view;
 
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TestApi;
 import android.annotation.XmlRes;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
@@ -39,6 +41,7 @@
 import android.os.PointerIconType;
 import android.util.Log;
 import android.util.SparseArray;
+import android.view.flags.Flags;
 
 import com.android.internal.util.XmlUtils;
 
@@ -637,4 +640,15 @@
             default: return Integer.toString(type);
         }
     }
+
+    /**
+     * Sets whether drop shadow will draw in the native code.
+     *
+     * @hide
+     */
+    @TestApi
+    @FlaggedApi(Flags.FLAG_ENABLE_VECTOR_CURSORS)
+    public void setDrawNativeDropShadow(boolean drawNativeDropShadow) {
+        mDrawNativeDropShadow = drawNativeDropShadow;
+    }
 }
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 6c6e8b2..188ad8f 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -203,9 +203,7 @@
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"FRAME_RATE_COMPATIBILITY_"},
-            value = {FRAME_RATE_COMPATIBILITY_DEFAULT, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
-                    FRAME_RATE_COMPATIBILITY_EXACT, FRAME_RATE_COMPATIBILITY_NO_VOTE,
-                    FRAME_RATE_COMPATIBILITY_MIN, FRAME_RATE_COMPATIBILITY_GTE})
+            value = {FRAME_RATE_COMPATIBILITY_DEFAULT, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE})
     public @interface FrameRateCompatibility {}
 
     // From native_window.h. Keep these in sync.
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index cfdf8fa..1cd7d34 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -1272,7 +1272,7 @@
      * surface has no buffer or crop, the surface is boundless and only constrained
      * by the size of its parent bounds.
      *
-     * @param session  The surface session, must not be null.
+     * @param session  The surface session.
      * @param name     The surface name, must not be null.
      * @param w        The surface initial width.
      * @param h        The surface initial height.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b6df1bb..eb7de93 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -42,6 +42,8 @@
 import static android.view.flags.Flags.sensitiveContentAppProtection;
 import static android.view.flags.Flags.toolkitFrameRateBySizeReadOnly;
 import static android.view.flags.Flags.toolkitFrameRateDefaultNormalReadOnly;
+import static android.view.flags.Flags.toolkitFrameRateSmallUsesPercentReadOnly;
+import static android.view.flags.Flags.toolkitFrameRateViewEnablingReadOnly;
 import static android.view.flags.Flags.toolkitMetricsForFrameRateDecision;
 import static android.view.flags.Flags.toolkitSetFrameRateReadOnly;
 import static android.view.flags.Flags.viewVelocityApi;
@@ -224,6 +226,7 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
@@ -2431,6 +2434,16 @@
      */
     protected static boolean sToolkitSetFrameRateReadOnlyFlagValue;
     private static boolean sToolkitMetricsForFrameRateDecisionFlagValue;
+    private static final boolean sToolkitFrameRateDefaultNormalReadOnlyFlagValue =
+            toolkitFrameRateDefaultNormalReadOnly();
+    private static final boolean sToolkitFrameRateBySizeReadOnlyFlagValue =
+            toolkitFrameRateBySizeReadOnly();
+
+    private static final boolean sToolkitFrameRateSmallUsesPercentReadOnlyFlagValue =
+            toolkitFrameRateSmallUsesPercentReadOnly();
+    private static final boolean sToolkitFrameRateViewEnablingReadOnlyFlagValue =
+            toolkitFrameRateViewEnablingReadOnly();
+
     // Used to set frame rate compatibility.
     @Surface.FrameRateCompatibility int mFrameRateCompatibility =
             FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
@@ -3322,16 +3335,17 @@
     public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0x00000000;
 
     /**
-     * Live region mode specifying that accessibility services should announce
-     * changes to this view.
+     * Live region mode specifying that accessibility services should notify users of changes to
+     * this view.
      * <p>
      * Use with {@link #setAccessibilityLiveRegion(int)}.
      */
     public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 0x00000001;
 
     /**
-     * Live region mode specifying that accessibility services should interrupt
-     * ongoing speech to immediately announce changes to this view.
+     * Live region mode specifying that accessibility services should immediately notify users of
+     * changes to this view. For example, a screen reader may interrupt ongoing speech to
+     * immediately announce these changes.
      * <p>
      * Use with {@link #setAccessibilityLiveRegion(int)}.
      */
@@ -3764,6 +3778,8 @@
      *         1                        PFLAG4_ROTARY_HAPTICS_WAITING_FOR_SCROLL_EVENT
      *       11                         PFLAG4_CONTENT_SENSITIVITY_MASK
      *      1                           PFLAG4_IS_COUNTED_AS_SENSITIVE
+     *     1                            PFLAG4_HAS_DRAWN
+     *    1                             PFLAG4_HAS_MOVED
      * |-------|-------|-------|-------|
      */
 
@@ -3896,6 +3912,19 @@
      * @see AttachInfo#mSensitiveViewsCount
      */
     private static final int PFLAG4_IS_COUNTED_AS_SENSITIVE = 0x4000000;
+
+    /**
+     * Whether this view has been drawn once with updateDisplayListIfDirty() or not.
+     * Used by VRR to for quick detection of scrolling.
+     */
+    private static final int PFLAG4_HAS_DRAWN = 0x8000000;
+
+    /**
+     * Whether this view has been moved with either setTranslationX/Y or setLeft/Top.
+     * Used by VRR to for quick detection of scrolling.
+     */
+    private static final int PFLAG4_HAS_MOVED = 0x10000000;
+
     /* End of masks for mPrivateFlags4 */
 
     /** @hide */
@@ -5695,12 +5724,22 @@
     private ViewTranslationResponse mViewTranslationResponse;
 
     /**
-     * The multiplier for mAttachInfo.mSmallSizePixels to consider a View to be small
-     * if both dimensions are smaller than this.
+     * The size in DP that is considered small for VRR purposes, if square.
      */
-    private static final int FRAME_RATE_SQUARE_SMALL_SIZE_MULTIPLIER = 4;
+    private static final float FRAME_RATE_SQUARE_SMALL_SIZE_DP = 40f;
 
-    private static final long INFREQUENT_UPDATE_INTERVAL_MILLIS = 100;
+    /**
+     * The size in DP that is considered small for VRR purposes in the narrow dimension. Used for
+     * narrow Views like a progress bar.
+     */
+    private static final float FRAME_RATE_NARROW_SIZE_DP = 10f;
+
+    /**
+     * A threshold value to determine the frame rate category of the View based on the size.
+     */
+    private static final float FRAME_RATE_SIZE_PERCENTAGE_THRESHOLD = 0.07f;
+
+    private static final int INFREQUENT_UPDATE_INTERVAL_MILLIS = 100;
     private static final int INFREQUENT_UPDATE_COUNTS = 2;
 
     // The preferred frame rate of the view that is mainly used for
@@ -5712,16 +5751,13 @@
     /**
      * @hide
      */
-    protected long mMinusOneFrameIntervalMillis = 0;
+    protected int mMinusOneFrameIntervalMillis = 0;
     /**
      * @hide
      */
-    protected long mMinusTwoFrameIntervalMillis = 0;
+    protected int mMinusTwoFrameIntervalMillis = 0;
     private int mLastFrameRateCategory = FRAME_RATE_CATEGORY_NO_PREFERENCE;
 
-    private float mLastFrameX = Float.NaN;
-    private float mLastFrameY = Float.NaN;
-
     @FlaggedApi(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
     public static final float REQUESTED_FRAME_RATE_CATEGORY_DEFAULT = Float.NaN;
     @FlaggedApi(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
@@ -8763,14 +8799,17 @@
      *
      * <p>
      * When transitioning from one Activity to another, instead of using
-     * setAccessibilityPaneTitle(), set a descriptive title for its window by using android:label
-     * for the matching <activity> entry in your application’s manifest or updating the title at
-     * runtime with{@link android.app.Activity#setTitle(CharSequence)}.
+     * {@code setAccessibilityPaneTitle()}, set a descriptive title for its window by using
+     * {@code android:label}
+     * for the matching Activity entry in your application's manifest or updating the title at
+     * runtime with {@link android.app.Activity#setTitle(CharSequence)}.
      *
      * <p>
+     * <aside>
      * <b>Note:</b> Use
      * {@link androidx.core.view.ViewCompat#setAccessibilityPaneTitle(View, CharSequence)}
-     * for backwards-compatibility. </aside>
+     * for backwards-compatibility.
+     * </aside>
      * @param accessibilityPaneTitle The pane's title. Setting to {@code null} indicates that this
      *                               View is not a pane.
      *
@@ -8878,7 +8917,7 @@
      * They should not need to specify what exactly is announced to users.
      *
      * <p>
-     * In general, only announce transitions and don’t generate a confirmation message for simple
+     * In general, only announce transitions and don't generate a confirmation message for simple
      * actions like a button press. Label your controls concisely and precisely instead, and for
      * significant UI changes like window changes, use
      * {@link android.app.Activity#setTitle(CharSequence)} and
@@ -15271,33 +15310,56 @@
      * to the view's content description or text, or to the content descriptions
      * or text of the view's children (where applicable).
      * <p>
-     * To indicate that the user should be notified of changes, use
-     * {@link #ACCESSIBILITY_LIVE_REGION_POLITE}. Announcements from this region are queued and
-     * do not disrupt ongoing speech.
+     * Different priority levels are available:
+     * <ul>
+     *   <li>
+     *       {@link #ACCESSIBILITY_LIVE_REGION_POLITE}:
+     *       Indicates that updates to the region should be presented to the user. Suitable in most
+     *       cases for prominent updates within app content that don't require the user's immediate
+     *       attention.
+     *   </li>
+     *   <li>
+     *       {@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}: Indicates that updates to the region have
+     *       the highest priority and should be presented to the user immediately. This may result
+     *       in disruptive notifications from an accessibility service, which may potentially
+     *       interrupt other feedback or user actions, so it should generally be used only for
+     *       critical, time-sensitive information.
+     *   </li>
+     *   <li>
+     *       {@link #ACCESSIBILITY_LIVE_REGION_NONE}: Disables change announcements (the default for
+     *       most views).
+     *   </li>
+     * </ul>
      * <p>
-     * For example, selecting an option in a dropdown menu may update a panel below with the updated
-     * content. This panel may be marked as a live region with
-     * {@link #ACCESSIBILITY_LIVE_REGION_POLITE} to notify users of the change.
+     * Examples:
+     * <ul>
+     *     <li>
+     *         Selecting an option in a dropdown menu updates a panel below with the updated
+     *         content. This panel may be marked as a live region with
+     *         {@link #ACCESSIBILITY_LIVE_REGION_POLITE} to notify users of the change. A screen
+     *         reader may queue changes as announcements that don't disrupt ongoing speech.
+     *      </li>
+     *      <li>
+     *          An emergency alert may be marked with {@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}
+     *          to immediately inform users of the emergency.
+     *      </li>
+     * </ul>
      * <p>
-     * For notifying users about errors, such as in a login screen with text that displays an
-     * "incorrect password" notification, that view should send an AccessibilityEvent of type
+     * For error notifications, like an "incorrect password" warning in a login screen, views
+     * should send a {@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED}
+     * {@code AccessibilityEvent} with a content change type
      * {@link AccessibilityEvent#CONTENT_CHANGE_TYPE_ERROR} and set
-     * {@link AccessibilityNodeInfo#setError(CharSequence)} instead. Custom widgets should expose
-     * error-setting methods that support accessibility automatically. For example, instead of
-     * explicitly sending this event when using a TextView, use
-     * {@link android.widget.TextView#setError(CharSequence)}.
+     * {@link AccessibilityNodeInfo#setError(CharSequence)}. Custom widgets should provide
+     * error-setting methods that support accessibility. For example, use
+     * {@link android.widget.TextView#setError(CharSequence)} instead of explicitly sending events.
      * <p>
-     * To disable change notifications for this view, use
-     * {@link #ACCESSIBILITY_LIVE_REGION_NONE}. This is the default live region
-     * mode for most views.
+     * Don't use live regions for frequently-updating UI elements (e.g., progress bars), as this can
+     * overwhelm the user with feedback from accessibility services. If necessary, use
+     * {@link AccessibilityNodeInfo#setMinDurationBetweenContentChanges(Duration)} to throttle
+     * feedback and reduce disruptions.
      * <p>
-     * If the view's changes should interrupt ongoing speech and notify the user
-     * immediately, use {@link #ACCESSIBILITY_LIVE_REGION_ASSERTIVE}. This may result in disruptive
-     * announcements from an accessibility service, so it should generally be used only to convey
-     * information that is time-sensitive or critical for use of the application. Examples may
-     * include an incoming call or an emergency alert.
-     * <p>
-     * <b>Note:</b> Use {@link androidx.core.view.ViewCompat#setAccessibilityLiveRegion(View, int)}
+     * <aside><b>Note:</b> Use
+     * {@link androidx.core.view.ViewCompat#setAccessibilityLiveRegion(View, int)}
      * for backwards-compatibility. </aside>
      *
      * @param mode The live region mode for this view, one of:
@@ -19420,6 +19482,7 @@
      */
     public final void setTop(int top) {
         if (top != mTop) {
+            mPrivateFlags4 |= PFLAG4_HAS_MOVED;
             final boolean matrixIsIdentity = hasIdentityMatrix();
             if (matrixIsIdentity) {
                 if (mAttachInfo != null) {
@@ -19544,6 +19607,7 @@
      */
     public final void setLeft(int left) {
         if (left != mLeft) {
+            mPrivateFlags4 |= PFLAG4_HAS_MOVED;
             final boolean matrixIsIdentity = hasIdentityMatrix();
             if (matrixIsIdentity) {
                 if (mAttachInfo != null) {
@@ -19800,6 +19864,7 @@
     @RemotableViewMethod
     public void setTranslationX(float translationX) {
         if (translationX != getTranslationX()) {
+            mPrivateFlags4 |= PFLAG4_HAS_MOVED;
             invalidateViewProperty(true, false);
             mRenderNode.setTranslationX(translationX);
             invalidateViewProperty(false, true);
@@ -19836,6 +19901,7 @@
     @RemotableViewMethod
     public void setTranslationY(float translationY) {
         if (translationY != getTranslationY()) {
+            mPrivateFlags4 |= PFLAG4_HAS_MOVED;
             invalidateViewProperty(true, false);
             mRenderNode.setTranslationY(translationY);
             invalidateViewProperty(false, true);
@@ -20308,6 +20374,7 @@
      */
     public void offsetTopAndBottom(int offset) {
         if (offset != 0) {
+            mPrivateFlags4 |= PFLAG4_HAS_MOVED;
             final boolean matrixIsIdentity = hasIdentityMatrix();
             if (matrixIsIdentity) {
                 if (isHardwareAccelerated()) {
@@ -20359,6 +20426,7 @@
      */
     public void offsetLeftAndRight(int offset) {
         if (offset != 0) {
+            mPrivateFlags4 |= PFLAG4_HAS_MOVED;
             final boolean matrixIsIdentity = hasIdentityMatrix();
             if (matrixIsIdentity) {
                 if (isHardwareAccelerated()) {
@@ -20757,8 +20825,8 @@
         }
 
         // For VRR to vote the preferred frame rate
-        if (sToolkitSetFrameRateReadOnlyFlagValue) {
-            updateInfrequentCount();
+        if (sToolkitSetFrameRateReadOnlyFlagValue
+                && sToolkitFrameRateViewEnablingReadOnlyFlagValue) {
             votePreferredFrameRate();
         }
 
@@ -20865,8 +20933,8 @@
     protected void damageInParent() {
         if (mParent != null && mAttachInfo != null) {
             // For VRR to vote the preferred frame rate
-            if (sToolkitSetFrameRateReadOnlyFlagValue) {
-                updateInfrequentCount();
+            if (sToolkitSetFrameRateReadOnlyFlagValue
+                    && sToolkitFrameRateViewEnablingReadOnlyFlagValue) {
                 votePreferredFrameRate();
             }
             mParent.onDescendantInvalidated(this, this);
@@ -23556,8 +23624,11 @@
             return renderNode;
         }
 
-        mLastFrameX = mLeft + mRenderNode.getTranslationX();
-        mLastFrameY = mTop + mRenderNode.getTranslationY();
+        mPrivateFlags4 = (mPrivateFlags4 & ~PFLAG4_HAS_MOVED) | PFLAG4_HAS_DRAWN;
+        if (sToolkitSetFrameRateReadOnlyFlagValue
+                && sToolkitFrameRateViewEnablingReadOnlyFlagValue) {
+            updateInfrequentCount();
+        }
 
         if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0
                 || !renderNode.hasDisplayList()
@@ -25398,6 +25469,7 @@
         }
 
         if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {
+            mPrivateFlags4 |= PFLAG4_HAS_MOVED;
             changed = true;
 
             // Remember our drawn bit
@@ -25470,16 +25542,25 @@
     }
 
     private void sizeChange(int newWidth, int newHeight, int oldWidth, int oldHeight) {
-        if (mAttachInfo != null) {
-            int narrowSize = mAttachInfo.mSmallSizePixels;
-            int smallSize = narrowSize * FRAME_RATE_SQUARE_SMALL_SIZE_MULTIPLIER;
-            if (newWidth <= narrowSize || newHeight <= narrowSize
-                    || (newWidth <= smallSize && newHeight <= smallSize)) {
-                int category = toolkitFrameRateBySizeReadOnly()
+        if (mAttachInfo != null && sToolkitFrameRateViewEnablingReadOnlyFlagValue) {
+            boolean isSmall;
+            if (sToolkitFrameRateSmallUsesPercentReadOnlyFlagValue) {
+                int size = newWidth * newHeight;
+                float percent = size / mAttachInfo.mDisplayPixelCount;
+                isSmall = percent <= FRAME_RATE_SIZE_PERCENTAGE_THRESHOLD;
+            } else {
+                float density = mAttachInfo.mDensity;
+                int narrowSize = (int) (density * FRAME_RATE_NARROW_SIZE_DP);
+                int smallSize = (int) (density * FRAME_RATE_SQUARE_SMALL_SIZE_DP);
+                isSmall = newWidth <= narrowSize || newHeight <= narrowSize
+                        || (newWidth <= smallSize && newHeight <= smallSize);
+            }
+            if (isSmall) {
+                int category = sToolkitFrameRateBySizeReadOnlyFlagValue
                         ? FRAME_RATE_CATEGORY_LOW : FRAME_RATE_CATEGORY_NORMAL;
                 mSizeBasedFrameRateCategoryAndReason = category | FRAME_RATE_CATEGORY_REASON_SMALL;
             } else {
-                int category = toolkitFrameRateDefaultNormalReadOnly()
+                int category = sToolkitFrameRateDefaultNormalReadOnlyFlagValue
                         ? FRAME_RATE_CATEGORY_NORMAL : FRAME_RATE_CATEGORY_HIGH;
                 mSizeBasedFrameRateCategoryAndReason = category | FRAME_RATE_CATEGORY_REASON_LARGE;
             }
@@ -32051,11 +32132,19 @@
         int mSensitiveViewsCount;
 
         /**
-         * The size used for a View to be considered small for the purposes of using
-         * low refresh rate by default. This is the size in one direction, so a long, thin
-         * item like a progress bar can be compared to this.
+         * The value of viewVelocityApi(), read only once per ViewRootImpl
          */
-        final int mSmallSizePixels;
+        final boolean mViewVelocityApi = viewVelocityApi();
+
+        /**
+         * Density so that it doesn't need to be retrieved on every invalidation.
+         */
+        final float mDensity;
+
+        /**
+         * The number of pixels in the display (width * height).
+         */
+        final float mDisplayPixelCount;
 
         /**
          * Creates a new set of attachment information with the specified
@@ -32074,7 +32163,10 @@
             mHandler = handler;
             mRootCallbacks = effectPlayer;
             mTreeObserver = new ViewTreeObserver(context);
-            mSmallSizePixels = (int) (context.getResources().getDisplayMetrics().density * 10);
+            DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
+            mDensity = displayMetrics.density;
+            float pixelCount = (float) displayMetrics.widthPixels * displayMetrics.heightPixels;
+            mDisplayPixelCount = pixelCount == 0f ? Float.POSITIVE_INFINITY : pixelCount;
         }
 
         void increaseSensitiveViewsCount() {
@@ -33779,25 +33871,6 @@
         return null;
     }
 
-    private float getSizePercentage() {
-        float alpha = mTransformationInfo != null ? mTransformationInfo.mAlpha : 1;
-        int visibility = mViewFlags & VISIBILITY_MASK;
-
-        if (mResources == null || alpha == 0 || visibility != VISIBLE) {
-            return 0;
-        }
-
-        DisplayMetrics displayMetrics = mResources.getDisplayMetrics();
-        int screenSize = displayMetrics.widthPixels
-                * displayMetrics.heightPixels;
-        int viewSize = getWidth() * getHeight();
-
-        if (screenSize == 0 || viewSize == 0) {
-            return 0f;
-        }
-        return (float) viewSize / screenSize;
-    }
-
     /**
      * Used to calculate the frame rate category of a View.
      *
@@ -33820,18 +33893,19 @@
         ViewRootImpl viewRootImpl = getViewRootImpl();
         int width = mRight - mLeft;
         int height = mBottom - mTop;
-        if (viewRootImpl != null && (width != 0 && height != 0)) {
-            if (viewVelocityApi()) {
+        float alpha = mTransformationInfo != null ? mTransformationInfo.mAlpha : 1;
+        int visibility = mViewFlags & VISIBILITY_MASK;
+
+        if (viewRootImpl != null && (width != 0 && height != 0)
+                && alpha != 0 && visibility == View.VISIBLE
+        ) {
+            if (mAttachInfo.mViewVelocityApi) {
                 float velocity = mFrameContentVelocity;
-                if (velocity < 0f) {
+                int mask = PFLAG4_HAS_MOVED | PFLAG4_HAS_DRAWN;
+                if (velocity < 0f && (mPrivateFlags4 & mask) == mask) {
                     // This current calculation is very simple. If something on the screen moved,
                     // then it votes for the highest velocity. If it doesn't move, then return 0.
-                    RenderNode renderNode = mRenderNode;
-                    float x = mLeft + renderNode.getTranslationX();
-                    float y = mTop + renderNode.getTranslationY();
-
-                    velocity = (!Float.isNaN(mLastFrameX) && (x != mLastFrameX || y != mLastFrameY))
-                            ? 100_000f : 0f;
+                    velocity = Float.POSITIVE_INFINITY;
                 }
                 if (velocity > 0f) {
                     float frameRate = convertVelocityToFrameRate(velocity);
@@ -33841,41 +33915,34 @@
             }
             if (!willNotDraw()) {
                 if (sToolkitMetricsForFrameRateDecisionFlagValue) {
-                    float sizePercentage = getSizePercentage();
+                    float sizePercentage = width * height / mAttachInfo.mDisplayPixelCount;
                     viewRootImpl.recordViewPercentage(sizePercentage);
                 }
 
                 int frameRateCategory;
                 if (Float.isNaN(mPreferredFrameRate)) {
-                    if (mMinusTwoFrameIntervalMillis + mMinusOneFrameIntervalMillis
-                            < INFREQUENT_UPDATE_INTERVAL_MILLIS && mAttachInfo != null) {
-                        frameRateCategory = mSizeBasedFrameRateCategoryAndReason;
-                    } else if (mInfrequentUpdateCount == INFREQUENT_UPDATE_COUNTS) {
-                        frameRateCategory =
-                                FRAME_RATE_CATEGORY_NORMAL
-                                        | FRAME_RATE_CATEGORY_REASON_INTERMITTENT;
-                    } else {
-                        frameRateCategory = mLastFrameRateCategory;
-                    }
+                    frameRateCategory = calculateFrameRateCategory();
                 } else if (mPreferredFrameRate < 0) {
-                    if (mPreferredFrameRate == REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE) {
-                        frameRateCategory = FRAME_RATE_CATEGORY_NO_PREFERENCE
-                                | FRAME_RATE_CATEGORY_REASON_REQUESTED;
-                    } else if (mPreferredFrameRate == REQUESTED_FRAME_RATE_CATEGORY_LOW) {
-                        frameRateCategory = FRAME_RATE_CATEGORY_LOW
-                                | FRAME_RATE_CATEGORY_REASON_REQUESTED;
-                    } else if (mPreferredFrameRate == REQUESTED_FRAME_RATE_CATEGORY_NORMAL) {
-                        frameRateCategory = FRAME_RATE_CATEGORY_NORMAL
-                                | FRAME_RATE_CATEGORY_REASON_REQUESTED;
-                    } else if (mPreferredFrameRate == REQUESTED_FRAME_RATE_CATEGORY_HIGH) {
-                        frameRateCategory = FRAME_RATE_CATEGORY_HIGH
-                                | FRAME_RATE_CATEGORY_REASON_REQUESTED;
-                    } else {
-                        // invalid frame rate, use default
-                        int category = toolkitFrameRateDefaultNormalReadOnly()
-                                ? FRAME_RATE_CATEGORY_NORMAL : FRAME_RATE_CATEGORY_HIGH;
-                        frameRateCategory = category
-                                | FRAME_RATE_CATEGORY_REASON_INVALID;
+                    switch ((int) mPreferredFrameRate) {
+                        case (int) REQUESTED_FRAME_RATE_CATEGORY_NO_PREFERENCE ->
+                                frameRateCategory = FRAME_RATE_CATEGORY_NO_PREFERENCE
+                                        | FRAME_RATE_CATEGORY_REASON_REQUESTED;
+                        case (int) REQUESTED_FRAME_RATE_CATEGORY_LOW ->
+                                frameRateCategory = FRAME_RATE_CATEGORY_LOW
+                                        | FRAME_RATE_CATEGORY_REASON_REQUESTED;
+                        case (int) REQUESTED_FRAME_RATE_CATEGORY_NORMAL ->
+                                frameRateCategory = FRAME_RATE_CATEGORY_NORMAL
+                                        | FRAME_RATE_CATEGORY_REASON_REQUESTED;
+                        case (int) REQUESTED_FRAME_RATE_CATEGORY_HIGH ->
+                                frameRateCategory = FRAME_RATE_CATEGORY_HIGH
+                                        | FRAME_RATE_CATEGORY_REASON_REQUESTED;
+                        default -> {
+                            // invalid frame rate, use default
+                            int category = sToolkitFrameRateDefaultNormalReadOnlyFlagValue
+                                    ? FRAME_RATE_CATEGORY_NORMAL : FRAME_RATE_CATEGORY_HIGH;
+                            frameRateCategory = category
+                                    | FRAME_RATE_CATEGORY_REASON_INVALID;
+                        }
                     }
                 } else {
                     viewRootImpl.votePreferredFrameRate(mPreferredFrameRate,
@@ -33892,7 +33959,7 @@
     }
 
     private float convertVelocityToFrameRate(float velocityPps) {
-        float density = getResources().getDisplayMetrics().density;
+        float density = mAttachInfo.mDensity;
         float velocityDps = velocityPps / density;
         // Choose a frame rate in increments of 10fps
         return Math.min(140f, 60f + (10f * (float) Math.floor(velocityDps / 300f)));
@@ -33980,20 +34047,23 @@
      * - otherwise, use the previous category value.
      */
     private void updateInfrequentCount() {
-        long currentTimeMillis = getDrawingTime();
-        long timeIntervalMillis = currentTimeMillis - mLastUpdateTimeMillis;
-        mMinusTwoFrameIntervalMillis = mMinusOneFrameIntervalMillis;
-        mMinusOneFrameIntervalMillis = timeIntervalMillis;
+        if (!willNotDraw()) {
+            long currentTimeMillis = getDrawingTime();
+            int timeIntervalMillis =
+                    (int) Math.min(Integer.MAX_VALUE, currentTimeMillis - mLastUpdateTimeMillis);
+            mMinusTwoFrameIntervalMillis = mMinusOneFrameIntervalMillis;
+            mMinusOneFrameIntervalMillis = timeIntervalMillis;
 
-        mLastUpdateTimeMillis = currentTimeMillis;
-        if (mMinusTwoFrameIntervalMillis >= 30 && timeIntervalMillis < 2) {
-            return;
-        }
-        if (timeIntervalMillis >= INFREQUENT_UPDATE_INTERVAL_MILLIS) {
-            mInfrequentUpdateCount = mInfrequentUpdateCount == INFREQUENT_UPDATE_COUNTS
+            mLastUpdateTimeMillis = currentTimeMillis;
+            if (mMinusTwoFrameIntervalMillis >= 30 && timeIntervalMillis < 2) {
+                return;
+            }
+            if (timeIntervalMillis >= INFREQUENT_UPDATE_INTERVAL_MILLIS) {
+                mInfrequentUpdateCount = mInfrequentUpdateCount == INFREQUENT_UPDATE_COUNTS
                         ? mInfrequentUpdateCount : mInfrequentUpdateCount + 1;
-        } else {
-            mInfrequentUpdateCount = 0;
+            } else {
+                mInfrequentUpdateCount = 0;
+            }
         }
     }
 }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 0d9e471..da6cd40 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -34,13 +34,13 @@
 import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE;
 import static android.view.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
 import static android.view.Surface.FRAME_RATE_COMPATIBILITY_GTE;
-import static android.view.View.FRAME_RATE_CATEGORY_REASON_UNKNOWN;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_IDLE;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_INTERMITTENT;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_INVALID;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_LARGE;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_REQUESTED;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_SMALL;
+import static android.view.View.FRAME_RATE_CATEGORY_REASON_UNKNOWN;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_VELOCITY;
 import static android.view.View.PFLAG_DRAW_ANIMATION;
 import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
@@ -69,11 +69,10 @@
 import static android.view.ViewRootImplProto.WINDOW_ATTRIBUTES;
 import static android.view.ViewRootImplProto.WIN_FRAME;
 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
-import static android.view.WindowInsetsController.COMPATIBLE_APPEARANCE_FLAGS;
-import static android.view.flags.Flags.sensitiveContentAppProtection;
 import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
 import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
 import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
+import static android.view.WindowInsetsController.Appearance;
 import static android.view.WindowInsetsController.BEHAVIOR_DEFAULT;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 import static android.view.WindowLayout.UNSPECIFIED_LENGTH;
@@ -85,8 +84,6 @@
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APPEARANCE_CONTROLLED;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FIT_INSETS_CONTROLLED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
@@ -107,10 +104,13 @@
 import static android.view.accessibility.Flags.fixMergedContentChangeEventV2;
 import static android.view.accessibility.Flags.forceInvertColor;
 import static android.view.accessibility.Flags.reduceWindowContentChangedEventThrottle;
+import static android.view.flags.Flags.sensitiveContentAppProtection;
 import static android.view.flags.Flags.toolkitFrameRateTypingReadOnly;
+import static android.view.flags.Flags.toolkitFrameRateVelocityMappingReadOnly;
 import static android.view.flags.Flags.toolkitMetricsForFrameRateDecision;
 import static android.view.flags.Flags.toolkitSetFrameRateReadOnly;
 import static android.view.flags.Flags.toolkitFrameRateFunctionEnablingReadOnly;
+import static android.view.flags.Flags.toolkitFrameRateViewEnablingReadOnly;
 import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_FOCUS_CONTROLLER;
 import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INSETS_CONTROLLER;
 
@@ -1154,6 +1154,9 @@
     private static boolean sToolkitFrameRateFunctionEnablingReadOnlyFlagValue;
     private static boolean sToolkitMetricsForFrameRateDecisionFlagValue;
     private static boolean sToolkitFrameRateTypingReadOnlyFlagValue;
+    private static final boolean sToolkitFrameRateViewEnablingReadOnlyFlagValue;
+    private static boolean sToolkitFrameRateVelocityMappingReadOnlyFlagValue =
+            toolkitFrameRateVelocityMappingReadOnly();;
 
     static {
         sToolkitSetFrameRateReadOnlyFlagValue = toolkitSetFrameRateReadOnly();
@@ -1161,6 +1164,8 @@
         sToolkitFrameRateTypingReadOnlyFlagValue = toolkitFrameRateTypingReadOnly();
         sToolkitFrameRateFunctionEnablingReadOnlyFlagValue =
                 toolkitFrameRateFunctionEnablingReadOnly();
+        sToolkitFrameRateViewEnablingReadOnlyFlagValue =
+                toolkitFrameRateViewEnablingReadOnly();
     }
 
     // The latest input event from the gesture that was used to resolve the pointer icon.
@@ -1519,7 +1524,9 @@
                     mOrigWindowType = mWindowAttributes.type;
                     mAttachInfo.mRecomputeGlobalAttributes = true;
                     collectViewAttributes();
-                    adjustLayoutParamsForCompatibility(mWindowAttributes);
+                    adjustLayoutParamsForCompatibility(mWindowAttributes,
+                            mInsetsController.getAppearanceControlled(),
+                            mInsetsController.isBehaviorControlled());
                     controlInsetsForCompatibility(mWindowAttributes);
 
                     Rect attachedFrame = new Rect();
@@ -2035,8 +2042,6 @@
             // Preserve appearance and behavior.
             final int appearance = mWindowAttributes.insetsFlags.appearance;
             final int behavior = mWindowAttributes.insetsFlags.behavior;
-            final int appearanceAndBehaviorPrivateFlags = mWindowAttributes.privateFlags
-                    & (PRIVATE_FLAG_APPEARANCE_CONTROLLED | PRIVATE_FLAG_BEHAVIOR_CONTROLLED);
 
             final int changes = mWindowAttributes.copyFrom(attrs);
             if ((changes & WindowManager.LayoutParams.TRANSLUCENT_FLAGS_CHANGED) != 0) {
@@ -2059,7 +2064,6 @@
             mWindowAttributes.subtreeSystemUiVisibility = subtreeSystemUiVisibility;
             mWindowAttributes.insetsFlags.appearance = appearance;
             mWindowAttributes.insetsFlags.behavior = behavior;
-            mWindowAttributes.privateFlags |= appearanceAndBehaviorPrivateFlags;
 
             if (mWindowAttributes.preservePreviousSurfaceInsets) {
                 // Restore old surface insets.
@@ -2624,8 +2628,10 @@
         // no longer needed if the dVRR feature is disabled.
         if (shouldEnableDvrr()) {
             try {
-                mFrameRateTransaction.setFrameRateSelectionStrategy(sc,
+                if (sToolkitFrameRateFunctionEnablingReadOnlyFlagValue) {
+                    mFrameRateTransaction.setFrameRateSelectionStrategy(sc,
                         sc.FRAME_RATE_SELECTION_STRATEGY_SELF).applyAsyncUnsafe();
+                }
             } catch (Exception e) {
                 Log.e(mTag, "Unable to set frame rate selection strategy ", e);
             }
@@ -2913,26 +2919,35 @@
     }
 
     @VisibleForTesting
-    public static void adjustLayoutParamsForCompatibility(WindowManager.LayoutParams inOutParams) {
+    public static void adjustLayoutParamsForCompatibility(WindowManager.LayoutParams inOutParams,
+            @Appearance int appearanceControlled, boolean behaviorControlled) {
         final int sysUiVis = inOutParams.systemUiVisibility | inOutParams.subtreeSystemUiVisibility;
         final int flags = inOutParams.flags;
         final int type = inOutParams.type;
         final int adjust = inOutParams.softInputMode & SOFT_INPUT_MASK_ADJUST;
 
-        if ((inOutParams.privateFlags & PRIVATE_FLAG_APPEARANCE_CONTROLLED) == 0) {
-            inOutParams.insetsFlags.appearance &= ~COMPATIBLE_APPEARANCE_FLAGS;
-            if ((sysUiVis & SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
-                inOutParams.insetsFlags.appearance |= APPEARANCE_LOW_PROFILE_BARS;
-            }
-            if ((sysUiVis & SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0) {
-                inOutParams.insetsFlags.appearance |= APPEARANCE_LIGHT_STATUS_BARS;
-            }
-            if ((sysUiVis & SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) != 0) {
-                inOutParams.insetsFlags.appearance |= APPEARANCE_LIGHT_NAVIGATION_BARS;
-            }
+        @Appearance int appearance = inOutParams.insetsFlags.appearance;
+        if ((appearanceControlled & APPEARANCE_LOW_PROFILE_BARS) == 0) {
+            appearance &= ~APPEARANCE_LOW_PROFILE_BARS;
+            appearance |= (sysUiVis & SYSTEM_UI_FLAG_LOW_PROFILE) != 0
+                    ? APPEARANCE_LOW_PROFILE_BARS
+                    : 0;
         }
+        if ((appearanceControlled & APPEARANCE_LIGHT_STATUS_BARS) == 0) {
+            appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
+            appearance |= (sysUiVis & SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0
+                    ? APPEARANCE_LIGHT_STATUS_BARS
+                    : 0;
+        }
+        if ((appearanceControlled & APPEARANCE_LIGHT_NAVIGATION_BARS) == 0) {
+            appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS;
+            appearance |= (sysUiVis & SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) != 0
+                    ? APPEARANCE_LIGHT_NAVIGATION_BARS
+                    : 0;
+        }
+        inOutParams.insetsFlags.appearance = appearance;
 
-        if ((inOutParams.privateFlags & PRIVATE_FLAG_BEHAVIOR_CONTROLLED) == 0) {
+        if (!behaviorControlled) {
             if ((sysUiVis & SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0
                     || (flags & FLAG_FULLSCREEN) != 0) {
                 inOutParams.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
@@ -3482,7 +3497,9 @@
                     && !PixelFormat.formatHasAlpha(params.format)) {
                 params.format = PixelFormat.TRANSLUCENT;
             }
-            adjustLayoutParamsForCompatibility(params);
+            adjustLayoutParamsForCompatibility(params,
+                    mInsetsController.getAppearanceControlled(),
+                    mInsetsController.isBehaviorControlled());
             controlInsetsForCompatibility(params);
             if (mDispatchedSystemBarAppearance != params.insetsFlags.appearance) {
                 mDispatchedSystemBarAppearance = params.insetsFlags.appearance;
@@ -6367,6 +6384,12 @@
                     return "MSG_KEEP_CLEAR_RECTS_CHANGED";
                 case MSG_REFRESH_POINTER_ICON:
                     return "MSG_REFRESH_POINTER_ICON";
+                case MSG_TOUCH_BOOST_TIMEOUT:
+                    return "MSG_TOUCH_BOOST_TIMEOUT";
+                case MSG_CHECK_INVALIDATION_IDLE:
+                    return "MSG_CHECK_INVALIDATION_IDLE";
+                case MSG_FRAME_RATE_SETTING:
+                    return "MSG_FRAME_RATE_SETTING";
             }
             return super.getMessageName(message);
         }
@@ -6571,10 +6594,15 @@
                     // Use the newer global config and last reported override config.
                     mPendingMergedConfiguration.setConfiguration(config,
                             mLastReportedMergedConfiguration.getOverrideConfiguration());
+                    if (mPendingActivityWindowInfo != null) {
+                        mPendingActivityWindowInfo.set(mLastReportedActivityWindowInfo);
+                    }
 
                     performConfigurationChange(new MergedConfiguration(mPendingMergedConfiguration),
                             false /* force */, INVALID_DISPLAY /* same display */,
-                            mLastReportedActivityWindowInfo);
+                            mPendingActivityWindowInfo != null
+                                    ? new ActivityWindowInfo(mPendingActivityWindowInfo)
+                                    : null);
                 } break;
                 case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
                     setAccessibilityFocus(null, null);
@@ -9016,6 +9044,7 @@
                     mPendingActivityWindowInfo.set(outInfo);
                 }
             }
+            mRelayoutBundle.clear();
             mWinFrameInScreen.set(mTmpFrames.frame);
             if (mTranslator != null) {
                 mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);
@@ -12463,7 +12492,9 @@
     }
 
     private void setPreferredFrameRateCategory(int preferredFrameRateCategory) {
-        if (!shouldSetFrameRateCategory()) {
+        if (!shouldSetFrameRateCategory()
+                || (mFrameRateCompatibility == FRAME_RATE_COMPATIBILITY_GTE
+                && sToolkitFrameRateVelocityMappingReadOnlyFlagValue)) {
             return;
         }
         int categoryFromConflictedFrameRates = FRAME_RATE_CATEGORY_NO_PREFERENCE;
@@ -12517,9 +12548,11 @@
                                     + category + ", reason " + reason + ", "
                                     + sourceView);
                 }
-                mFrameRateTransaction.setFrameRateCategory(mSurfaceControl,
+                if (sToolkitFrameRateFunctionEnablingReadOnlyFlagValue) {
+                    mFrameRateTransaction.setFrameRateCategory(mSurfaceControl,
                         frameRateCategory, false).applyAsyncUnsafe();
-                mLastPreferredFrameRateCategory = frameRateCategory;
+                    mLastPreferredFrameRateCategory = frameRateCategory;
+                }
             }
         } catch (Exception e) {
             Log.e(mTag, "Unable to set frame rate category", e);
@@ -12558,8 +12591,12 @@
     }
 
     private void setPreferredFrameRate(float preferredFrameRate) {
-        if (!shouldSetFrameRate() || (mFrameRateCompatibility == FRAME_RATE_COMPATIBILITY_GTE
-                && preferredFrameRate > 0)) {
+        if (!shouldSetFrameRate()) {
+            return;
+        }
+        if (mFrameRateCompatibility == FRAME_RATE_COMPATIBILITY_GTE
+                && preferredFrameRate > 0 && !sToolkitFrameRateVelocityMappingReadOnlyFlagValue) {
+            mIsTouchBoosting = false;
             return;
         }
 
@@ -12572,9 +12609,11 @@
                                 + preferredFrameRate + " compatibility "
                                 + mFrameRateCompatibility);
                 }
-                mFrameRateTransaction.setFrameRate(mSurfaceControl, preferredFrameRate,
+                if (sToolkitFrameRateFunctionEnablingReadOnlyFlagValue) {
+                    mFrameRateTransaction.setFrameRate(mSurfaceControl, preferredFrameRate,
                     mFrameRateCompatibility).applyAsyncUnsafe();
-                mLastPreferredFrameRate = preferredFrameRate;
+                    mLastPreferredFrameRate = preferredFrameRate;
+                }
             }
         } catch (Exception e) {
             Log.e(mTag, "Unable to set frame rate", e);
@@ -12617,14 +12656,14 @@
      */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
     public void votePreferredFrameRateCategory(int frameRateCategory, int reason, View view) {
-        if (frameRateCategory == FRAME_RATE_CATEGORY_HIGH) {
-            mFrameRateCategoryHighCount = FRAME_RATE_CATEGORY_COUNT;
-        } else if (frameRateCategory == FRAME_RATE_CATEGORY_HIGH_HINT) {
-            mFrameRateCategoryHighHintCount = FRAME_RATE_CATEGORY_COUNT;
-        } else if (frameRateCategory == FRAME_RATE_CATEGORY_NORMAL) {
-            mFrameRateCategoryNormalCount = FRAME_RATE_CATEGORY_COUNT;
-        } else if (frameRateCategory == FRAME_RATE_CATEGORY_LOW) {
-            mFrameRateCategoryLowCount = FRAME_RATE_CATEGORY_COUNT;
+        switch (frameRateCategory) {
+            case FRAME_RATE_CATEGORY_LOW -> mFrameRateCategoryLowCount = FRAME_RATE_CATEGORY_COUNT;
+            case FRAME_RATE_CATEGORY_NORMAL ->
+                    mFrameRateCategoryNormalCount = FRAME_RATE_CATEGORY_COUNT;
+            case FRAME_RATE_CATEGORY_HIGH_HINT ->
+                    mFrameRateCategoryHighHintCount = FRAME_RATE_CATEGORY_COUNT;
+            case FRAME_RATE_CATEGORY_HIGH ->
+                    mFrameRateCategoryHighCount = FRAME_RATE_CATEGORY_COUNT;
         }
 
         int oldCategory = mPreferredFrameRateCategory;
@@ -12801,7 +12840,7 @@
 
     private boolean shouldEnableDvrr() {
         // uncomment this when we are ready for enabling dVRR
-        if (sToolkitFrameRateFunctionEnablingReadOnlyFlagValue) {
+        if (sToolkitFrameRateViewEnablingReadOnlyFlagValue) {
             return sToolkitSetFrameRateReadOnlyFlagValue && isFrameRatePowerSavingsBalanced();
         }
         return false;
diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java
index 4214141..b66c59a 100644
--- a/core/java/android/view/ViewRootInsetsControllerHost.java
+++ b/core/java/android/view/ViewRootInsetsControllerHost.java
@@ -17,9 +17,6 @@
 package android.view;
 
 import static android.view.InsetsController.DEBUG;
-import static android.view.WindowInsetsController.COMPATIBLE_APPEARANCE_FLAGS;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APPEARANCE_CONTROLLED;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
 
 import android.annotation.NonNull;
 import android.content.Context;
@@ -174,9 +171,6 @@
 
     @Override
     public void setSystemBarsAppearance(int appearance, int mask) {
-        if ((mask & COMPATIBLE_APPEARANCE_FLAGS) != 0) {
-            mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_APPEARANCE_CONTROLLED;
-        }
         final InsetsFlags insetsFlags = mViewRoot.mWindowAttributes.insetsFlags;
         final int newAppearance = (insetsFlags.appearance & ~mask) | (appearance & mask);
         if (insetsFlags.appearance != newAppearance) {
@@ -192,13 +186,7 @@
     }
 
     @Override
-    public boolean isSystemBarsAppearanceControlled() {
-        return (mViewRoot.mWindowAttributes.privateFlags & PRIVATE_FLAG_APPEARANCE_CONTROLLED) != 0;
-    }
-
-    @Override
     public void setSystemBarsBehavior(int behavior) {
-        mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
         if (mViewRoot.mWindowAttributes.insetsFlags.behavior != behavior) {
             mViewRoot.mWindowAttributes.insetsFlags.behavior = behavior;
             mViewRoot.mWindowAttributesChanged = true;
@@ -212,11 +200,6 @@
     }
 
     @Override
-    public boolean isSystemBarsBehaviorControlled() {
-        return (mViewRoot.mWindowAttributes.privateFlags & PRIVATE_FLAG_BEHAVIOR_CONTROLLED) != 0;
-    }
-
-    @Override
     public void releaseSurfaceControlFromRt(SurfaceControl surfaceControl) {
 
          // At the time we receive new leashes (e.g. InsetsSourceConsumer is processing
diff --git a/core/java/android/view/WindowInsetsController.java b/core/java/android/view/WindowInsetsController.java
index 7601ffa..1ffffb3 100644
--- a/core/java/android/view/WindowInsetsController.java
+++ b/core/java/android/view/WindowInsetsController.java
@@ -101,14 +101,6 @@
     int APPEARANCE_FORCE_LIGHT_NAVIGATION_BARS = 1 << 9;
 
     /**
-     * Appearance flags that can be implied from system UI flags.
-     * @hide
-     */
-    int COMPATIBLE_APPEARANCE_FLAGS = APPEARANCE_LOW_PROFILE_BARS
-            | APPEARANCE_LIGHT_STATUS_BARS
-            | APPEARANCE_LIGHT_NAVIGATION_BARS;
-
-    /**
      * Determines the appearance of system bars.
      * @hide
      */
@@ -271,10 +263,23 @@
     void setSystemBarsAppearance(@Appearance int appearance, @Appearance int mask);
 
     /**
+     * Similar to {@link #setSystemBarsAppearance} but the given flag will only take effect when it
+     * is not controlled by {@link #setSystemBarsAppearance}.
+     *
+     * @see WindowInsetsController#getSystemBarsAppearance()
+     * @see android.R.attr#windowLightStatusBar
+     * @see android.R.attr#windowLightNavigationBar
+     * @hide
+     */
+    void setSystemBarsAppearanceFromResource(@Appearance int appearance, @Appearance int mask);
+
+    /**
      * Retrieves the requested appearance of system bars.
      *
      * @return The requested bitmask of system bar appearance controlled by this window.
      * @see #setSystemBarsAppearance(int, int)
+     * @see android.R.attr#windowLightStatusBar
+     * @see android.R.attr#windowLightNavigationBar
      */
     @Appearance int getSystemBarsAppearance();
 
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 5666739..59cb450 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -104,6 +104,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.PixelFormat;
@@ -1490,7 +1491,13 @@
         }
 
         try {
-            return ActivityTaskManager.supportsMultiWindow(ActivityThread.currentApplication());
+            final Context context = ActivityThread.currentApplication();
+            if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+                // Watch supports multi-window to present essential system UI, but it doesn't need
+                // WM Extensions.
+                return false;
+            }
+            return ActivityTaskManager.supportsMultiWindow(context);
         } catch (Exception e) {
             // In case the PackageManager is not set up correctly in test.
             Log.e("WindowManager", "Unable to read if the device supports multi window", e);
@@ -3433,20 +3440,6 @@
         public static final int PRIVATE_FLAG_CONSUME_IME_INSETS = 1 << 25;
 
         /**
-         * Flag to indicate that the window is controlling the appearance of system bars. So we
-         * don't need to adjust it by reading its system UI flags for compatibility.
-         * @hide
-         */
-        public static final int PRIVATE_FLAG_APPEARANCE_CONTROLLED = 1 << 26;
-
-        /**
-         * Flag to indicate that the window is controlling the behavior of system bars. So we don't
-         * need to adjust it by reading its window flags or system UI flags for compatibility.
-         * @hide
-         */
-        public static final int PRIVATE_FLAG_BEHAVIOR_CONTROLLED = 1 << 27;
-
-        /**
          * Flag to indicate that the window is controlling how it fits window insets on its own.
          * So we don't need to adjust its attributes for fitting window insets.
          * @hide
@@ -3517,8 +3510,6 @@
                 PRIVATE_FLAG_NOT_MAGNIFIABLE,
                 PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
                 PRIVATE_FLAG_CONSUME_IME_INSETS,
-                PRIVATE_FLAG_APPEARANCE_CONTROLLED,
-                PRIVATE_FLAG_BEHAVIOR_CONTROLLED,
                 PRIVATE_FLAG_FIT_INSETS_CONTROLLED,
                 PRIVATE_FLAG_TRUSTED_OVERLAY,
                 PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME,
@@ -3619,14 +3610,6 @@
                         equals = PRIVATE_FLAG_CONSUME_IME_INSETS,
                         name = "CONSUME_IME_INSETS"),
                 @ViewDebug.FlagToString(
-                        mask = PRIVATE_FLAG_APPEARANCE_CONTROLLED,
-                        equals = PRIVATE_FLAG_APPEARANCE_CONTROLLED,
-                        name = "APPEARANCE_CONTROLLED"),
-                @ViewDebug.FlagToString(
-                        mask = PRIVATE_FLAG_BEHAVIOR_CONTROLLED,
-                        equals = PRIVATE_FLAG_BEHAVIOR_CONTROLLED,
-                        name = "BEHAVIOR_CONTROLLED"),
-                @ViewDebug.FlagToString(
                         mask = PRIVATE_FLAG_FIT_INSETS_CONTROLLED,
                         equals = PRIVATE_FLAG_FIT_INSETS_CONTROLLED,
                         name = "FIT_INSETS_CONTROLLED"),
@@ -4370,6 +4353,22 @@
         public static final int INPUT_FEATURE_SPY = 1 << 2;
 
         /**
+         * Input feature used to indicate that this window is sensitive for tracing.
+         * <p>
+         * A window that uses {@link LayoutParams#FLAG_SECURE} will automatically be treated as
+         * a sensitive for input tracing, but this input feature can be set on windows that don't
+         * set FLAG_SECURE. The tracing configuration will determine how these sensitive events
+         * are eventually traced.
+         * <p>
+         * This can only be set for trusted system overlays.
+         * <p>
+         * Note: Input tracing is only available on userdebug and eng builds.
+         *
+         * @hide
+         */
+        public static final int INPUT_FEATURE_SENSITIVE_FOR_TRACING = 1 << 3;
+
+        /**
          * An internal annotation for flags that can be specified to {@link #inputFeatures}.
          *
          * NOTE: These are not the same as {@link android.os.InputConfig} flags.
@@ -4381,6 +4380,7 @@
                 INPUT_FEATURE_NO_INPUT_CHANNEL,
                 INPUT_FEATURE_DISABLE_USER_ACTIVITY,
                 INPUT_FEATURE_SPY,
+                INPUT_FEATURE_SENSITIVE_FOR_TRACING,
         })
         public @interface InputFeatureFlags {
         }
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 9708591..3fc9ebc 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -69,7 +69,6 @@
 
 import com.android.internal.R;
 import com.android.internal.accessibility.common.ShortcutConstants;
-import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IntPair;
 
@@ -161,22 +160,6 @@
     public static final String ACTION_CHOOSE_ACCESSIBILITY_BUTTON =
             "com.android.internal.intent.action.CHOOSE_ACCESSIBILITY_BUTTON";
 
-    /**
-     * Used as an int value for accessibility chooser activity to represent the accessibility button
-     * shortcut type.
-     *
-     * @hide
-     */
-    public static final int ACCESSIBILITY_BUTTON = 0;
-
-    /**
-     * Used as an int value for accessibility chooser activity to represent hardware key shortcut,
-     * such as volume key button.
-     *
-     * @hide
-     */
-    public static final int ACCESSIBILITY_SHORTCUT_KEY = 1;
-
     /** @hide */
     public static final int FLASH_REASON_CALL = 1;
 
@@ -190,35 +173,6 @@
     public static final int FLASH_REASON_PREVIEW = 4;
 
     /**
-     * Annotations for the shortcut type.
-     * <p>Note: Keep in sync with {@link #SHORTCUT_TYPES}.</p>
-     * @hide
-     */
-    // TODO(b/323686675): reuse the one defined in ShortcutConstants
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            // LINT.IfChange(shortcut_type_intdef)
-            ACCESSIBILITY_BUTTON,
-            ACCESSIBILITY_SHORTCUT_KEY,
-            UserShortcutType.QUICK_SETTINGS,
-            // LINT.ThenChange(:shortcut_type_array)
-    })
-    public @interface ShortcutType {}
-
-    /**
-     * Used for iterating through {@link ShortcutType}.
-     * <p>Note: Keep in sync with {@link ShortcutType}.</p>
-     * @hide
-     */
-    public static final int[] SHORTCUT_TYPES = {
-            // LINT.IfChange(shortcut_type_array)
-            ACCESSIBILITY_BUTTON,
-            ACCESSIBILITY_SHORTCUT_KEY,
-            UserShortcutType.QUICK_SETTINGS,
-            // LINT.ThenChange(:shortcut_type_intdef)
-    };
-
-    /**
      * Annotations for content flag of UI.
      * @hide
      */
@@ -1648,7 +1602,7 @@
      */
     @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
     public void enableShortcutsForTargets(boolean enable,
-            @UserShortcutType int shortcutTypes, @NonNull Set<String> targets,
+            @ShortcutConstants.UserShortcutType int shortcutTypes, @NonNull Set<String> targets,
             @UserIdInt int userId) {
         final IAccessibilityManager service;
         synchronized (mLock) {
@@ -1862,7 +1816,8 @@
     @TestApi
     @RequiresPermission(Manifest.permission.MANAGE_ACCESSIBILITY)
     @NonNull
-    public List<String> getAccessibilityShortcutTargets(@ShortcutType int shortcutType) {
+    public List<String> getAccessibilityShortcutTargets(
+            @ShortcutConstants.UserShortcutType int shortcutType) {
         final IAccessibilityManager service;
         synchronized (mLock) {
             service = getServiceLocked();
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 49a2843..a5ba294 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -159,7 +159,7 @@
      * <p> To avoid disconnected trees, this flag will also prefetch the parent. Siblings will be
      * prefetched before descendants.
      *
-     * @see #FLAG_PREFETCH_ANCESTORS for where to use these flags.
+     * <p> See {@link #FLAG_PREFETCH_ANCESTORS} for information on where these flags can be used.
      */
     public static final int FLAG_PREFETCH_SIBLINGS = 1 << 1;
 
@@ -171,7 +171,7 @@
      * {@link #FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST} or this will trigger an
      * IllegalArgumentException.
      *
-     * @see #FLAG_PREFETCH_ANCESTORS for where to use these flags.
+     * <p> See {@link #FLAG_PREFETCH_ANCESTORS} for information on where these flags can be used.
      */
     public static final int FLAG_PREFETCH_DESCENDANTS_HYBRID = 1 << 2;
 
@@ -181,7 +181,7 @@
      * {@link #FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST} or this will trigger an
      * IllegalArgumentException.
      *
-     * @see #FLAG_PREFETCH_ANCESTORS for where to use these flags.
+     * <p> See {@link #FLAG_PREFETCH_ANCESTORS} for information on where these flags can be used.
      */
     public static final int FLAG_PREFETCH_DESCENDANTS_DEPTH_FIRST = 1 << 3;
 
@@ -191,7 +191,7 @@
      * {@link #FLAG_PREFETCH_DESCENDANTS_DEPTH_FIRST} or this will trigger an
      * IllegalArgumentException.
      *
-     * @see #FLAG_PREFETCH_ANCESTORS for where to use these flags.
+     * <p> See {@link #FLAG_PREFETCH_ANCESTORS} for information on where these flags can be used.
      */
     public static final int FLAG_PREFETCH_DESCENDANTS_BREADTH_FIRST = 1 << 4;
 
@@ -199,7 +199,7 @@
      * Prefetching flag that specifies prefetching should not be interrupted by a request to
      * retrieve a node or perform an action on a node.
      *
-     * @see #FLAG_PREFETCH_ANCESTORS for where to use these flags.
+     * <p> See {@link #FLAG_PREFETCH_ANCESTORS} for information on where these flags can be used.
      */
     public static final int FLAG_PREFETCH_UNINTERRUPTIBLE = 1 << 5;
 
@@ -1295,6 +1295,8 @@
     /**
      * Get the child at given index.
      *
+     * <p>
+     * See {@link #getParent(int)} for a description of prefetching.
      * @param index The child index.
      * @param prefetchingStrategy the prefetching strategy.
      * @return The child node.
@@ -1302,7 +1304,6 @@
      * @throws IllegalStateException If called outside of an {@link AccessibilityService} and before
      *                               calling {@link #setQueryFromAppProcessEnabled}.
      *
-     * @see AccessibilityNodeInfo#getParent(int) for a description of prefetching.
      */
     @Nullable
     public AccessibilityNodeInfo getChild(int index, @PrefetchingStrategy int prefetchingStrategy) {
@@ -1903,8 +1904,13 @@
      * Accessibility service will throttle those content change events and only handle one event
      * per minute for that view.
      * </p>
+     * <p>
+     * Example UI elements that frequently update and may benefit from a duration are progress bars,
+     * timers, and stopwatches.
+     * </p>
      *
-     * @see AccessibilityEvent#getContentChangeTypes for all content change types.
+     * @see AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED
+     * @see AccessibilityEvent#getContentChangeTypes
      * @param duration the minimum duration between content change events.
      *                                         Negative duration would be treated as zero.
      */
@@ -3954,7 +3960,7 @@
     /**
      * Returns the container title.
      *
-     * @see #setContainerTitle for details.
+     * @see #setContainerTitle
      */
     @Nullable
     public CharSequence getContainerTitle() {
@@ -5161,15 +5167,17 @@
      * {@link View#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)} and are performed
      * within {@link View#performAccessibilityAction(int, Bundle)}.
      * </p>
+     * <p>
      * <aside class="note">
      * <b>Note:</b> Views which support these actions should invoke
      * {@link View#setImportantForAccessibility(int)} with
      * {@link View#IMPORTANT_FOR_ACCESSIBILITY_YES} to ensure an {@link AccessibilityService}
-     * can discover the set of supported actions.
+     * can discover the set of supported actions. </aside>
      * </p>
+     * <p>
      * <aside class="note">
      * <b>Note:</b> Use {@link androidx.core.view.ViewCompat#addAccessibilityAction(View,
-     * CharSequence, AccessibilityViewCommand)} to register an action directly on the view.
+     * CharSequence, AccessibilityViewCommand)} to register an action directly on the view. </aside>
      * </p>
      */
     public static final class AccessibilityAction implements Parcelable {
@@ -5185,8 +5193,8 @@
          * <p>The node that is focused should return {@code true} for
          * {@link AccessibilityNodeInfo#isFocused()}.
          *
-         * @see #ACTION_ACCESSIBILITY_FOCUS for the difference between system and accessibility
-         * focus.
+         * See {@link #ACTION_ACCESSIBILITY_FOCUS} for the difference between system and
+         * accessibility focus.
          */
         public static final AccessibilityAction ACTION_FOCUS =
                 new AccessibilityAction(AccessibilityNodeInfo.ACTION_FOCUS);
diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
index eefc72b..f4aef22 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/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 1d9eb71..c7df15c 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -588,6 +588,9 @@
      */
     public static final int NO_SESSION = Integer.MAX_VALUE;
 
+    /** @hide **/
+    public static final String PINNED_DATASET_ID = "PINNED_DATASET_ID";
+
     private final IAutoFillManager mService;
 
     private final Object mLock = new Object();
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 4de0f29..b3bd92b 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 1d4d18b..d0fe3e0 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"
@@ -81,6 +82,14 @@
 }
 
 flag {
+    name: "toolkit_frame_rate_small_uses_percent_read_only"
+    namespace: "toolkit"
+    description: "VRR uses percent of size to consider a view to be small"
+    bug: "239979904"
+    is_fixed_read_only: true
+}
+
+flag {
     name: "toolkit_frame_rate_typing_read_only"
     namespace: "toolkit"
     description: "Feature flag for suppressing boost on typing"
@@ -94,4 +103,12 @@
     description: "Feature flag to enable the functionality of the dVRR feature"
     bug: "239979904"
     is_fixed_read_only: true
+}
+
+flag {
+    name: "toolkit_frame_rate_view_enabling_read_only"
+    namespace: "toolkit"
+    description: "Feature flag to enable the functionality on views for the dVRR feature"
+    bug: "239979904"
+    is_fixed_read_only: true
 }
\ No newline at end of file
diff --git a/core/java/android/view/flags/scroll_feedback_flags.aconfig b/core/java/android/view/flags/scroll_feedback_flags.aconfig
index a7c4104..338037f 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/flags/view_flags.aconfig b/core/java/android/view/flags/view_flags.aconfig
index c482f8b..e8e02ec 100644
--- a/core/java/android/view/flags/view_flags.aconfig
+++ b/core/java/android/view/flags/view_flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.view.flags"
+container: "system"
 
 flag {
     name: "enable_surface_native_alloc_registration_ro"
diff --git a/core/java/android/view/flags/window_insets.aconfig b/core/java/android/view/flags/window_insets.aconfig
index bf6df5c..bedb7d5 100644
--- a/core/java/android/view/flags/window_insets.aconfig
+++ b/core/java/android/view/flags/window_insets.aconfig
@@ -1,4 +1,5 @@
 package: "android.view.flags"
+container: "system"
 
 flag {
     name: "customizable_window_headers"
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 80b2396..8174da6 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1153,6 +1153,9 @@
                     }
                     final boolean startInput;
                     synchronized (mH) {
+                        if (reason == UnbindReason.DISCONNECT_IME) {
+                            mImeDispatcher.clear();
+                        }
                         if (getBindSequenceLocked() != sequence) {
                             return;
                         }
diff --git a/core/java/android/view/inputmethod/flags.aconfig b/core/java/android/view/inputmethod/flags.aconfig
index be74a65..d79903b 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"
@@ -93,3 +94,15 @@
     bug: "322836622"
     is_fixed_read_only: true
 }
+
+flag {
+    name: "ctrl_shift_shortcut"
+    namespace: "input_method"
+    description: "Ctrl+Shift shortcut to switch IMEs"
+    bug: "327198899"
+    is_fixed_read_only: true
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
diff --git a/core/java/android/webkit/flags.aconfig b/core/java/android/webkit/flags.aconfig
index 2d834a8..defe61e 100644
--- a/core/java/android/webkit/flags.aconfig
+++ b/core/java/android/webkit/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.webkit"
+container: "system"
 
 flag {
     name: "update_service_ipc_wrapper"
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index d00fc1c..abb1471 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -299,8 +299,10 @@
                 final int duration = mScrollerX.mDuration;
                 if (elapsedTime < duration) {
                     final float q = mInterpolator.getInterpolation(elapsedTime / (float) duration);
-                    mScrollerX.updateScroll(q);
-                    mScrollerY.updateScroll(q);
+                    final float q2 =
+                            mInterpolator.getInterpolation((elapsedTime - 1) / (float) duration);
+                    mScrollerX.updateScroll(q, q2);
+                    mScrollerY.updateScroll(q, q2);
                 } else {
                     abortAnimation();
                 }
@@ -642,8 +644,11 @@
                     * 0.84f; // look and feel tuning
         }
 
-        void updateScroll(float q) {
-            mCurrentPosition = mStart + Math.round(q * (mFinal - mStart));
+        void updateScroll(float q, float q2) {
+            int distance = mFinal - mStart;
+            mCurrentPosition = mStart + Math.round(q * distance);
+            // q2 is 1ms before q1
+            mCurrVelocity = 1000f * (q - q2) * distance;
         }
 
         /*
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 356d059..6e43d0f 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -69,6 +69,7 @@
 import com.android.internal.R;
 
 import java.text.NumberFormat;
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Locale;
 
@@ -139,6 +140,14 @@
  * <p>The "inverse" styles provide an inverse color scheme for the spinner, which may be necessary
  * if your application uses a light colored theme (a white background).</p>
  *
+ * <h4>Accessibility</h4>
+ * <p>
+ * Consider using
+ * {@link AccessibilityNodeInfo#setMinDurationBetweenContentChanges(Duration)} to
+ * convey to accessibility services that changes can be throttled. This may reduce the
+ * frequency of potentially disruptive notifications.
+ * </p>
+ *
  * <p><strong>XML attributes</b></strong>
  * <p>
  * See {@link android.R.styleable#ProgressBar ProgressBar Attributes},
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 42c2d80..b5bf529 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -568,7 +568,7 @@
                     handled = pageScroll(View.FOCUS_DOWN);
                     break;
                 case KeyEvent.KEYCODE_SPACE:
-                    pageScroll(event.isShiftPressed() ? View.FOCUS_UP : View.FOCUS_DOWN);
+                    handled = pageScroll(event.isShiftPressed() ? View.FOCUS_UP : View.FOCUS_DOWN);
                     break;
             }
         }
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/widget/flags/notification_widget_flags.aconfig b/core/java/android/widget/flags/notification_widget_flags.aconfig
index e60fa15..b530e71 100644
--- a/core/java/android/widget/flags/notification_widget_flags.aconfig
+++ b/core/java/android/widget/flags/notification_widget_flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.widget.flags"
+container: "system"
 
 flag {
    name: "notif_linearlayout_optimized"
diff --git a/core/java/android/window/flags/accessibility.aconfig b/core/java/android/window/flags/accessibility.aconfig
index 2d1cbb5..733e3db 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"
@@ -25,4 +26,14 @@
   metadata {
     purpose: PURPOSE_BUGFIX
   }
-}
\ No newline at end of file
+}
+
+flag {
+  name: "delay_notification_to_magnification_when_recents_window_to_front_transition"
+  namespace: "accessibility"
+  description: "The flag controls whether the delaying of notification for recents window to-front transition is needed. In accessibilityController other callbacks will decide sending or canceling the delayed notification."
+  bug: "324949652"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
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 fa0dab0..98ff3c6 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/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index b9d74e1..efe31ff 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.window.flags"
+container: "system"
 
 flag {
     name: "enable_scaled_resizing"
@@ -28,3 +29,10 @@
     description: "Enables new initial bounds for desktop windowing which adjust depending on app constraints"
     bug: "324377962"
 }
+
+flag {
+    name: "enable_desktop_windowing_task_limit"
+    namespace: "lse_desktop_experience"
+    description: "Enables a limit on the number of Tasks shown in Desktop Mode"
+    bug: "332502912"
+}
diff --git a/core/java/android/window/flags/responsible_apis.aconfig b/core/java/android/window/flags/responsible_apis.aconfig
index 94c72c6..33af486 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 dea9497..aa92af2 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 5c31048..460df31 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 a5c209d..dd6b772a 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"
@@ -8,6 +9,16 @@
 }
 
 flag {
+    name: "wait_for_transition_on_display_switch"
+    namespace: "windowing_frontend"
+    description: "Waits for Shell transition to start before unblocking the screen after display switch"
+    bug: "301420598"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
   name: "edge_to_edge_by_default"
   namespace: "windowing_frontend"
   description: "Make app go edge-to-edge by default when targeting SDK 35 or greater"
diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig
index 4b3d8e8..80265ec 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/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index 840e2a1..a0c405e 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -18,8 +18,8 @@
 
 import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
 
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
 import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
 import static com.android.internal.os.RoSystemProperties.SUPPORT_ONE_HANDED_MODE;
 import static com.android.internal.util.ArrayUtils.convertToLongArray;
@@ -53,11 +53,9 @@
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.Flags;
 import android.widget.Toast;
 
 import com.android.internal.R;
-import com.android.internal.accessibility.common.ShortcutConstants;
 import com.android.internal.accessibility.dialog.AccessibilityTarget;
 import com.android.internal.accessibility.util.ShortcutUtils;
 import com.android.internal.util.function.pooled.PooledLambda;
@@ -331,7 +329,7 @@
     }
 
     private AlertDialog createShortcutWarningDialog(int userId) {
-        List<AccessibilityTarget> targets = getTargets(mContext, ACCESSIBILITY_SHORTCUT_KEY);
+        List<AccessibilityTarget> targets = getTargets(mContext, HARDWARE);
         if (targets.size() == 0) {
             return null;
         }
@@ -370,23 +368,17 @@
                         })
                 .setPositiveButton(R.string.accessibility_shortcut_off,
                         (DialogInterface d, int which) -> {
-                            if (Flags.updateAlwaysOnA11yService()) {
-                                Set<String> targetServices =
-                                        ShortcutUtils.getShortcutTargetsFromSettings(
-                                                mContext,
-                                                ShortcutConstants.UserShortcutType.HARDWARE,
-                                                userId);
+                            Set<String> targetServices =
+                                    ShortcutUtils.getShortcutTargetsFromSettings(
+                                            mContext,
+                                            HARDWARE,
+                                            userId);
 
-                                Settings.Secure.putStringForUser(mContext.getContentResolver(),
-                                        Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "",
-                                        userId);
-                                ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
-                                        mContext, targetServices, userId);
-                            } else {
-                                Settings.Secure.putStringForUser(mContext.getContentResolver(),
-                                        Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "",
-                                        userId);
-                            }
+                            Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                                    Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "",
+                                    userId);
+                            ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
+                                    mContext, targetServices, userId);
 
                             // If canceled, treat as if the dialog has never been shown
                             Settings.Secure.putIntForUser(mContext.getContentResolver(),
@@ -543,7 +535,7 @@
     private ComponentName getShortcutTargetComponentName() {
         final List<String> shortcutTargets = mFrameworkObjectProvider
                 .getAccessibilityManagerInstance(mContext)
-                .getAccessibilityShortcutTargets(ACCESSIBILITY_SHORTCUT_KEY);
+                .getAccessibilityShortcutTargets(HARDWARE);
         if (shortcutTargets.size() != 1) {
             return null;
         }
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityActivityTarget.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityActivityTarget.java
index 063154d..bd3c659 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityActivityTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityActivityTarget.java
@@ -17,23 +17,22 @@
 package com.android.internal.accessibility.dialog;
 
 import static com.android.internal.accessibility.util.ShortcutUtils.convertToKey;
-import static com.android.internal.accessibility.util.ShortcutUtils.convertToUserType;
 import static com.android.internal.accessibility.util.ShortcutUtils.isShortcutContained;
 
 import android.accessibilityservice.AccessibilityShortcutInfo;
 import android.annotation.NonNull;
 import android.content.Context;
-import android.view.accessibility.AccessibilityManager.ShortcutType;
 
 import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
 import com.android.internal.accessibility.common.ShortcutConstants.ShortcutMenuMode;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 
 /**
  * Base class for creating accessibility activity target.
  */
 class AccessibilityActivityTarget extends AccessibilityTarget {
 
-    AccessibilityActivityTarget(Context context, @ShortcutType int shortcutType,
+    AccessibilityActivityTarget(Context context, @UserShortcutType int shortcutType,
             @NonNull AccessibilityShortcutInfo shortcutInfo) {
         super(context,
                 shortcutType,
@@ -44,7 +43,7 @@
                 shortcutInfo.getActivityInfo().applicationInfo.uid,
                 shortcutInfo.getActivityInfo().loadLabel(context.getPackageManager()),
                 shortcutInfo.getActivityInfo().loadIcon(context.getPackageManager()),
-                convertToKey(convertToUserType(shortcutType)));
+                convertToKey(shortcutType));
     }
 
     @Override
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java
index 7eb09e5..fc3cd45 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityButtonChooserActivity.java
@@ -17,10 +17,10 @@
 package com.android.internal.accessibility.dialog;
 
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
 import static com.android.internal.accessibility.util.AccessibilityStatsLogUtils.logAccessibilityButtonLongPressStatus;
 
@@ -85,7 +85,7 @@
             prompt.setVisibility(View.VISIBLE);
         }
 
-        mTargets.addAll(getTargets(this, ACCESSIBILITY_BUTTON));
+        mTargets.addAll(getTargets(this, SOFTWARE));
 
         final GridView gridview = findViewById(R.id.accessibility_button_chooser_grid);
         gridview.setAdapter(new ButtonTargetAdapter(mTargets));
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityServiceTarget.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityServiceTarget.java
index 2b6913c..677c0f0 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityServiceTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityServiceTarget.java
@@ -17,16 +17,15 @@
 package com.android.internal.accessibility.dialog;
 
 import static com.android.internal.accessibility.util.ShortcutUtils.convertToKey;
-import static com.android.internal.accessibility.util.ShortcutUtils.convertToUserType;
 import static com.android.internal.accessibility.util.ShortcutUtils.isShortcutContained;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.annotation.NonNull;
 import android.content.Context;
-import android.view.accessibility.AccessibilityManager.ShortcutType;
 
 import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
 import com.android.internal.accessibility.common.ShortcutConstants.ShortcutMenuMode;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 
 /**
  * Base class for creating accessibility service target with various fragment types related to
@@ -36,7 +35,7 @@
 
     private final AccessibilityServiceInfo mAccessibilityServiceInfo;
 
-    AccessibilityServiceTarget(Context context, @ShortcutType int shortcutType,
+    AccessibilityServiceTarget(Context context, @UserShortcutType int shortcutType,
             @AccessibilityFragmentType int fragmentType,
             @NonNull AccessibilityServiceInfo serviceInfo) {
         super(context,
@@ -48,7 +47,7 @@
                 serviceInfo.getResolveInfo().serviceInfo.applicationInfo.uid,
                 serviceInfo.getResolveInfo().loadLabel(context.getPackageManager()),
                 serviceInfo.getResolveInfo().loadIcon(context.getPackageManager()),
-                convertToKey(convertToUserType(shortcutType)));
+                convertToKey(shortcutType));
         mAccessibilityServiceInfo = serviceInfo;
     }
 
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java
index c70febb..6256dbc 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityShortcutChooserActivity.java
@@ -15,11 +15,10 @@
  */
 package com.android.internal.accessibility.dialog;
 
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
-import static android.view.accessibility.AccessibilityManager.ShortcutType;
-
 import static com.android.internal.accessibility.common.ShortcutConstants.ShortcutMenuMode;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getInstalledTargets;
 import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
 import static com.android.internal.accessibility.util.AccessibilityUtils.isUserSetupCompleted;
@@ -37,7 +36,6 @@
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.Flags;
 import android.widget.AdapterView;
 
 import com.android.internal.R;
@@ -51,8 +49,8 @@
  * activity or allowlisting feature for volume key shortcut.
  */
 public class AccessibilityShortcutChooserActivity extends Activity {
-    @ShortcutType
-    private final int mShortcutType = ACCESSIBILITY_SHORTCUT_KEY;
+    @UserShortcutType
+    private final int mShortcutType = HARDWARE;
     private static final String KEY_ACCESSIBILITY_SHORTCUT_MENU_MODE =
             "accessibility_shortcut_menu_mode";
     private final List<AccessibilityTarget> mTargets = new ArrayList<>();
@@ -216,7 +214,7 @@
                 mTargetAdapter.getShortcutMenuMode() == ShortcutMenuMode.EDIT;
         final int selectDialogTitleId = R.string.accessibility_select_shortcut_menu_title;
         final int editDialogTitleId =
-                mShortcutType == ACCESSIBILITY_BUTTON
+                mShortcutType == SOFTWARE
                         ? R.string.accessibility_edit_shortcut_menu_button_title
                         : R.string.accessibility_edit_shortcut_menu_volume_title;
 
@@ -248,12 +246,10 @@
 
         boolean allowEditing = isUserSetupCompleted(this);
         boolean showWhenLocked = false;
-        if (Flags.allowShortcutChooserOnLockscreen()) {
-            final KeyguardManager keyguardManager = getSystemService(KeyguardManager.class);
-            if (keyguardManager != null && keyguardManager.isKeyguardLocked()) {
-                allowEditing = false;
-                showWhenLocked = true;
-            }
+        final KeyguardManager keyguardManager = getSystemService(KeyguardManager.class);
+        if (keyguardManager != null && keyguardManager.isKeyguardLocked()) {
+            allowEditing = false;
+            showWhenLocked = true;
         }
         if (allowEditing) {
             final String positiveButtonText =
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
index 652cb52..ba1dffc 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
@@ -16,10 +16,8 @@
 
 package com.android.internal.accessibility.dialog;
 
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
-
-import static com.android.internal.accessibility.util.ShortcutUtils.convertToUserType;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.internal.accessibility.util.ShortcutUtils.optInValueToSettings;
 import static com.android.internal.accessibility.util.ShortcutUtils.optOutValueFromSettings;
 
@@ -30,10 +28,10 @@
 import android.graphics.drawable.Drawable;
 import android.view.View;
 import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityManager.ShortcutType;
 
 import com.android.internal.accessibility.common.ShortcutConstants;
 import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 import com.android.internal.accessibility.dialog.TargetAdapter.ViewHolder;
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -47,7 +45,7 @@
 public abstract class AccessibilityTarget implements TargetOperations, OnTargetSelectedListener,
         OnTargetCheckedChangeListener {
     private Context mContext;
-    @ShortcutType
+    @UserShortcutType
     private int mShortcutType;
     @AccessibilityFragmentType
     private int mFragmentType;
@@ -61,7 +59,7 @@
     private CharSequence mStateDescription;
 
     @VisibleForTesting
-    public AccessibilityTarget(Context context, @ShortcutType int shortcutType,
+    public AccessibilityTarget(Context context, @UserShortcutType int shortcutType,
             @AccessibilityFragmentType int fragmentType, boolean isShortcutSwitched, String id,
             int uid, CharSequence label, Drawable icon, String key) {
         mContext = context;
@@ -99,10 +97,10 @@
         final AccessibilityManager am =
                 getContext().getSystemService(AccessibilityManager.class);
         switch (getShortcutType()) {
-            case ACCESSIBILITY_BUTTON:
+            case SOFTWARE:
                 am.notifyAccessibilityButtonClicked(getContext().getDisplayId(), getId());
                 return;
-            case ACCESSIBILITY_SHORTCUT_KEY:
+            case HARDWARE:
                 am.performAccessibilityShortcut(getId());
                 return;
             default:
@@ -114,9 +112,9 @@
     public void onCheckedChanged(boolean isChecked) {
         setShortcutEnabled(isChecked);
         if (isChecked) {
-            optInValueToSettings(getContext(), convertToUserType(getShortcutType()), getId());
+            optInValueToSettings(getContext(), getShortcutType(), getId());
         } else {
-            optOutValueFromSettings(getContext(), convertToUserType(getShortcutType()), getId());
+            optOutValueFromSettings(getContext(), getShortcutType(), getId());
         }
     }
 
@@ -142,7 +140,7 @@
         return mContext;
     }
 
-    public @ShortcutType int getShortcutType() {
+    public @UserShortcutType int getShortcutType() {
         return mShortcutType;
     }
 
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
index 0d82d63..e523ab0 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
@@ -16,14 +16,13 @@
 
 package com.android.internal.accessibility.dialog;
 
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
-
 import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.ONE_HANDED_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.REDUCE_BRIGHT_COLORS_COMPONENT_NAME;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.internal.accessibility.util.AccessibilityUtils.getAccessibilityServiceFragmentType;
 import static com.android.internal.accessibility.util.ShortcutUtils.isShortcutContained;
 import static com.android.internal.os.RoSystemProperties.SUPPORT_ONE_HANDED_MODE;
@@ -38,10 +37,10 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityManager.ShortcutType;
 
 import com.android.internal.R;
 import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -64,7 +63,7 @@
      * @hide
      */
     public static List<AccessibilityTarget> getTargets(Context context,
-            @ShortcutType int shortcutType) {
+            @UserShortcutType int shortcutType) {
         // List all accessibility target
         final List<AccessibilityTarget> installedTargets = getInstalledTargets(context,
                 shortcutType);
@@ -107,7 +106,7 @@
      * @hide
      */
     public static List<AccessibilityTarget> getInstalledTargets(Context context,
-            @ShortcutType int shortcutType) {
+            @UserShortcutType int shortcutType) {
         final List<AccessibilityTarget> targets = new ArrayList<>();
         targets.addAll(getAccessibilityFilteredTargets(context, shortcutType));
         targets.addAll(getAllowListingFeatureTargets(context, shortcutType));
@@ -116,7 +115,7 @@
     }
 
     private static List<AccessibilityTarget> getAccessibilityFilteredTargets(Context context,
-            @ShortcutType int shortcutType) {
+            @UserShortcutType int shortcutType) {
         final List<AccessibilityTarget> serviceTargets =
                 getAccessibilityServiceTargets(context, shortcutType);
         final List<AccessibilityTarget> activityTargets =
@@ -149,7 +148,7 @@
     }
 
     private static List<AccessibilityTarget> getAccessibilityServiceTargets(Context context,
-            @ShortcutType int shortcutType) {
+            @UserShortcutType int shortcutType) {
         final AccessibilityManager am = (AccessibilityManager) context.getSystemService(
                 Context.ACCESSIBILITY_SERVICE);
         final List<AccessibilityServiceInfo> installedServices =
@@ -165,7 +164,7 @@
             final boolean hasRequestAccessibilityButtonFlag =
                     (info.flags & AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0;
             if ((targetSdk <= Build.VERSION_CODES.Q) && !hasRequestAccessibilityButtonFlag
-                    && (shortcutType == ACCESSIBILITY_BUTTON)) {
+                    && (shortcutType == SOFTWARE)) {
                 continue;
             }
 
@@ -176,7 +175,7 @@
     }
 
     private static List<AccessibilityTarget> getAccessibilityActivityTargets(Context context,
-            @ShortcutType int shortcutType) {
+            @UserShortcutType int shortcutType) {
         final AccessibilityManager am = (AccessibilityManager) context.getSystemService(
                 Context.ACCESSIBILITY_SERVICE);
         final List<AccessibilityShortcutInfo> installedServices =
@@ -195,7 +194,7 @@
     }
 
     private static List<AccessibilityTarget> getAllowListingFeatureTargets(Context context,
-            @ShortcutType int shortcutType) {
+            @UserShortcutType int shortcutType) {
         final List<AccessibilityTarget> targets = new ArrayList<>();
         final int uid = context.getApplicationInfo().uid;
 
@@ -276,7 +275,7 @@
     }
 
     private static AccessibilityTarget createAccessibilityServiceTarget(Context context,
-            @ShortcutType int shortcutType, @NonNull AccessibilityServiceInfo info) {
+            @UserShortcutType int shortcutType, @NonNull AccessibilityServiceInfo info) {
         switch (getAccessibilityServiceFragmentType(info)) {
             case AccessibilityFragmentType.VOLUME_SHORTCUT_TOGGLE:
                 return new VolumeShortcutToggleAccessibilityServiceTarget(context, shortcutType,
diff --git a/core/java/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTarget.java b/core/java/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTarget.java
index 1bc8b84..2097788 100644
--- a/core/java/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTarget.java
@@ -16,22 +16,14 @@
 
 package com.android.internal.accessibility.dialog;
 
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
-
-import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
-import static com.android.internal.accessibility.util.AccessibilityUtils.setAccessibilityServiceState;
-import static com.android.internal.accessibility.util.ShortcutUtils.isComponentIdExistingInSettings;
-
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.annotation.NonNull;
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.UserHandle;
-import android.view.accessibility.AccessibilityManager.ShortcutType;
-import android.view.accessibility.Flags;
 
 import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 import com.android.internal.accessibility.util.ShortcutUtils;
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -45,7 +37,7 @@
 public class InvisibleToggleAccessibilityServiceTarget extends AccessibilityServiceTarget {
 
     public InvisibleToggleAccessibilityServiceTarget(
-            Context context, @ShortcutType int shortcutType,
+            Context context, @UserShortcutType int shortcutType,
             @NonNull AccessibilityServiceInfo serviceInfo) {
         super(context,
                 shortcutType,
@@ -55,31 +47,9 @@
 
     @Override
     public void onCheckedChanged(boolean isChecked) {
+        super.onCheckedChanged(isChecked);
         final ComponentName componentName = ComponentName.unflattenFromString(getId());
-
-        if (Flags.updateAlwaysOnA11yService()) {
-            super.onCheckedChanged(isChecked);
-            ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
-                    getContext(), Set.of(componentName.flattenToString()), UserHandle.myUserId());
-        } else {
-            if (!isComponentIdExistingInOtherShortcut()) {
-                setAccessibilityServiceState(getContext(), componentName, isChecked);
-            }
-
-            super.onCheckedChanged(isChecked);
-        }
-    }
-
-    private boolean isComponentIdExistingInOtherShortcut() {
-        switch (getShortcutType()) {
-            case ACCESSIBILITY_BUTTON:
-                return isComponentIdExistingInSettings(getContext(), UserShortcutType.HARDWARE,
-                        getId());
-            case ACCESSIBILITY_SHORTCUT_KEY:
-                return isComponentIdExistingInSettings(getContext(), UserShortcutType.SOFTWARE,
-                        getId());
-            default:
-                throw new IllegalStateException("Unexpected shortcut type");
-        }
+        ShortcutUtils.updateInvisibleToggleAccessibilityServiceEnableState(
+                getContext(), Set.of(componentName.flattenToString()), UserHandle.myUserId());
     }
 }
diff --git a/core/java/com/android/internal/accessibility/dialog/InvisibleToggleAllowListingFeatureTarget.java b/core/java/com/android/internal/accessibility/dialog/InvisibleToggleAllowListingFeatureTarget.java
index c22f17d..9605793 100644
--- a/core/java/com/android/internal/accessibility/dialog/InvisibleToggleAllowListingFeatureTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/InvisibleToggleAllowListingFeatureTarget.java
@@ -18,9 +18,9 @@
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
-import android.view.accessibility.AccessibilityManager.ShortcutType;
 
 import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 
 /**
  * Extension for {@link AccessibilityTarget} with {@link AccessibilityFragmentType#INVISIBLE_TOGGLE}
@@ -28,7 +28,7 @@
  */
 class InvisibleToggleAllowListingFeatureTarget extends AccessibilityTarget {
 
-    InvisibleToggleAllowListingFeatureTarget(Context context, @ShortcutType int shortcutType,
+    InvisibleToggleAllowListingFeatureTarget(Context context, @UserShortcutType int shortcutType,
             boolean isShortcutSwitched, String id, int uid, CharSequence label, Drawable icon,
             String key) {
         super(context, shortcutType, AccessibilityFragmentType.INVISIBLE_TOGGLE, isShortcutSwitched,
diff --git a/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java b/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java
index a4ffef6..4c5401c 100644
--- a/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java
@@ -22,11 +22,11 @@
 import android.annotation.NonNull;
 import android.content.Context;
 import android.view.View;
-import android.view.accessibility.AccessibilityManager.ShortcutType;
 
 import com.android.internal.R;
 import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
 import com.android.internal.accessibility.common.ShortcutConstants.ShortcutMenuMode;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 import com.android.internal.accessibility.dialog.TargetAdapter.ViewHolder;
 
 import java.lang.annotation.Retention;
@@ -45,7 +45,7 @@
         float DISABLED = 0.5f;
     }
 
-    ToggleAccessibilityServiceTarget(Context context, @ShortcutType int shortcutType,
+    ToggleAccessibilityServiceTarget(Context context, @UserShortcutType int shortcutType,
             @NonNull AccessibilityServiceInfo serviceInfo) {
         super(context,
                 shortcutType,
diff --git a/core/java/com/android/internal/accessibility/dialog/ToggleAllowListingFeatureTarget.java b/core/java/com/android/internal/accessibility/dialog/ToggleAllowListingFeatureTarget.java
index 11e668f..c285670 100644
--- a/core/java/com/android/internal/accessibility/dialog/ToggleAllowListingFeatureTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/ToggleAllowListingFeatureTarget.java
@@ -21,11 +21,11 @@
 import android.graphics.drawable.Drawable;
 import android.provider.Settings;
 import android.view.View;
-import android.view.accessibility.AccessibilityManager.ShortcutType;
 
 import com.android.internal.R;
 import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
 import com.android.internal.accessibility.common.ShortcutConstants.ShortcutMenuMode;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 import com.android.internal.accessibility.dialog.TargetAdapter.ViewHolder;
 
 /**
@@ -34,7 +34,7 @@
  */
 class ToggleAllowListingFeatureTarget extends AccessibilityTarget {
 
-    ToggleAllowListingFeatureTarget(Context context, @ShortcutType int shortcutType,
+    ToggleAllowListingFeatureTarget(Context context, @UserShortcutType int shortcutType,
             boolean isShortcutSwitched, String id, int uid, CharSequence label, Drawable icon,
             String key) {
         super(context, shortcutType, AccessibilityFragmentType.TOGGLE, isShortcutSwitched, id,
diff --git a/core/java/com/android/internal/accessibility/dialog/VolumeShortcutToggleAccessibilityServiceTarget.java b/core/java/com/android/internal/accessibility/dialog/VolumeShortcutToggleAccessibilityServiceTarget.java
index 04f5061..7535979 100644
--- a/core/java/com/android/internal/accessibility/dialog/VolumeShortcutToggleAccessibilityServiceTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/VolumeShortcutToggleAccessibilityServiceTarget.java
@@ -16,10 +16,8 @@
 
 package com.android.internal.accessibility.dialog;
 
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
-
-import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.internal.accessibility.util.AccessibilityUtils.setAccessibilityServiceState;
 import static com.android.internal.accessibility.util.ShortcutUtils.optOutValueFromSettings;
 
@@ -27,11 +25,11 @@
 import android.annotation.NonNull;
 import android.content.ComponentName;
 import android.content.Context;
-import android.view.accessibility.AccessibilityManager.ShortcutType;
 import android.widget.Toast;
 
 import com.android.internal.R;
 import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 
 /**
  * Extension for {@link AccessibilityServiceTarget} with
@@ -39,8 +37,8 @@
  */
 class VolumeShortcutToggleAccessibilityServiceTarget extends AccessibilityServiceTarget {
 
-    VolumeShortcutToggleAccessibilityServiceTarget(Context context, @ShortcutType int shortcutType,
-            @NonNull AccessibilityServiceInfo serviceInfo) {
+    VolumeShortcutToggleAccessibilityServiceTarget(Context context,
+            @UserShortcutType int shortcutType, @NonNull AccessibilityServiceInfo serviceInfo) {
         super(context,
                 shortcutType,
                 AccessibilityFragmentType.VOLUME_SHORTCUT_TOGGLE,
@@ -50,10 +48,10 @@
     @Override
     public void onCheckedChanged(boolean isChecked) {
         switch (getShortcutType()) {
-            case ACCESSIBILITY_BUTTON:
+            case SOFTWARE:
                 onCheckedFromAccessibilityButton(isChecked);
                 return;
-            case ACCESSIBILITY_SHORTCUT_KEY:
+            case HARDWARE:
                 super.onCheckedChanged(isChecked);
                 return;
             default:
diff --git a/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java b/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
index 6b074a6..6864bf7 100644
--- a/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
+++ b/core/java/com/android/internal/accessibility/util/AccessibilityStatsLogUtils.java
@@ -21,10 +21,10 @@
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__DISABLED;
 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__ENABLED;
 import static com.android.internal.util.FrameworkStatsLog.ACCESSIBILITY_SHORTCUT_REPORTED__SERVICE_STATUS__UNKNOWN;
@@ -47,9 +47,9 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.provider.Settings;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityManager.ShortcutType;
 
+import com.android.internal.accessibility.common.ShortcutConstants;
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 import com.android.internal.util.FrameworkStatsLog;
 
 /** Methods for logging accessibility states. */
@@ -71,15 +71,15 @@
 
     /**
      * Logs accessibility feature name that is assigned to the given {@code shortcutType}.
-     * Calls this when clicking the shortcut {@link AccessibilityManager#ACCESSIBILITY_BUTTON} or
-     * {@link AccessibilityManager#ACCESSIBILITY_SHORTCUT_KEY}.
+     * Calls this when clicking the shortcut {@link ShortcutConstants.UserShortcutType#SOFTWARE} or
+     * {@link ShortcutConstants.UserShortcutType#HARDWARE}.
      *
      * @param context context used to retrieve the {@link Settings} provider
      * @param componentName component name of the accessibility feature
      * @param shortcutType  accessibility shortcut type
      */
     public static void logAccessibilityShortcutActivated(Context context,
-            ComponentName componentName, @ShortcutType int shortcutType) {
+            ComponentName componentName, @UserShortcutType int shortcutType) {
         logAccessibilityShortcutActivatedInternal(componentName,
                 convertToLoggingShortcutType(context, shortcutType), UNKNOWN_STATUS);
     }
@@ -87,16 +87,17 @@
     /**
      * Logs accessibility feature name that is assigned to the given {@code shortcutType} and the
      * {@code serviceEnabled} status.
-     * Calls this when clicking the shortcut {@link AccessibilityManager#ACCESSIBILITY_BUTTON}
-     * or {@link AccessibilityManager#ACCESSIBILITY_SHORTCUT_KEY}.
+     * Calls this when clicking the shortcut {@link ShortcutConstants.UserShortcutType#SOFTWARE}
+     * or {@link ShortcutConstants.UserShortcutType#HARDWARE}.
      *
      * @param context context used to retrieve the {@link Settings} provider
      * @param componentName  component name of the accessibility feature
      * @param shortcutType   accessibility shortcut type
      * @param serviceEnabled {@code true} if the service is enabled
      */
-    public static void logAccessibilityShortcutActivated(Context context,
-            ComponentName componentName, @ShortcutType int shortcutType, boolean serviceEnabled) {
+    public static void logAccessibilityShortcutActivated(
+            Context context, ComponentName componentName,
+            @UserShortcutType int shortcutType, boolean serviceEnabled) {
         logAccessibilityShortcutActivatedInternal(componentName,
                 convertToLoggingShortcutType(context, shortcutType),
                 convertToLoggingServiceStatus(serviceEnabled));
@@ -235,9 +236,9 @@
     }
 
     private static int convertToLoggingShortcutType(Context context,
-            @ShortcutType int shortcutType) {
+            @UserShortcutType int shortcutType) {
         switch (shortcutType) {
-            case ACCESSIBILITY_BUTTON:
+            case SOFTWARE:
                 if (isAccessibilityFloatingMenuEnabled(context)) {
                     return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_FLOATING_MENU;
                 } else if (isAccessibilityGestureEnabled(context)) {
@@ -245,7 +246,7 @@
                 } else {
                     return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__A11Y_BUTTON;
                 }
-            case ACCESSIBILITY_SHORTCUT_KEY:
+            case HARDWARE:
                 return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__VOLUME_KEY;
         }
         return ACCESSIBILITY_SHORTCUT_REPORTED__SHORTCUT_TYPE__UNKNOWN_TYPE;
diff --git a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
index f9c4d37..5b09a8b 100644
--- a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
+++ b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
@@ -16,14 +16,10 @@
 
 package com.android.internal.accessibility.util;
 
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
-
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
 import static com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType.INVISIBLE_TOGGLE;
 import static com.android.internal.accessibility.common.ShortcutConstants.SERVICES_SEPARATOR;
 import static com.android.internal.accessibility.common.ShortcutConstants.USER_SHORTCUT_TYPES;
-import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.annotation.NonNull;
@@ -33,7 +29,8 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityManager.ShortcutType;
+
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 
 import java.util.Collections;
 import java.util.List;
@@ -151,7 +148,7 @@
      * @param componentId The component id that need to be checked.
      * @return {@code true} if a component id is contained.
      */
-    public static boolean isShortcutContained(Context context, @ShortcutType int shortcutType,
+    public static boolean isShortcutContained(Context context, @UserShortcutType int shortcutType,
             @NonNull String componentId) {
         final AccessibilityManager am = (AccessibilityManager) context.getSystemService(
                 Context.ACCESSIBILITY_SERVICE);
@@ -184,24 +181,6 @@
     }
 
     /**
-     * Converts {@link ShortcutType} to {@link UserShortcutType}.
-     *
-     * @param type The shortcut type.
-     * @return Mapping type from {@link UserShortcutType}.
-     */
-    public static @UserShortcutType int convertToUserType(@ShortcutType int type) {
-        switch (type) {
-            case ACCESSIBILITY_BUTTON:
-                return UserShortcutType.SOFTWARE;
-            case ACCESSIBILITY_SHORTCUT_KEY:
-                return UserShortcutType.HARDWARE;
-            default:
-                throw new IllegalArgumentException(
-                        "Unsupported shortcut type:" + type);
-        }
-    }
-
-    /**
      * Updates an accessibility state if the accessibility service is a Always-On a11y service,
      * a.k.a. AccessibilityServices that has FLAG_REQUEST_ACCESSIBILITY_BUTTON
      * <p>
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 6bd273b..4f55441 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -28,6 +28,7 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 
 import static com.android.internal.app.ResolverActivity.EXTRA_CALLING_USER;
+import static com.android.internal.app.ResolverActivity.EXTRA_RESTRICT_TO_SINGLE_USER;
 import static com.android.internal.app.ResolverActivity.EXTRA_SELECTED_PROFILE;
 
 import android.annotation.Nullable;
@@ -190,7 +191,7 @@
                 .thenApplyAsync(targetResolveInfo -> {
                     if (isResolverActivityResolveInfo(targetResolveInfo)) {
                         launchResolverActivityWithCorrectTab(intentReceived, className, newIntent,
-                                callingUserId, targetUserId);
+                                callingUserId, targetUserId, false);
                     // When switching to the personal profile, automatically start the activity
                     } else if (className.equals(FORWARD_INTENT_TO_PARENT)) {
                         startActivityAsCaller(newIntent, targetUserId);
@@ -218,7 +219,7 @@
                 .thenAcceptAsync(targetResolveInfo -> {
                     if (isResolverActivityResolveInfo(targetResolveInfo)) {
                         launchResolverActivityWithCorrectTab(intentReceived, className, newIntent,
-                                callingUserId, targetUserId);
+                                callingUserId, targetUserId, true);
                     } else {
                         maybeShowUserConsentMiniResolverPrivate(targetResolveInfo, newIntent,
                                 targetUserId);
@@ -490,7 +491,7 @@
     }
 
     private void launchResolverActivityWithCorrectTab(Intent intentReceived, String className,
-            Intent newIntent, int callingUserId, int targetUserId) {
+            Intent newIntent, int callingUserId, int targetUserId, boolean singleTabOnly) {
         // When showing the intent resolver, instead of forwarding to the other profile,
         // we launch it in the current user and select the other tab. This fixes b/155874820.
         //
@@ -505,6 +506,9 @@
         sanitizeIntent(intentReceived);
         intentReceived.putExtra(EXTRA_SELECTED_PROFILE, selectedProfile);
         intentReceived.putExtra(EXTRA_CALLING_USER, UserHandle.of(callingUserId));
+        if (singleTabOnly) {
+            intentReceived.putExtra(EXTRA_RESTRICT_TO_SINGLE_USER, true);
+        }
         startActivityAsCaller(intentReceived, null, false, userId);
         finish();
     }
diff --git a/core/java/com/android/internal/app/SuspendedAppActivity.java b/core/java/com/android/internal/app/SuspendedAppActivity.java
index 6620156..7a8a47e 100644
--- a/core/java/com/android/internal/app/SuspendedAppActivity.java
+++ b/core/java/com/android/internal/app/SuspendedAppActivity.java
@@ -16,7 +16,7 @@
 
 package com.android.internal.app;
 
-import static android.app.admin.flags.Flags.crossUserSuspensionEnabled;
+import static android.app.admin.flags.Flags.crossUserSuspensionEnabledRo;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 import static android.content.pm.SuspendDialogInfo.BUTTON_ACTION_MORE_DETAILS;
@@ -234,7 +234,7 @@
         }
         mSuspendedPackage = intent.getStringExtra(EXTRA_SUSPENDED_PACKAGE);
         mSuspendingPackage = intent.getStringExtra(EXTRA_SUSPENDING_PACKAGE);
-        if (crossUserSuspensionEnabled()) {
+        if (crossUserSuspensionEnabledRo()) {
             mSuspendingUserId = intent.getIntExtra(EXTRA_SUSPENDING_USER, mUserId);
         } else {
             mSuspendingUserId = mUserId;
@@ -373,7 +373,7 @@
                 .putExtra(Intent.EXTRA_USER_ID, userId)
                 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                         | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-        if (crossUserSuspensionEnabled() && suspendingPackage != null) {
+        if (crossUserSuspensionEnabledRo() && suspendingPackage != null) {
             intent.putExtra(EXTRA_SUSPENDING_USER, suspendingPackage.userId);
         }
         return intent;
diff --git a/core/java/com/android/internal/compat/Android.bp b/core/java/com/android/internal/compat/Android.bp
index 9ff05a6..8253aa8 100644
--- a/core/java/com/android/internal/compat/Android.bp
+++ b/core/java/com/android/internal/compat/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "compat_logging_flags",
     package: "com.android.internal.compat.flags",
+    container: "system",
     srcs: [
         "compat_logging_flags.aconfig",
     ],
diff --git a/core/java/com/android/internal/compat/compat_logging_flags.aconfig b/core/java/com/android/internal/compat/compat_logging_flags.aconfig
index a5c31ed..4f51626 100644
--- a/core/java/com/android/internal/compat/compat_logging_flags.aconfig
+++ b/core/java/com/android/internal/compat/compat_logging_flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.internal.compat.flags"
+container: "system"
 
 flag {
     name: "skip_old_and_disabled_compat_logging"
@@ -6,4 +7,4 @@
     description: "Feature flag for skipping debug logging for changes that do not target the latest sdk or are disabled"
     bug: "323949942"
     is_fixed_read_only: true
-}
\ No newline at end of file
+}
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 d73e623..03b6a5b 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/jank/Cuj.java b/core/java/com/android/internal/jank/Cuj.java
index d2a533c..f2d2c1b 100644
--- a/core/java/com/android/internal/jank/Cuj.java
+++ b/core/java/com/android/internal/jank/Cuj.java
@@ -127,10 +127,17 @@
     public static final int CUJ_LAUNCHER_LAUNCH_APP_PAIR_FROM_WORKSPACE = 91;
     public static final int CUJ_LAUNCHER_LAUNCH_APP_PAIR_FROM_TASKBAR = 92;
     public static final int CUJ_LAUNCHER_SAVE_APP_PAIR = 93;
+    public static final int CUJ_LAUNCHER_ALL_APPS_SEARCH_BACK = 95;
+    public static final int CUJ_LAUNCHER_TASKBAR_ALL_APPS_CLOSE_BACK = 96;
+    public static final int CUJ_LAUNCHER_TASKBAR_ALL_APPS_SEARCH_BACK = 97;
+    public static final int CUJ_LAUNCHER_WIDGET_PICKER_CLOSE_BACK = 98;
+    public static final int CUJ_LAUNCHER_WIDGET_PICKER_SEARCH_BACK = 99;
+    public static final int CUJ_LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK = 100;
+    public static final int CUJ_LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK = 101;
 
     // When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE.
     @VisibleForTesting
-    static final int LAST_CUJ = CUJ_LAUNCHER_SAVE_APP_PAIR;
+    static final int LAST_CUJ = CUJ_LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK;
 
     /** @hide */
     @IntDef({
@@ -217,7 +224,13 @@
             CUJ_LAUNCHER_SEARCH_QSB_WEB_SEARCH,
             CUJ_LAUNCHER_LAUNCH_APP_PAIR_FROM_WORKSPACE,
             CUJ_LAUNCHER_LAUNCH_APP_PAIR_FROM_TASKBAR,
-            CUJ_LAUNCHER_SAVE_APP_PAIR
+            CUJ_LAUNCHER_SAVE_APP_PAIR,
+            CUJ_LAUNCHER_ALL_APPS_SEARCH_BACK,
+            CUJ_LAUNCHER_TASKBAR_ALL_APPS_CLOSE_BACK,
+            CUJ_LAUNCHER_TASKBAR_ALL_APPS_SEARCH_BACK,
+            CUJ_LAUNCHER_WIDGET_PICKER_CLOSE_BACK,
+            CUJ_LAUNCHER_WIDGET_PICKER_SEARCH_BACK,
+            CUJ_LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface CujType {
@@ -315,6 +328,13 @@
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_LAUNCH_APP_PAIR_FROM_WORKSPACE] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_LAUNCH_APP_PAIR_FROM_WORKSPACE;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_LAUNCH_APP_PAIR_FROM_TASKBAR] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_LAUNCH_APP_PAIR_FROM_TASKBAR;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_SAVE_APP_PAIR] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_SAVE_APP_PAIR;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_ALL_APPS_SEARCH_BACK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_ALL_APPS_SEARCH_BACK;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_TASKBAR_ALL_APPS_CLOSE_BACK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_TASKBAR_ALL_APPS_CLOSE_BACK;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_TASKBAR_ALL_APPS_SEARCH_BACK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_TASKBAR_ALL_APPS_SEARCH_BACK;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_WIDGET_PICKER_CLOSE_BACK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_WIDGET_PICKER_CLOSE_BACK;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_WIDGET_PICKER_SEARCH_BACK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_WIDGET_PICKER_SEARCH_BACK;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK;
     }
 
     private Cuj() {
@@ -499,6 +519,20 @@
                 return "LAUNCHER_LAUNCH_APP_PAIR_FROM_TASKBAR";
             case CUJ_LAUNCHER_SAVE_APP_PAIR:
                 return "LAUNCHER_SAVE_APP_PAIR";
+            case CUJ_LAUNCHER_ALL_APPS_SEARCH_BACK:
+                return "LAUNCHER_ALL_APPS_SEARCH_BACK";
+            case CUJ_LAUNCHER_TASKBAR_ALL_APPS_CLOSE_BACK:
+                return "LAUNCHER_TASKBAR_ALL_APPS_CLOSE_BACK";
+            case CUJ_LAUNCHER_TASKBAR_ALL_APPS_SEARCH_BACK:
+                return "LAUNCHER_TASKBAR_ALL_APPS_SEARCH_BACK";
+            case CUJ_LAUNCHER_WIDGET_PICKER_CLOSE_BACK:
+                return "LAUNCHER_WIDGET_PICKER_CLOSE_BACK";
+            case CUJ_LAUNCHER_WIDGET_PICKER_SEARCH_BACK:
+                return "LAUNCHER_WIDGET_PICKER_SEARCH_BACK";
+            case CUJ_LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK:
+                return "LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK";
+            case CUJ_LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK:
+                return "LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK";
         }
         return "UNKNOWN";
     }
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index a288fb7..b86cbfb 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -168,6 +168,13 @@
     @Deprecated public static final int CUJ_LAUNCHER_LAUNCH_APP_PAIR_FROM_WORKSPACE = Cuj.CUJ_LAUNCHER_LAUNCH_APP_PAIR_FROM_WORKSPACE;
     @Deprecated public static final int CUJ_LAUNCHER_LAUNCH_APP_PAIR_FROM_TASKBAR = Cuj.CUJ_LAUNCHER_LAUNCH_APP_PAIR_FROM_TASKBAR;
     @Deprecated public static final int CUJ_LAUNCHER_SAVE_APP_PAIR = Cuj.CUJ_LAUNCHER_SAVE_APP_PAIR;
+    @Deprecated public static final int CUJ_LAUNCHER_ALL_APPS_SEARCH_BACK = Cuj.CUJ_LAUNCHER_ALL_APPS_SEARCH_BACK;
+    @Deprecated public static final int CUJ_LAUNCHER_TASKBAR_ALL_APPS_CLOSE_BACK = Cuj.CUJ_LAUNCHER_TASKBAR_ALL_APPS_CLOSE_BACK;
+    @Deprecated public static final int CUJ_LAUNCHER_TASKBAR_ALL_APPS_SEARCH_BACK = Cuj.CUJ_LAUNCHER_TASKBAR_ALL_APPS_SEARCH_BACK;
+    @Deprecated public static final int CUJ_LAUNCHER_WIDGET_PICKER_CLOSE_BACK = Cuj.CUJ_LAUNCHER_WIDGET_PICKER_CLOSE_BACK;
+    @Deprecated public static final int CUJ_LAUNCHER_WIDGET_PICKER_SEARCH_BACK = Cuj.CUJ_LAUNCHER_WIDGET_PICKER_SEARCH_BACK;
+    @Deprecated public static final int CUJ_LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK = Cuj.CUJ_LAUNCHER_WIDGET_BOTTOM_SHEET_CLOSE_BACK;
+    @Deprecated public static final int CUJ_LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK = Cuj.CUJ_LAUNCHER_WIDGET_EDU_SHEET_CLOSE_BACK;
 
     private static class InstanceHolder {
         public static final InteractionJankMonitor INSTANCE =
diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java
index c14d8d8..8063be6 100644
--- a/core/java/com/android/internal/os/BinderInternal.java
+++ b/core/java/com/android/internal/os/BinderInternal.java
@@ -45,8 +45,8 @@
     static ArrayList<Runnable> sGcWatchers = new ArrayList<>();
     static Runnable[] sTmpWatchers = new Runnable[1];
     static long sLastGcTime;
-    static final BinderProxyLimitListenerDelegate sBinderProxyLimitListenerDelegate =
-            new BinderProxyLimitListenerDelegate();
+    static final BinderProxyCountEventListenerDelegate sBinderProxyCountEventListenerDelegate =
+            new BinderProxyCountEventListenerDelegate();
 
     static final class GcWatcher {
         @Override
@@ -226,15 +226,24 @@
      * @param low   The threshold a binder count must drop below before the callback
      *              can be called again. (This is to avoid many repeated calls to the
      *              callback in a brief period of time)
+     * @param warning The threshold between {@code high} and {@code low} where if the binder count
+     *                exceeds that, the warning callback would be triggered.
      */
-    public static final native void nSetBinderProxyCountWatermarks(int high, int low);
+    public static final native void nSetBinderProxyCountWatermarks(int high, int low, int warning);
 
     /**
      * Interface for callback invocation when the Binder Proxy limit is reached. onLimitReached will
      * be called with the uid of the app causing too many Binder Proxies
      */
-    public interface BinderProxyLimitListener {
+    public interface BinderProxyCountEventListener {
         public void onLimitReached(int uid);
+
+        /**
+         * Call when the number of binder proxies from the uid of the app reaches
+         * the warning threshold.
+         */
+        default void onWarningThresholdReached(int uid) {
+        }
     }
 
     /**
@@ -243,7 +252,17 @@
      * @param uid The uid of the bad behaving app sending too many binders
      */
     public static void binderProxyLimitCallbackFromNative(int uid) {
-       sBinderProxyLimitListenerDelegate.notifyClient(uid);
+        sBinderProxyCountEventListenerDelegate.notifyLimitReached(uid);
+    }
+
+    /**
+     * Callback used by native code to trigger a callback in java code. The callback will be
+     * triggered when too many binder proxies from a uid hits the warning limit.
+     * @param uid The uid of the bad behaving app sending too many binders
+     */
+    @SuppressWarnings("unused")
+    public static void binderProxyWarningCallbackFromNative(int uid) {
+        sBinderProxyCountEventListenerDelegate.notifyWarningReached(uid);
     }
 
     /**
@@ -252,41 +271,45 @@
      * @param handler must not be null, callback will be posted through the handler;
      *
      */
-    public static void setBinderProxyCountCallback(BinderProxyLimitListener listener,
+    public static void setBinderProxyCountCallback(BinderProxyCountEventListener listener,
             @NonNull Handler handler) {
         Preconditions.checkNotNull(handler,
                 "Must provide NonNull Handler to setBinderProxyCountCallback when setting "
-                        + "BinderProxyLimitListener");
-        sBinderProxyLimitListenerDelegate.setListener(listener, handler);
+                        + "BinderProxyCountEventListener");
+        sBinderProxyCountEventListenerDelegate.setListener(listener, handler);
     }
 
     /**
      * Clear the Binder Proxy callback
      */
     public static void clearBinderProxyCountCallback() {
-        sBinderProxyLimitListenerDelegate.setListener(null, null);
+        sBinderProxyCountEventListenerDelegate.setListener(null, null);
     }
 
-    static private class BinderProxyLimitListenerDelegate {
-        private BinderProxyLimitListener mBinderProxyLimitListener;
+    private static class BinderProxyCountEventListenerDelegate {
+        private BinderProxyCountEventListener mBinderProxyCountEventListener;
         private Handler mHandler;
 
-        void setListener(BinderProxyLimitListener listener, Handler handler) {
+        void setListener(BinderProxyCountEventListener listener, Handler handler) {
             synchronized (this) {
-                mBinderProxyLimitListener = listener;
+                mBinderProxyCountEventListener = listener;
                 mHandler = handler;
             }
         }
 
-        void notifyClient(final int uid) {
+        void notifyLimitReached(final int uid) {
             synchronized (this) {
-                if (mBinderProxyLimitListener != null) {
-                    mHandler.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            mBinderProxyLimitListener.onLimitReached(uid);
-                        }
-                    });
+                if (mBinderProxyCountEventListener != null) {
+                    mHandler.post(() -> mBinderProxyCountEventListener.onLimitReached(uid));
+                }
+            }
+        }
+
+        void notifyWarningReached(final int uid) {
+            synchronized (this) {
+                if (mBinderProxyCountEventListener != null) {
+                    mHandler.post(() ->
+                            mBinderProxyCountEventListener.onWarningThresholdReached(uid));
                 }
             }
         }
diff --git a/core/java/com/android/internal/pm/pkg/component/flags/flags.aconfig b/core/java/com/android/internal/pm/pkg/component/flags/flags.aconfig
index ea9abdb..89db1cb 100644
--- a/core/java/com/android/internal/pm/pkg/component/flags/flags.aconfig
+++ b/core/java/com/android/internal/pm/pkg/component/flags/flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.internal.pm.pkg.component.flags"
+container: "system"
 
 flag {
     name: "enable_per_process_use_embedded_dex_attr"
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 02cb53e..e6a2a6c 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -22,6 +22,8 @@
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 import static android.view.WindowInsetsController.APPEARANCE_FORCE_LIGHT_NAVIGATION_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
 import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
 import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
@@ -2628,15 +2630,24 @@
                 false)) {
             params.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION;
         }
-        final int sysUiVis = decor.getSystemUiVisibility();
-        final int statusLightFlag = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
-        final int statusFlag = a.getBoolean(R.styleable.Window_windowLightStatusBar, false)
-                ? statusLightFlag : 0;
-        final int navLightFlag = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
-        final int navFlag = a.getBoolean(R.styleable.Window_windowLightNavigationBar, false)
-                ? navLightFlag : 0;
+
+        final boolean lightStatus = a.getBoolean(R.styleable.Window_windowLightStatusBar, false);
+        final boolean lightNav = a.getBoolean(R.styleable.Window_windowLightNavigationBar, false);
+
+        // Here still sets the light bar flags via setSystemUiVisibility (even it is deprecated) to
+        // make the light bar state be able to be read from the legacy method.
         decor.setSystemUiVisibility(
-                (sysUiVis & ~(statusLightFlag | navLightFlag)) | (statusFlag | navFlag));
+                (decor.getSystemUiVisibility()
+                        & ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
+                                | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR))
+                | (lightStatus ? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0)
+                | (lightNav ? View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR : 0));
+
+        decor.getWindowInsetsController().setSystemBarsAppearanceFromResource(
+                (lightStatus ? APPEARANCE_LIGHT_STATUS_BARS : 0)
+                        | (lightNav ? APPEARANCE_LIGHT_NAVIGATION_BARS : 0),
+                APPEARANCE_LIGHT_STATUS_BARS | APPEARANCE_LIGHT_NAVIGATION_BARS);
+
         if (a.hasValue(R.styleable.Window_windowLayoutInDisplayCutoutMode)) {
             int mode = a.getInt(R.styleable.Window_windowLayoutInDisplayCutoutMode, -1);
             if (mode < LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
@@ -3945,6 +3956,9 @@
 
     @Override
     public int getNavigationBarColor() {
+        if (mEdgeToEdgeEnforced) {
+            return Color.TRANSPARENT;
+        }
         return mNavigationBarColor;
     }
 
diff --git a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
index 2096ba4..d244874 100644
--- a/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/LegacyProtoLogImpl.java
@@ -66,6 +66,7 @@
     private final TraceBuffer mBuffer;
     private final LegacyProtoLogViewerConfigReader mViewerConfig;
     private final TreeMap<String, IProtoLogGroup> mLogGroups;
+    private final Runnable mCacheUpdater;
     private final int mPerChunkSize;
 
     private boolean mProtoLogEnabled;
@@ -73,20 +74,21 @@
     private final Object mProtoLogEnabledLock = new Object();
 
     public LegacyProtoLogImpl(String outputFile, String viewerConfigFilename,
-            TreeMap<String, IProtoLogGroup> logGroups) {
+            TreeMap<String, IProtoLogGroup> logGroups, Runnable cacheUpdater) {
         this(new File(outputFile), viewerConfigFilename, BUFFER_CAPACITY,
-                new LegacyProtoLogViewerConfigReader(), PER_CHUNK_SIZE, logGroups);
+                new LegacyProtoLogViewerConfigReader(), PER_CHUNK_SIZE, logGroups, cacheUpdater);
     }
 
     public LegacyProtoLogImpl(File file, String viewerConfigFilename, int bufferCapacity,
             LegacyProtoLogViewerConfigReader viewerConfig, int perChunkSize,
-            TreeMap<String, IProtoLogGroup> logGroups) {
+            TreeMap<String, IProtoLogGroup> logGroups, Runnable cacheUpdater) {
         mLogFile = file;
         mBuffer = new TraceBuffer(bufferCapacity);
         mLegacyViewerConfigFilename = viewerConfigFilename;
         mViewerConfig = viewerConfig;
         mPerChunkSize = perChunkSize;
-        this.mLogGroups = logGroups;
+        mLogGroups = logGroups;
+        mCacheUpdater = cacheUpdater;
     }
 
     /**
@@ -285,6 +287,8 @@
                 return -1;
             }
         }
+
+        mCacheUpdater.run();
         return 0;
     }
 
@@ -399,5 +403,12 @@
     public int stopLoggingToLogcat(String[] groups, ILogger logger) {
         return setLogging(true /* setTextLogging */, false, logger, groups);
     }
+
+    @Override
+    public boolean isEnabled(IProtoLogGroup group, LogLevel level) {
+        // In legacy logging we just enable an entire group at a time without more granular control,
+        // so we ignore the level argument to this function.
+        return group.isLogToLogcat() || (group.isLogToProto() && isProtoEnabled());
+    }
 }
 
diff --git a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
index 4ead82f..9f3ce81 100644
--- a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
@@ -16,33 +16,34 @@
 
 package com.android.internal.protolog;
 
-import static perfetto.protos.PerfettoTrace.InternedData.PROTOLOG_STACKTRACE;
-import static perfetto.protos.PerfettoTrace.InternedData.PROTOLOG_STRING_ARGS;
-import static perfetto.protos.PerfettoTrace.InternedString.IID;
-import static perfetto.protos.PerfettoTrace.InternedString.STR;
-import static perfetto.protos.PerfettoTrace.ProtoLogMessage.BOOLEAN_PARAMS;
-import static perfetto.protos.PerfettoTrace.ProtoLogMessage.DOUBLE_PARAMS;
-import static perfetto.protos.PerfettoTrace.ProtoLogMessage.MESSAGE_ID;
-import static perfetto.protos.PerfettoTrace.ProtoLogMessage.SINT64_PARAMS;
-import static perfetto.protos.PerfettoTrace.ProtoLogMessage.STACKTRACE_IID;
-import static perfetto.protos.PerfettoTrace.ProtoLogMessage.STR_PARAM_IIDS;
-import static perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.GROUPS;
-import static perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.Group.ID;
-import static perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.Group.NAME;
-import static perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.Group.TAG;
-import static perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MESSAGES;
-import static perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MessageData.GROUP_ID;
-import static perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MessageData.LEVEL;
-import static perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MessageData.MESSAGE;
-import static perfetto.protos.PerfettoTrace.TracePacket.INTERNED_DATA;
-import static perfetto.protos.PerfettoTrace.TracePacket.PROTOLOG_MESSAGE;
-import static perfetto.protos.PerfettoTrace.TracePacket.PROTOLOG_VIEWER_CONFIG;
-import static perfetto.protos.PerfettoTrace.TracePacket.SEQUENCE_FLAGS;
-import static perfetto.protos.PerfettoTrace.TracePacket.SEQ_INCREMENTAL_STATE_CLEARED;
-import static perfetto.protos.PerfettoTrace.TracePacket.SEQ_NEEDS_INCREMENTAL_STATE;
-import static perfetto.protos.PerfettoTrace.TracePacket.TIMESTAMP;
+import static android.internal.perfetto.protos.PerfettoTrace.InternedData.PROTOLOG_STACKTRACE;
+import static android.internal.perfetto.protos.PerfettoTrace.InternedData.PROTOLOG_STRING_ARGS;
+import static android.internal.perfetto.protos.PerfettoTrace.InternedString.IID;
+import static android.internal.perfetto.protos.PerfettoTrace.InternedString.STR;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogMessage.BOOLEAN_PARAMS;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogMessage.DOUBLE_PARAMS;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogMessage.MESSAGE_ID;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogMessage.SINT64_PARAMS;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogMessage.STACKTRACE_IID;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogMessage.STR_PARAM_IIDS;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.GROUPS;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.Group.ID;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.Group.NAME;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.Group.TAG;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MESSAGES;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MessageData.GROUP_ID;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MessageData.LEVEL;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MessageData.MESSAGE;
+import static android.internal.perfetto.protos.PerfettoTrace.TracePacket.INTERNED_DATA;
+import static android.internal.perfetto.protos.PerfettoTrace.TracePacket.PROTOLOG_MESSAGE;
+import static android.internal.perfetto.protos.PerfettoTrace.TracePacket.PROTOLOG_VIEWER_CONFIG;
+import static android.internal.perfetto.protos.PerfettoTrace.TracePacket.SEQUENCE_FLAGS;
+import static android.internal.perfetto.protos.PerfettoTrace.TracePacket.SEQ_INCREMENTAL_STATE_CLEARED;
+import static android.internal.perfetto.protos.PerfettoTrace.TracePacket.SEQ_NEEDS_INCREMENTAL_STATE;
+import static android.internal.perfetto.protos.PerfettoTrace.TracePacket.TIMESTAMP;
 
 import android.annotation.Nullable;
+import android.internal.perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MessageData;
 import android.os.ShellCommand;
 import android.os.SystemClock;
 import android.os.Trace;
@@ -51,6 +52,7 @@
 import android.tracing.perfetto.InitArguments;
 import android.tracing.perfetto.Producer;
 import android.tracing.perfetto.TracingContext;
+import android.util.ArrayMap;
 import android.util.LongArray;
 import android.util.Slog;
 import android.util.proto.ProtoInputStream;
@@ -69,13 +71,12 @@
 import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Map;
+import java.util.Set;
 import java.util.TreeMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MessageData;
-
 /**
  * A service for the ProtoLog logging system.
  */
@@ -84,18 +85,22 @@
     private final AtomicInteger mTracingInstances = new AtomicInteger();
 
     private final ProtoLogDataSource mDataSource = new ProtoLogDataSource(
-            this.mTracingInstances::incrementAndGet,
+            this::onTracingInstanceStart,
             this::dumpTransitionTraceConfig,
-            this.mTracingInstances::decrementAndGet
+            this::onTracingInstanceStop
     );
     private final ProtoLogViewerConfigReader mViewerConfigReader;
     private final ViewerConfigInputStreamProvider mViewerConfigInputStreamProvider;
     private final TreeMap<String, IProtoLogGroup> mLogGroups;
+    private final Runnable mCacheUpdater;
+
+    private final Map<LogLevel, Integer> mDefaultLogLevelCounts = new ArrayMap<>();
+    private final Map<IProtoLogGroup, Map<LogLevel, Integer>> mLogLevelCounts = new ArrayMap<>();
 
     private final ExecutorService mBackgroundLoggingService = Executors.newCachedThreadPool();
 
     public PerfettoProtoLogImpl(String viewerConfigFilePath,
-            TreeMap<String, IProtoLogGroup> logGroups) {
+            TreeMap<String, IProtoLogGroup> logGroups, Runnable cacheUpdater) {
         this(() -> {
             try {
                 return new ProtoInputStream(new FileInputStream(viewerConfigFilePath));
@@ -103,28 +108,32 @@
                 Slog.w(LOG_TAG, "Failed to load viewer config file " + viewerConfigFilePath, e);
                 return null;
             }
-        }, logGroups);
+        }, logGroups, cacheUpdater);
     }
 
     public PerfettoProtoLogImpl(
             ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
-            TreeMap<String, IProtoLogGroup> logGroups
+            TreeMap<String, IProtoLogGroup> logGroups,
+            Runnable cacheUpdater
     ) {
         this(viewerConfigInputStreamProvider,
-                new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider), logGroups);
+                new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider), logGroups,
+                cacheUpdater);
     }
 
     @VisibleForTesting
     public PerfettoProtoLogImpl(
             ViewerConfigInputStreamProvider viewerConfigInputStreamProvider,
             ProtoLogViewerConfigReader viewerConfigReader,
-            TreeMap<String, IProtoLogGroup> logGroups
+            TreeMap<String, IProtoLogGroup> logGroups,
+            Runnable cacheUpdater
     ) {
         Producer.init(InitArguments.DEFAULTS);
         mDataSource.register(DataSourceParams.DEFAULTS);
         this.mViewerConfigInputStreamProvider = viewerConfigInputStreamProvider;
         this.mViewerConfigReader = viewerConfigReader;
         this.mLogGroups = logGroups;
+        this.mCacheUpdater = cacheUpdater;
     }
 
     /**
@@ -495,6 +504,29 @@
         return setTextLogging(false, logger, groups);
     }
 
+    @Override
+    public boolean isEnabled(IProtoLogGroup group, LogLevel level) {
+        return group.isLogToLogcat() || getLogFromLevel(group).ordinal() <= level.ordinal();
+    }
+
+    private LogLevel getLogFromLevel(IProtoLogGroup group) {
+        if (mLogLevelCounts.containsKey(group)) {
+            for (LogLevel logLevel : LogLevel.values()) {
+                if (mLogLevelCounts.get(group).getOrDefault(logLevel, 0) > 0) {
+                    return logLevel;
+                }
+            }
+        } else {
+            for (LogLevel logLevel : LogLevel.values()) {
+                if (mDefaultLogLevelCounts.getOrDefault(logLevel, 0) > 0) {
+                    return logLevel;
+                }
+            }
+        }
+
+        return LogLevel.WTF;
+    }
+
     /**
      * Start logging the stack trace of the when the log message happened for target groups
      * @return status code
@@ -522,6 +554,8 @@
                 return -1;
             }
         }
+
+        mCacheUpdater.run();
         return 0;
     }
 
@@ -568,6 +602,61 @@
         return -1;
     }
 
+    private synchronized void onTracingInstanceStart(ProtoLogDataSource.ProtoLogConfig config) {
+        this.mTracingInstances.incrementAndGet();
+
+        final LogLevel defaultLogFrom = config.getDefaultGroupConfig().logFrom;
+        mDefaultLogLevelCounts.put(defaultLogFrom,
+                mDefaultLogLevelCounts.getOrDefault(defaultLogFrom, 0) + 1);
+
+        final Set<String> overriddenGroupTags = config.getGroupTagsWithOverriddenConfigs();
+
+        for (String overriddenGroupTag : overriddenGroupTags) {
+            IProtoLogGroup group = mLogGroups.get(overriddenGroupTag);
+
+            mLogLevelCounts.putIfAbsent(group, new ArrayMap<>());
+            final Map<LogLevel, Integer> logLevelsCountsForGroup = mLogLevelCounts.get(group);
+
+            final LogLevel logFromLevel = config.getConfigFor(overriddenGroupTag).logFrom;
+            logLevelsCountsForGroup.put(logFromLevel,
+                    logLevelsCountsForGroup.getOrDefault(logFromLevel, 0) + 1);
+        }
+
+        mCacheUpdater.run();
+    }
+
+    private synchronized void onTracingInstanceStop(ProtoLogDataSource.ProtoLogConfig config) {
+        this.mTracingInstances.decrementAndGet();
+
+        final LogLevel defaultLogFrom = config.getDefaultGroupConfig().logFrom;
+        mDefaultLogLevelCounts.put(defaultLogFrom,
+                mDefaultLogLevelCounts.get(defaultLogFrom) - 1);
+        if (mDefaultLogLevelCounts.get(defaultLogFrom) <= 0) {
+            mDefaultLogLevelCounts.remove(defaultLogFrom);
+        }
+
+        final Set<String> overriddenGroupTags = config.getGroupTagsWithOverriddenConfigs();
+
+        for (String overriddenGroupTag : overriddenGroupTags) {
+            IProtoLogGroup group = mLogGroups.get(overriddenGroupTag);
+
+            mLogLevelCounts.putIfAbsent(group, new ArrayMap<>());
+            final Map<LogLevel, Integer> logLevelsCountsForGroup = mLogLevelCounts.get(group);
+
+            final LogLevel logFromLevel = config.getConfigFor(overriddenGroupTag).logFrom;
+            logLevelsCountsForGroup.put(logFromLevel,
+                    logLevelsCountsForGroup.get(logFromLevel) - 1);
+            if (logLevelsCountsForGroup.get(logFromLevel) <= 0) {
+                logLevelsCountsForGroup.remove(logFromLevel);
+            }
+            if (logLevelsCountsForGroup.isEmpty()) {
+                mLogLevelCounts.remove(group);
+            }
+        }
+
+        mCacheUpdater.run();
+    }
+
     static void logAndPrintln(@Nullable PrintWriter pw, String msg) {
         Slog.i(LOG_TAG, msg);
         if (pw != null) {
diff --git a/core/java/com/android/internal/protolog/ProtoLogDataSource.java b/core/java/com/android/internal/protolog/ProtoLogDataSource.java
index a8ff75d..e79bf36 100644
--- a/core/java/com/android/internal/protolog/ProtoLogDataSource.java
+++ b/core/java/com/android/internal/protolog/ProtoLogDataSource.java
@@ -16,13 +16,14 @@
 
 package com.android.internal.protolog;
 
-import static perfetto.protos.PerfettoTrace.DataSourceConfig.PROTOLOG_CONFIG;
-import static perfetto.protos.PerfettoTrace.ProtoLogConfig.GROUP_OVERRIDES;
-import static perfetto.protos.PerfettoTrace.ProtoLogConfig.TRACING_MODE;
-import static perfetto.protos.PerfettoTrace.ProtoLogGroup.COLLECT_STACKTRACE;
-import static perfetto.protos.PerfettoTrace.ProtoLogGroup.LOG_FROM;
-import static perfetto.protos.PerfettoTrace.ProtoLogGroup.GROUP_NAME;
+import static android.internal.perfetto.protos.PerfettoTrace.DataSourceConfig.PROTOLOG_CONFIG;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogConfig.GROUP_OVERRIDES;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogConfig.TRACING_MODE;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogGroup.COLLECT_STACKTRACE;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogGroup.GROUP_NAME;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogGroup.LOG_FROM;
 
+import android.internal.perfetto.protos.PerfettoTrace;
 import android.tracing.perfetto.CreateIncrementalStateArgs;
 import android.tracing.perfetto.CreateTlsStateArgs;
 import android.tracing.perfetto.DataSource;
@@ -38,18 +39,19 @@
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
-
-import perfetto.protos.PerfettoTrace;
+import java.util.Set;
+import java.util.function.Consumer;
 
 public class ProtoLogDataSource extends DataSource<ProtoLogDataSource.Instance,
         ProtoLogDataSource.TlsState,
         ProtoLogDataSource.IncrementalState> {
 
-    private final Runnable mOnStart;
+    private final Consumer<ProtoLogConfig> mOnStart;
     private final Runnable mOnFlush;
-    private final Runnable mOnStop;
+    private final Consumer<ProtoLogConfig> mOnStop;
 
-    public ProtoLogDataSource(Runnable onStart, Runnable onFlush, Runnable onStop) {
+    public ProtoLogDataSource(Consumer<ProtoLogConfig> onStart, Runnable onFlush,
+            Consumer<ProtoLogConfig> onStop) {
         super("android.protolog");
         this.mOnStart = onStart;
         this.mOnFlush = onFlush;
@@ -139,7 +141,7 @@
         public boolean clearReported = false;
     }
 
-    private static class ProtoLogConfig {
+    public static class ProtoLogConfig {
         private final LogLevel mDefaultLogFromLevel;
         private final Map<String, GroupConfig> mGroupConfigs;
 
@@ -152,13 +154,17 @@
             this.mGroupConfigs = groupConfigs;
         }
 
-        private GroupConfig getConfigFor(String groupTag) {
+        public GroupConfig getConfigFor(String groupTag) {
             return mGroupConfigs.getOrDefault(groupTag, getDefaultGroupConfig());
         }
 
-        private GroupConfig getDefaultGroupConfig() {
+        public GroupConfig getDefaultGroupConfig() {
             return new GroupConfig(mDefaultLogFromLevel, false);
         }
+
+        public Set<String> getGroupTagsWithOverriddenConfigs() {
+            return mGroupConfigs.keySet();
+        }
     }
 
     public static class GroupConfig {
@@ -256,18 +262,18 @@
 
     public static class Instance extends DataSourceInstance {
 
-        private final Runnable mOnStart;
+        private final Consumer<ProtoLogConfig> mOnStart;
         private final Runnable mOnFlush;
-        private final Runnable mOnStop;
+        private final Consumer<ProtoLogConfig> mOnStop;
         private final ProtoLogConfig mConfig;
 
         public Instance(
                 DataSource<Instance, TlsState, IncrementalState> dataSource,
                 int instanceIdx,
                 ProtoLogConfig config,
-                Runnable onStart,
+                Consumer<ProtoLogConfig> onStart,
                 Runnable onFlush,
-                Runnable onStop
+                Consumer<ProtoLogConfig> onStop
         ) {
             super(dataSource, instanceIdx);
             this.mOnStart = onStart;
@@ -278,7 +284,7 @@
 
         @Override
         public void onStart(StartCallbackArguments args) {
-            this.mOnStart.run();
+            this.mOnStart.accept(this.mConfig);
         }
 
         @Override
@@ -288,7 +294,7 @@
 
         @Override
         public void onStop(StopCallbackArguments args) {
-            this.mOnStop.run();
+            this.mOnStop.accept(this.mConfig);
         }
     }
 }
diff --git a/core/java/com/android/internal/protolog/ProtoLogImpl.java b/core/java/com/android/internal/protolog/ProtoLogImpl.java
index 487ae814..6d142af 100644
--- a/core/java/com/android/internal/protolog/ProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/ProtoLogImpl.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.protolog;
 
+import static com.android.internal.protolog.common.ProtoLogToolInjected.Value.CACHE_UPDATER;
 import static com.android.internal.protolog.common.ProtoLogToolInjected.Value.LEGACY_OUTPUT_FILE_PATH;
 import static com.android.internal.protolog.common.ProtoLogToolInjected.Value.LEGACY_VIEWER_CONFIG_PATH;
 import static com.android.internal.protolog.common.ProtoLogToolInjected.Value.LOG_GROUPS;
@@ -49,6 +50,9 @@
     @ProtoLogToolInjected(LOG_GROUPS)
     private static TreeMap<String, IProtoLogGroup> sLogGroups;
 
+    @ProtoLogToolInjected(CACHE_UPDATER)
+    private static Runnable sCacheUpdater;
+
     /** Used by the ProtoLogTool, do not call directly - use {@code ProtoLog} class instead. */
     public static void d(IProtoLogGroup group, long messageHash, int paramsMask,
             @Nullable String messageString,
@@ -94,9 +98,12 @@
         getSingleInstance().log(LogLevel.WTF, group, messageHash, paramsMask, messageString, args);
     }
 
-    public static boolean isEnabled(IProtoLogGroup group) {
-        // TODO: Implement for performance reasons, with optional level parameter?
-        return true;
+    /**
+     * Should return true iff we should be logging to either protolog or logcat for this group
+     * and log level.
+     */
+    public static boolean isEnabled(IProtoLogGroup group, LogLevel level) {
+        return getSingleInstance().isEnabled(group, level);
     }
 
     /**
@@ -105,11 +112,14 @@
     public static synchronized IProtoLog getSingleInstance() {
         if (sServiceInstance == null) {
             if (android.tracing.Flags.perfettoProtologTracing()) {
-                sServiceInstance = new PerfettoProtoLogImpl(sViewerConfigPath, sLogGroups);
+                sServiceInstance = new PerfettoProtoLogImpl(
+                        sViewerConfigPath, sLogGroups, sCacheUpdater);
             } else {
                 sServiceInstance = new LegacyProtoLogImpl(
-                        sLegacyOutputFilePath, sLegacyViewerConfigPath, sLogGroups);
+                        sLegacyOutputFilePath, sLegacyViewerConfigPath, sLogGroups, sCacheUpdater);
             }
+
+            sCacheUpdater.run();
         }
         return sServiceInstance;
     }
diff --git a/core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java b/core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java
index ae3d448..88a7b54 100644
--- a/core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java
+++ b/core/java/com/android/internal/protolog/ProtoLogViewerConfigReader.java
@@ -1,8 +1,8 @@
 package com.android.internal.protolog;
 
-import static perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MESSAGES;
-import static perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MessageData.MESSAGE;
-import static perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MessageData.MESSAGE_ID;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MESSAGES;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MessageData.MESSAGE;
+import static android.internal.perfetto.protos.PerfettoTrace.ProtoLogViewerConfig.MessageData.MESSAGE_ID;
 
 import android.util.ArrayMap;
 import android.util.proto.ProtoInputStream;
diff --git a/core/java/com/android/internal/protolog/common/IProtoLog.java b/core/java/com/android/internal/protolog/common/IProtoLog.java
index c06d14b..f72d9f7 100644
--- a/core/java/com/android/internal/protolog/common/IProtoLog.java
+++ b/core/java/com/android/internal/protolog/common/IProtoLog.java
@@ -52,4 +52,12 @@
      * @return status code
      */
     int stopLoggingToLogcat(String[] groups, ILogger logger);
+
+    /**
+     * Should return true iff logging is enabled to ProtoLog or to Logcat for this group and level.
+     * @param group ProtoLog group to check for.
+     * @param level ProtoLog level to check for.
+     * @return If we need to log this group and level to either ProtoLog or Logcat.
+     */
+    boolean isEnabled(IProtoLogGroup group, LogLevel level);
 }
diff --git a/core/java/com/android/internal/protolog/common/IProtoLogGroup.java b/core/java/com/android/internal/protolog/common/IProtoLogGroup.java
index 4e9686f99..149aa7a 100644
--- a/core/java/com/android/internal/protolog/common/IProtoLogGroup.java
+++ b/core/java/com/android/internal/protolog/common/IProtoLogGroup.java
@@ -38,6 +38,7 @@
 
     /**
      * returns true is any logging is enabled for this group.
+     * @deprecated TODO(b/324128613) remove once we migrate fully to Perfetto
      */
     default boolean isLogToAny() {
         return isLogToLogcat() || isLogToProto();
@@ -50,6 +51,7 @@
 
     /**
      * set binary logging for this group.
+     * @deprecated TODO(b/324128613) remove once we migrate fully to Perfetto
      */
     void setLogToProto(boolean logToProto);
 
diff --git a/core/java/com/android/internal/protolog/common/ProtoLog.java b/core/java/com/android/internal/protolog/common/ProtoLog.java
index 18e3f66..8149cd5 100644
--- a/core/java/com/android/internal/protolog/common/ProtoLog.java
+++ b/core/java/com/android/internal/protolog/common/ProtoLog.java
@@ -135,7 +135,7 @@
      * @param group Group to check enable status of.
      * @return true iff this is being logged.
      */
-    public static boolean isEnabled(IProtoLogGroup group) {
+    public static boolean isEnabled(IProtoLogGroup group, LogLevel level) {
         if (REQUIRE_PROTOLOGTOOL) {
             throw new UnsupportedOperationException(
                     "ProtoLog calls MUST be processed with ProtoLogTool");
diff --git a/core/java/com/android/internal/protolog/common/ProtoLogToolInjected.java b/core/java/com/android/internal/protolog/common/ProtoLogToolInjected.java
index 17c82d7..2d39f3b 100644
--- a/core/java/com/android/internal/protolog/common/ProtoLogToolInjected.java
+++ b/core/java/com/android/internal/protolog/common/ProtoLogToolInjected.java
@@ -23,7 +23,11 @@
 @Target({ElementType.FIELD, ElementType.PARAMETER})
 public @interface ProtoLogToolInjected {
     enum Value {
-        VIEWER_CONFIG_PATH, LEGACY_OUTPUT_FILE_PATH, LEGACY_VIEWER_CONFIG_PATH, LOG_GROUPS
+        VIEWER_CONFIG_PATH,
+        LEGACY_OUTPUT_FILE_PATH,
+        LEGACY_VIEWER_CONFIG_PATH,
+        LOG_GROUPS,
+        CACHE_UPDATER
     }
 
     Value value();
diff --git a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
index cc1f3dd..7423a16 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/RemoteComposePlayer.java
@@ -16,6 +16,7 @@
 package com.android.internal.widget.remotecompose.player;
 
 import android.content.Context;
+import android.graphics.Color;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.ViewGroup;
@@ -97,6 +98,7 @@
                             LayoutParams.MATCH_PARENT);
                     HorizontalScrollView horizontalScrollView =
                             new HorizontalScrollView(getContext());
+                    horizontalScrollView.setBackgroundColor(Color.TRANSPARENT);
                     horizontalScrollView.setFillViewport(true);
                     horizontalScrollView.addView(mInner, layoutParamsInner);
                     LayoutParams layoutParams = new LayoutParams(
@@ -113,6 +115,7 @@
                             LayoutParams.MATCH_PARENT,
                             LayoutParams.WRAP_CONTENT);
                     ScrollView scrollView = new ScrollView(getContext());
+                    scrollView.setBackgroundColor(Color.TRANSPARENT);
                     scrollView.setFillViewport(true);
                     scrollView.addView(mInner, layoutParamsInner);
                     LayoutParams layoutParams = new LayoutParams(
@@ -136,7 +139,9 @@
     private void init(Context context, AttributeSet attrs, int defStyleAttr) {
         LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,
                 LayoutParams.MATCH_PARENT);
+        setBackgroundColor(Color.TRANSPARENT);
         mInner = new RemoteComposeCanvas(context, attrs, defStyleAttr);
+        mInner.setBackgroundColor(Color.TRANSPARENT);
         addView(mInner, layoutParams);
     }
 
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index fd4ff29..03b57d0 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -309,6 +309,7 @@
                 "libdebuggerd_client",
                 "libutils",
                 "libbinder",
+                "libbinderdebug",
                 "libbinder_ndk",
                 "libui",
                 "libgraphicsenv",
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 593bdf0..163f32e 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -110,3 +110,6 @@
 
 # PerformanceHintManager
 per-file android_os_PerformanceHintManager.cpp = file:/ADPF_OWNERS
+
+# IF Tools
+per-file android_tracing_Perfetto* = file:platform/development:/tools/winscope/OWNERS
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index a98f947..3c2dccd 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -16,97 +16,51 @@
 
 #define LOG_TAG "android.os.Debug"
 
+#include "android_os_Debug.h"
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android-base/strings.h>
 #include <assert.h>
+#include <binderdebug/BinderDebug.h>
+#include <bionic/malloc.h>
 #include <ctype.h>
+#include <debuggerd/client.h>
+#include <dmabufinfo/dmabuf_sysfs_stats.h>
+#include <dmabufinfo/dmabufinfo.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
+#include <log/log.h>
 #include <malloc.h>
+#include <meminfo/androidprocheaps.h>
+#include <meminfo/procmeminfo.h>
+#include <meminfo/sysmeminfo.h>
+#include <memtrack/memtrack.h>
+#include <memunreachable/memunreachable.h>
+#include <nativehelper/JNIPlatformHelp.h>
+#include <nativehelper/ScopedUtfChars.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/time.h>
 #include <time.h>
 #include <unistd.h>
+#include <utils/String8.h>
+#include <utils/misc.h>
+#include <vintf/KernelConfigs.h>
 
 #include <iomanip>
 #include <string>
 #include <vector>
 
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <bionic/malloc.h>
-#include <debuggerd/client.h>
-#include <log/log.h>
-#include <utils/misc.h>
-#include <utils/String8.h>
-
-#include <nativehelper/JNIPlatformHelp.h>
-#include <nativehelper/ScopedUtfChars.h>
 #include "jni.h"
-#include <dmabufinfo/dmabuf_sysfs_stats.h>
-#include <dmabufinfo/dmabufinfo.h>
-#include <meminfo/procmeminfo.h>
-#include <meminfo/sysmeminfo.h>
-#include <memtrack/memtrack.h>
-#include <memunreachable/memunreachable.h>
-#include <android-base/strings.h>
-#include "android_os_Debug.h"
-#include <vintf/KernelConfigs.h>
 
 namespace android
 {
 
-enum {
-    HEAP_UNKNOWN,
-    HEAP_DALVIK,
-    HEAP_NATIVE,
-
-    HEAP_DALVIK_OTHER,
-    HEAP_STACK,
-    HEAP_CURSOR,
-    HEAP_ASHMEM,
-    HEAP_GL_DEV,
-    HEAP_UNKNOWN_DEV,
-    HEAP_SO,
-    HEAP_JAR,
-    HEAP_APK,
-    HEAP_TTF,
-    HEAP_DEX,
-    HEAP_OAT,
-    HEAP_ART,
-    HEAP_UNKNOWN_MAP,
-    HEAP_GRAPHICS,
-    HEAP_GL,
-    HEAP_OTHER_MEMTRACK,
-
-    // Dalvik extra sections (heap).
-    HEAP_DALVIK_NORMAL,
-    HEAP_DALVIK_LARGE,
-    HEAP_DALVIK_ZYGOTE,
-    HEAP_DALVIK_NON_MOVING,
-
-    // Dalvik other extra sections.
-    HEAP_DALVIK_OTHER_LINEARALLOC,
-    HEAP_DALVIK_OTHER_ACCOUNTING,
-    HEAP_DALVIK_OTHER_ZYGOTE_CODE_CACHE,
-    HEAP_DALVIK_OTHER_APP_CODE_CACHE,
-    HEAP_DALVIK_OTHER_COMPILER_METADATA,
-    HEAP_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE,
-
-    // Boot vdex / app dex / app vdex
-    HEAP_DEX_BOOT_VDEX,
-    HEAP_DEX_APP_DEX,
-    HEAP_DEX_APP_VDEX,
-
-    // App art, boot art.
-    HEAP_ART_APP,
-    HEAP_ART_BOOT,
-
-    _NUM_HEAP,
-    _NUM_EXCLUSIVE_HEAP = HEAP_OTHER_MEMTRACK+1,
-    _NUM_CORE_HEAP = HEAP_NATIVE+1
-};
+using namespace android::meminfo;
 
 struct stat_fields {
     jfieldID pss_field;
@@ -146,18 +100,6 @@
 static jfieldID otherStats_field;
 static jfieldID hasSwappedOutPss_field;
 
-struct stats_t {
-    int pss;
-    int swappablePss;
-    int rss;
-    int privateDirty;
-    int sharedDirty;
-    int privateClean;
-    int sharedClean;
-    int swappedOut;
-    int swappedOutPss;
-};
-
 #define BINDER_STATS "/proc/binder/stats"
 
 static jlong android_os_Debug_getNativeHeapSize(JNIEnv *env, jobject clazz)
@@ -240,190 +182,14 @@
     return err;
 }
 
-static bool load_maps(int pid, stats_t* stats, bool* foundSwapPss)
-{
-    *foundSwapPss = false;
-    uint64_t prev_end = 0;
-    int prev_heap = HEAP_UNKNOWN;
-
-    std::string smaps_path = base::StringPrintf("/proc/%d/smaps", pid);
-    auto vma_scan = [&](const meminfo::Vma& vma) {
-        int which_heap = HEAP_UNKNOWN;
-        int sub_heap = HEAP_UNKNOWN;
-        bool is_swappable = false;
-        std::string name;
-        if (base::EndsWith(vma.name, " (deleted)")) {
-            name = vma.name.substr(0, vma.name.size() - strlen(" (deleted)"));
-        } else {
-            name = vma.name;
-        }
-
-        uint32_t namesz = name.size();
-        if (base::StartsWith(name, "[heap]")) {
-            which_heap = HEAP_NATIVE;
-        } else if (base::StartsWith(name, "[anon:libc_malloc]")) {
-            which_heap = HEAP_NATIVE;
-        } else if (base::StartsWith(name, "[anon:scudo:")) {
-            which_heap = HEAP_NATIVE;
-        } else if (base::StartsWith(name, "[anon:GWP-ASan")) {
-            which_heap = HEAP_NATIVE;
-        } else if (base::StartsWith(name, "[stack")) {
-            which_heap = HEAP_STACK;
-        } else if (base::StartsWith(name, "[anon:stack_and_tls:")) {
-            which_heap = HEAP_STACK;
-        } else if (base::EndsWith(name, ".so")) {
-            which_heap = HEAP_SO;
-            is_swappable = true;
-        } else if (base::EndsWith(name, ".jar")) {
-            which_heap = HEAP_JAR;
-            is_swappable = true;
-        } else if (base::EndsWith(name, ".apk")) {
-            which_heap = HEAP_APK;
-            is_swappable = true;
-        } else if (base::EndsWith(name, ".ttf")) {
-            which_heap = HEAP_TTF;
-            is_swappable = true;
-        } else if ((base::EndsWith(name, ".odex")) ||
-                (namesz > 4 && strstr(name.c_str(), ".dex") != nullptr)) {
-            which_heap = HEAP_DEX;
-            sub_heap = HEAP_DEX_APP_DEX;
-            is_swappable = true;
-        } else if (base::EndsWith(name, ".vdex")) {
-            which_heap = HEAP_DEX;
-            // Handle system@framework@boot and system/framework/boot|apex
-            if ((strstr(name.c_str(), "@boot") != nullptr) ||
-                    (strstr(name.c_str(), "/boot") != nullptr) ||
-                    (strstr(name.c_str(), "/apex") != nullptr)) {
-                sub_heap = HEAP_DEX_BOOT_VDEX;
-            } else {
-                sub_heap = HEAP_DEX_APP_VDEX;
-            }
-            is_swappable = true;
-        } else if (base::EndsWith(name, ".oat")) {
-            which_heap = HEAP_OAT;
-            is_swappable = true;
-        } else if (base::EndsWith(name, ".art") || base::EndsWith(name, ".art]")) {
-            which_heap = HEAP_ART;
-            // Handle system@framework@boot* and system/framework/boot|apex*
-            if ((strstr(name.c_str(), "@boot") != nullptr) ||
-                    (strstr(name.c_str(), "/boot") != nullptr) ||
-                    (strstr(name.c_str(), "/apex") != nullptr)) {
-                sub_heap = HEAP_ART_BOOT;
-            } else {
-                sub_heap = HEAP_ART_APP;
-            }
-            is_swappable = true;
-        } else if (base::StartsWith(name, "/dev/")) {
-            which_heap = HEAP_UNKNOWN_DEV;
-            if (base::StartsWith(name, "/dev/kgsl-3d0")) {
-                which_heap = HEAP_GL_DEV;
-            } else if (base::StartsWith(name, "/dev/ashmem/CursorWindow")) {
-                which_heap = HEAP_CURSOR;
-            } else if (base::StartsWith(name, "/dev/ashmem/jit-zygote-cache")) {
-                which_heap = HEAP_DALVIK_OTHER;
-                sub_heap = HEAP_DALVIK_OTHER_ZYGOTE_CODE_CACHE;
-            } else if (base::StartsWith(name, "/dev/ashmem")) {
-                which_heap = HEAP_ASHMEM;
-            }
-        } else if (base::StartsWith(name, "/memfd:jit-cache")) {
-          which_heap = HEAP_DALVIK_OTHER;
-          sub_heap = HEAP_DALVIK_OTHER_APP_CODE_CACHE;
-        } else if (base::StartsWith(name, "/memfd:jit-zygote-cache")) {
-          which_heap = HEAP_DALVIK_OTHER;
-          sub_heap = HEAP_DALVIK_OTHER_ZYGOTE_CODE_CACHE;
-        } else if (base::StartsWith(name, "[anon:")) {
-            which_heap = HEAP_UNKNOWN;
-            if (base::StartsWith(name, "[anon:dalvik-")) {
-                which_heap = HEAP_DALVIK_OTHER;
-                if (base::StartsWith(name, "[anon:dalvik-LinearAlloc")) {
-                    sub_heap = HEAP_DALVIK_OTHER_LINEARALLOC;
-                } else if (base::StartsWith(name, "[anon:dalvik-alloc space") ||
-                        base::StartsWith(name, "[anon:dalvik-main space")) {
-                    // This is the regular Dalvik heap.
-                    which_heap = HEAP_DALVIK;
-                    sub_heap = HEAP_DALVIK_NORMAL;
-                } else if (base::StartsWith(name,
-                            "[anon:dalvik-large object space") ||
-                        base::StartsWith(
-                            name, "[anon:dalvik-free list large object space")) {
-                    which_heap = HEAP_DALVIK;
-                    sub_heap = HEAP_DALVIK_LARGE;
-                } else if (base::StartsWith(name, "[anon:dalvik-non moving space")) {
-                    which_heap = HEAP_DALVIK;
-                    sub_heap = HEAP_DALVIK_NON_MOVING;
-                } else if (base::StartsWith(name, "[anon:dalvik-zygote space")) {
-                    which_heap = HEAP_DALVIK;
-                    sub_heap = HEAP_DALVIK_ZYGOTE;
-                } else if (base::StartsWith(name, "[anon:dalvik-indirect ref")) {
-                    sub_heap = HEAP_DALVIK_OTHER_INDIRECT_REFERENCE_TABLE;
-                } else if (base::StartsWith(name, "[anon:dalvik-jit-code-cache") ||
-                        base::StartsWith(name, "[anon:dalvik-data-code-cache")) {
-                    sub_heap = HEAP_DALVIK_OTHER_APP_CODE_CACHE;
-                } else if (base::StartsWith(name, "[anon:dalvik-CompilerMetadata")) {
-                    sub_heap = HEAP_DALVIK_OTHER_COMPILER_METADATA;
-                } else {
-                    sub_heap = HEAP_DALVIK_OTHER_ACCOUNTING;  // Default to accounting.
-                }
-            }
-        } else if (namesz > 0) {
-            which_heap = HEAP_UNKNOWN_MAP;
-        } else if (vma.start == prev_end && prev_heap == HEAP_SO) {
-            // bss section of a shared library
-            which_heap = HEAP_SO;
-        }
-
-        prev_end = vma.end;
-        prev_heap = which_heap;
-
-        const meminfo::MemUsage& usage = vma.usage;
-        if (usage.swap_pss > 0 && *foundSwapPss != true) {
-            *foundSwapPss = true;
-        }
-
-        uint64_t swapable_pss = 0;
-        if (is_swappable && (usage.pss > 0)) {
-            float sharing_proportion = 0.0;
-            if ((usage.shared_clean > 0) || (usage.shared_dirty > 0)) {
-                sharing_proportion = (usage.pss - usage.uss) / (usage.shared_clean + usage.shared_dirty);
-            }
-            swapable_pss = (sharing_proportion * usage.shared_clean) + usage.private_clean;
-        }
-
-        stats[which_heap].pss += usage.pss;
-        stats[which_heap].swappablePss += swapable_pss;
-        stats[which_heap].rss += usage.rss;
-        stats[which_heap].privateDirty += usage.private_dirty;
-        stats[which_heap].sharedDirty += usage.shared_dirty;
-        stats[which_heap].privateClean += usage.private_clean;
-        stats[which_heap].sharedClean += usage.shared_clean;
-        stats[which_heap].swappedOut += usage.swap;
-        stats[which_heap].swappedOutPss += usage.swap_pss;
-        if (which_heap == HEAP_DALVIK || which_heap == HEAP_DALVIK_OTHER ||
-                which_heap == HEAP_DEX || which_heap == HEAP_ART) {
-            stats[sub_heap].pss += usage.pss;
-            stats[sub_heap].swappablePss += swapable_pss;
-            stats[sub_heap].rss += usage.rss;
-            stats[sub_heap].privateDirty += usage.private_dirty;
-            stats[sub_heap].sharedDirty += usage.shared_dirty;
-            stats[sub_heap].privateClean += usage.private_clean;
-            stats[sub_heap].sharedClean += usage.shared_clean;
-            stats[sub_heap].swappedOut += usage.swap;
-            stats[sub_heap].swappedOutPss += usage.swap_pss;
-        }
-        return true;
-    };
-
-    return meminfo::ForEachVmaFromFile(smaps_path, vma_scan);
-}
-
 static jboolean android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
         jint pid, jobject object)
 {
     bool foundSwapPss;
-    stats_t stats[_NUM_HEAP];
+    AndroidHeapStats stats[_NUM_HEAP];
     memset(&stats, 0, sizeof(stats));
 
-    if (!load_maps(pid, stats, &foundSwapPss)) {
+    if (!ExtractAndroidHeapStats(pid, stats, &foundSwapPss)) {
         return JNI_FALSE;
     }
 
@@ -815,6 +581,15 @@
         return false;
     }
 
+    std::string binderState;
+    android::status_t status = android::getBinderTransactions(pid, binderState);
+    if (status == android::OK) {
+        if (!android::base::WriteStringToFd(binderState, fd)) {
+            PLOG(ERROR) << "Failed to dump binder state info for pid: " << pid;
+        }
+    } else {
+        PLOG(ERROR) << "Failed to get binder state info for pid: " << pid << " status: " << status;
+    }
     int res = dump_backtrace_to_file_timeout(pid, dumpType, timeoutSecs, fd);
     if (fdatasync(fd.get()) != 0) {
         PLOG(ERROR) << "Failed flushing trace.";
diff --git a/core/jni/android_os_Trace.cpp b/core/jni/android_os_Trace.cpp
index 4387a4c..21e056d 100644
--- a/core/jni/android_os_Trace.cpp
+++ b/core/jni/android_os_Trace.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <cutils/compiler.h>
+#include <cutils/trace.h>
 #include <jni.h>
 #include <log/log.h>
 #include <nativehelper/JNIHelp.h>
@@ -103,7 +104,9 @@
 }
 
 static void android_os_Trace_nativeSetAppTracingAllowed(JNIEnv*, jclass, jboolean allowed) {
-    // no-op
+    // TODO(b/331916606): this is load-bearing for an app to notice that it is
+    // traced after post-zygote-fork specialisation.
+    atrace_update_tags();
 }
 
 static void android_os_Trace_nativeSetTracingEnabled(JNIEnv*, jclass, jboolean enabled) {
diff --git a/core/jni/android_text_Hyphenator.cpp b/core/jni/android_text_Hyphenator.cpp
index 7c976b7..b6bf617 100644
--- a/core/jni/android_text_Hyphenator.cpp
+++ b/core/jni/android_text_Hyphenator.cpp
@@ -36,43 +36,41 @@
     return SYSTEM_HYPHENATOR_PREFIX + lowerLocale + SYSTEM_HYPHENATOR_SUFFIX;
 }
 
-static std::pair<const uint8_t*, uint32_t> mmapPatternFile(const std::string& locale) {
+static const uint8_t* mmapPatternFile(const std::string& locale) {
     const std::string hyFilePath = buildFileName(locale);
     const int fd = open(hyFilePath.c_str(), O_RDONLY | O_CLOEXEC);
     if (fd == -1) {
-        return std::make_pair(nullptr, 0); // Open failed.
+        return nullptr;  // Open failed.
     }
 
     struct stat st = {};
     if (fstat(fd, &st) == -1) {  // Unlikely to happen.
         close(fd);
-        return std::make_pair(nullptr, 0);
+        return nullptr;
     }
 
     void* ptr = mmap(nullptr, st.st_size, PROT_READ, MAP_SHARED, fd, 0 /* offset */);
     close(fd);
     if (ptr == MAP_FAILED) {
-        return std::make_pair(nullptr, 0);
+        return nullptr;
     }
-    return std::make_pair(reinterpret_cast<const uint8_t*>(ptr), st.st_size);
+    return reinterpret_cast<const uint8_t*>(ptr);
 }
 
 static void addHyphenatorWithoutPatternFile(const std::string& locale, int minPrefix,
         int minSuffix) {
-    minikin::addHyphenator(locale,
-                           minikin::Hyphenator::loadBinary(nullptr, 0, minPrefix, minSuffix,
-                                                           locale));
+    minikin::addHyphenator(locale, minikin::Hyphenator::loadBinary(
+            nullptr, minPrefix, minSuffix, locale));
 }
 
 static void addHyphenator(const std::string& locale, int minPrefix, int minSuffix) {
-    auto [ptr, size] = mmapPatternFile(locale);
+    const uint8_t* ptr = mmapPatternFile(locale);
     if (ptr == nullptr) {
         ALOGE("Unable to find pattern file or unable to map it for %s", locale.c_str());
         return;
     }
-    minikin::addHyphenator(locale,
-                           minikin::Hyphenator::loadBinary(ptr, size, minPrefix, minSuffix,
-                                                           locale));
+    minikin::addHyphenator(locale, minikin::Hyphenator::loadBinary(
+            ptr, minPrefix, minSuffix, locale));
 }
 
 static void addHyphenatorAlias(const std::string& from, const std::string& to) {
diff --git a/core/jni/android_tracing_PerfettoDataSource.cpp b/core/jni/android_tracing_PerfettoDataSource.cpp
index 1eff5ce..25ff853 100644
--- a/core/jni/android_tracing_PerfettoDataSource.cpp
+++ b/core/jni/android_tracing_PerfettoDataSource.cpp
@@ -213,7 +213,7 @@
 
 PerfettoDataSource::~PerfettoDataSource() {
     JNIEnv* env = AndroidRuntime::getJNIEnv();
-    env->DeleteWeakGlobalRef(mJavaDataSource);
+    env->DeleteGlobalRef(mJavaDataSource);
 }
 
 jlong nativeCreate(JNIEnv* env, jclass clazz, jobject javaDataSource, jstring name) {
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index d2d5186..2068bd7 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -88,6 +88,7 @@
     jclass mClass;
     jmethodID mForceGc;
     jmethodID mProxyLimitCallback;
+    jmethodID mProxyWarningCallback;
 
 } gBinderInternalOffsets;
 
@@ -1240,7 +1241,7 @@
     gCollectedAtRefs = gNumLocalRefsCreated + gNumDeathRefsCreated;
 }
 
-static void android_os_BinderInternal_proxyLimitcallback(int uid)
+static void android_os_BinderInternal_proxyLimitCallback(int uid)
 {
     JNIEnv *env = AndroidRuntime::getJNIEnv();
     env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
@@ -1254,6 +1255,20 @@
     }
 }
 
+static void android_os_BinderInternal_proxyWarningCallback(int uid)
+{
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+    env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
+                              gBinderInternalOffsets.mProxyWarningCallback,
+                              uid);
+
+    if (env->ExceptionCheck()) {
+        ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
+        binder_report_exception(env, excep.get(),
+                                "*** Uncaught exception in binderProxyWarningCallbackFromNative");
+    }
+}
+
 static void android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv* env, jobject clazz,
                                                                  jboolean enable)
 {
@@ -1278,9 +1293,10 @@
 }
 
 static void android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv* env, jobject clazz,
-                                                                    jint high, jint low)
+                                                                    jint high, jint low,
+                                                                    jint warning)
 {
-    BpBinder::setBinderProxyCountWatermarks(high, low);
+    BpBinder::setBinderProxyCountWatermarks(high, low, warning);
 }
 
 // ----------------------------------------------------------------------------
@@ -1295,7 +1311,7 @@
     { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled },
     { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts },
     { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount },
-    { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks}
+    { "nSetBinderProxyCountWatermarks", "(III)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks}
 };
 
 const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
@@ -1307,6 +1323,8 @@
     gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
     gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
     gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V");
+    gBinderInternalOffsets.mProxyWarningCallback =
+        GetStaticMethodIDOrDie(env, clazz, "binderProxyWarningCallbackFromNative", "(I)V");
 
     jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray");
     gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass);
@@ -1315,7 +1333,8 @@
     gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put",
                                                    "(II)V");
 
-    BpBinder::setLimitCallback(android_os_BinderInternal_proxyLimitcallback);
+    BpBinder::setBinderProxyCountEventCallback(android_os_BinderInternal_proxyLimitCallback,
+                                               android_os_BinderInternal_proxyWarningCallback);
 
     return RegisterMethodsOrDie(
         env, kBinderInternalPathName,
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index b900fa6..b51f72d 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -11,7 +11,6 @@
 # Frameworks
 ogunwale@google.com
 jjaggi@google.com
-kwekua@google.com
 roosa@google.com
 per-file package_item_info.proto = file:/PACKAGE_MANAGER_OWNERS
 per-file usagestatsservice.proto, usagestatsservice_v2.proto = file:/core/java/android/app/usage/OWNERS
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cfe6f73..f743299 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -7507,16 +7507,6 @@
     <permission android:name="android.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO"
                 android:protectionLevel="signature|privileged|appop" />
 
-    <!-- @SystemApi Required for the privileged assistant apps targeting
-         {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}
-         that receive training data from a sandboxed {@link HotwordDetectionService} or
-         {@link VisualQueryDetectionService}.
-         <p>Protection level: internal|appop
-         @FlaggedApi("android.permission.flags.voice_activation_permission_apis")
-         @hide -->
-    <permission android:name="android.permission.RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA"
-                android:protectionLevel="internal|appop" />
-
     <!-- @SystemApi Allows requesting the framework broadcast the
          {@link Intent#ACTION_DEVICE_CUSTOMIZATION_READY} intent.
          @hide -->
@@ -8120,7 +8110,7 @@
         android:protectionLevel="signature|privileged" />
 
     <!-- @hide @SystemApi
-        @FlaggedApi("com.android.server.notification.flags.redact_otp_notifications_from_untrusted_listeners")
+        @FlaggedApi("android.view.flags.sensitive_content_app_protection_api")
         Allows apps with a NotificationListenerService to receive notifications with sensitive
         information
         <p>Apps with a NotificationListenerService without this permission will not be able
@@ -8168,6 +8158,15 @@
     <permission android:name="android.permission.RESTRICT_DISPLAY_MODES"
         android:protectionLevel="signature" />
 
+    <!-- Allows internal applications to override screen timeout temporarily
+        <p>Protection level: signature
+        <p>Not for use by third-party applications.
+        @FlaggedApi("com.android.server.power.feature.flags.enable_early_screen_timeout_detector")
+        @hide
+    -->
+    <permission android:name="android.permission.SCREEN_TIMEOUT_OVERRIDE"
+                android:protectionLevel="signature" />
+
     <!-- Attribution for Geofencing service. -->
     <attribution android:tag="GeofencingService" android:label="@string/geofencing_service"/>
     <!-- Attribution for Country Detector. -->
diff --git a/core/res/OWNERS b/core/res/OWNERS
index 6924248..4e61ff2 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -43,6 +43,9 @@
 # Device Idle
 per-file res/values/config_device_idle.xml = file:/apex/jobscheduler/OWNERS
 
+# Display Manager
+per-file res/values/config_display.xml = file:/services/core/java/com/android/server/display/OWNERS
+
 # Wear
 per-file res/*-watch/* = file:/WEAR_OWNERS
 
diff --git a/core/res/res/layout/autofill_fill_dialog.xml b/core/res/res/layout/autofill_fill_dialog.xml
index 196af6d..ed9961c 100644
--- a/core/res/res/layout/autofill_fill_dialog.xml
+++ b/core/res/res/layout/autofill_fill_dialog.xml
@@ -72,6 +72,7 @@
         android:layout_marginEnd="24dp"
         android:clipToPadding="false"
         android:drawSelectorOnTop="true"
+        android:contentSensitivity="sensitive"
         android:clickable="true"
         android:divider="@null"
         android:visibility="gone" />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index ed05041..63cd6b9 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Kan nie selnetwerk bereik nie"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Probeer die voorkeurnetwerk verander. Tik om te verander."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Noodoproepe is onbeskikbaar"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Noodoproepe vereis ’n selnetwerk."</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Opletberigte"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Oproepaanstuur"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Noodterugbel-modus"</string>
@@ -358,7 +357,7 @@
     <string name="capability_desc_canTakeScreenshot" msgid="7762297374317934052">"Kan \'n skermkiekie neem."</string>
     <string name="dream_preview_title" msgid="5570751491996100804">"Voorskou, <xliff:g id="DREAM_NAME">%1$s</xliff:g>"</string>
     <string name="permlab_statusBar" msgid="8798267849526214017">"deaktiveer of verander statusbalk"</string>
-    <string name="permdesc_statusBar" msgid="5809162768651019642">"Laat die program toe om die statusbalk te deaktiveer en stelselikone by te voeg of te verwyder."</string>
+    <string name="permdesc_statusBar" msgid="5809162768651019642">"Laat die app toe om die statusbalk te deaktiveer en stelselikone by te voeg of te verwyder."</string>
     <string name="permlab_statusBarService" msgid="2523421018081437981">"wees die statusbalk"</string>
     <string name="permdesc_statusBarService" msgid="6652917399085712557">"Laat die program toe om die statusbalk te wees."</string>
     <string name="permlab_expandStatusBar" msgid="1184232794782141698">"vou statusbalk in of uit"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Vee uit"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Invoermetode"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Teksaksies"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Handskrif word nie in hierdie veld gesteun nie"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Handskrif word nie in wagwoordvelde gesteun nie"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Terug"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Wissel invoermetode"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Bergingspasie word min"</string>
@@ -1932,6 +1929,12 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Bestuur deur <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Aan"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Af"</string>
+    <!-- no translation found for zen_mode_trigger_summary_divider_text (7461583466043698862) -->
+    <skip />
+    <!-- no translation found for zen_mode_trigger_summary_range_symbol_combination (1804900738798069619) -->
+    <skip />
+    <!-- no translation found for zen_mode_trigger_event_calendar_any (2086784607921121803) -->
+    <skip />
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> demp sekere klanke"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Daar is \'n interne probleem met jou toestel en dit sal dalk onstabiel wees totdat jy \'n fabriekterugstelling doen."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Daar is \'n interne probleem met jou toestel. Kontak jou vervaardiger vir besonderhede."</string>
@@ -2031,7 +2034,7 @@
     <string name="pin_specific_target" msgid="7824671240625957415">"Speld <xliff:g id="LABEL">%1$s</xliff:g> vas"</string>
     <string name="unpin_target" msgid="3963318576590204447">"Ontspeld"</string>
     <string name="unpin_specific_target" msgid="3859828252160908146">"Ontspeld <xliff:g id="LABEL">%1$s</xliff:g>"</string>
-    <string name="app_info" msgid="6113278084877079851">"Programinligting"</string>
+    <string name="app_info" msgid="6113278084877079851">"Appinligting"</string>
     <string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
     <string name="demo_starting_message" msgid="6577581216125805905">"Begin tans demonstrasie …"</string>
     <string name="demo_restarting_message" msgid="1160053183701746766">"Stel toestel tans terug …"</string>
@@ -2394,6 +2397,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Toets"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Gemeenskaplik"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Outomaties aan satelliet gekoppel"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Jy kan boodskappe stuur en ontvang sonder ’n selfoon- of wi-fi-netwerk"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Maak Boodskappe oop"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index a127ad7..799a7ab 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"የሞባይል አውታረ መረብን መድረስ አልተቻለም"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ተመራጭ አውታረ መረብን ለመለወጥ ይሞክሩ። ለመለወጥ መታ ያድርጉ።"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"የአደጋ ጊዜ ጥሪ አይገኝም"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"የአደጋ ጥሪዎች የተንቀሳቃሽ ስልክ አውታረ መረብ ያስፈልጋቸዋል"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"ማንቂያዎች"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"ጥሪ ማስተላለፍ"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"የአደጋ ጊዜ ጥሪ ሁነታ"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"ሰርዝ"</string>
     <string name="inputMethod" msgid="1784759500516314751">"ግቤት ስልት"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"የፅሁፍ እርምጃዎች"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"የእጅ ጽሑፍ በዚህ መስክ ውስጥ አይደገፍም"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"የእጅ ጽሑፍ በይለፍ ቃል መስኮች ውስጥ አይደገፍም"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"ተመለስ"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"የግቤት ስልትን ቀይር"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"የማከማቻ ቦታ እያለቀ ነው"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"በ<xliff:g id="APP_NAME">%1$s</xliff:g> የሚተዳደር"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"በርቷል"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ጠፍቷል"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"፣ "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ማንኛውም ቀን መቁጠሪያ"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> አንዳንድ ድምጾችን እየዘጋ ነው"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"መሣሪያዎ ላይ የውስጣዊ ችግር አለ፣ የፋብሪካ ውሂብ ዳግም እስኪያስጀምሩት ድረስ ላይረጋጋ ይችላል።"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"መሣሪያዎ ላይ የውስጣዊ ችግር አለ። ዝርዝሮችን ለማግኘት አምራችዎን ያነጋግሩ።"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"ሙከራ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"የጋራ"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"ከሳተላይት ጋር በራስ-ሰር ተገናኝቷል"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"ያለ ሞባይል ወይም የWi-Fi አውታረ መረብ መልዕክቶችን መላክ እና መቀበል ይችላሉ"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"መልዕክቶች ይክፈቱ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index d67443a..fad2cd6 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -88,8 +88,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"يتعذّر الوصول إلى شبكة الجوّال."</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"حاول تغيير الشبكة المفضلة. انقر لتغييرها."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"لا تتوفر إمكانية الاتصال في حالات الطوارئ."</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"يتطلّب إجراء مكالمات الطوارئ الاتصال بشبكة جوّال"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"التنبيهات"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"إعادة توجيه المكالمة"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"وضع معاودة الاتصال بالطوارئ"</string>
@@ -320,7 +319,7 @@
     <string name="permgroupdesc_contacts" msgid="9163927941244182567">"الوصول إلى جهات اتصالك"</string>
     <string name="permgrouplab_location" msgid="1858277002233964394">"الموقع الجغرافي"</string>
     <string name="permgroupdesc_location" msgid="1995955142118450685">"الوصول إلى موقع هذا الجهاز"</string>
-    <string name="permgrouplab_calendar" msgid="6426860926123033230">"التقويم"</string>
+    <string name="permgrouplab_calendar" msgid="6426860926123033230">"‏تقويم Google"</string>
     <string name="permgroupdesc_calendar" msgid="6762751063361489379">"الوصول إلى تقويمك"</string>
     <string name="permgrouplab_sms" msgid="795737735126084874">"SMS"</string>
     <string name="permgroupdesc_sms" msgid="5726462398070064542">"‏إرسال رسائل قصيرة SMS وعرضها"</string>
@@ -1188,10 +1187,8 @@
     <string name="deleteText" msgid="4200807474529938112">"حذف"</string>
     <string name="inputMethod" msgid="1784759500516314751">"طريقة الإرسال"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"إجراءات النص"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"الكتابة بخط اليد غير متاحة في هذا الحقل"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"الكتابة بخط اليد غير متاحة في حقول كلمات المرور"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"رجوع"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"تبديل أسلوب الإدخال"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"مساحة التخزين منخفضة"</string>
@@ -1290,7 +1287,7 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"بدء التطبيقات."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"جارٍ إعادة التشغيل."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"ضغطت على زر التشغيل، يؤدي هذا عادةً إلى إيقاف الشاشة.\n\nجرِّب النقر بخفة أثناء إعداد بصمتك."</string>
-    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"لإيقاف عملية الإعداد، أغلِق الشاشة."</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"لإيقاف عملية الإعداد، أغلِق الشاشة"</string>
     <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"إيقاف"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"هل تريد مواصلة تأكيد بصمة إصبعك؟"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"ضغطت على زر التشغيل، يؤدي هذا عادةً إلى إيقاف الشاشة.\n\nجرِّب النقر بخفة لتأكيد بصمة إصبعك."</string>
@@ -1936,6 +1933,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"تحت إدارة \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"مفعَّل"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"غير مفعَّل"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"، "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"من <xliff:g id="START">%1$s</xliff:g> إلى <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"أي تقويم"</string>
     <string name="muted_by" msgid="91464083490094950">"يعمل <xliff:g id="THIRD_PARTY">%1$s</xliff:g> على كتم بعض الأصوات."</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"حدثت مشكلة داخلية في جهازك، وقد لا يستقر وضعه حتى إجراء إعادة الضبط على الإعدادات الأصلية."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"حدثت مشكلة داخلية في جهازك. يمكنك الاتصال بالمصنِّع للحصول على تفاصيل."</string>
@@ -1997,7 +1997,7 @@
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"الطوارئ"</string>
     <string name="set_up_screen_lock_title" msgid="8346083801616474030">"ضبط قفل شاشة"</string>
     <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"ضبط قفل الشاشة"</string>
-    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"لاستخدام مساحتك الخاصة، يجب ضبط قفل شاشة على هذا الجهاز."</string>
+    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"لاستخدام مساحتك الخاصة، يجب ضبط قفل شاشة على هذا الجهاز"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"التطبيق غير متاح"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> غير متاح الآن."</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"تطبيق <xliff:g id="ACTIVITY">%1$s</xliff:g> غير متاح"</string>
@@ -2398,6 +2398,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"ملف شخصي تجريبي"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"ملف شخصي مشترك"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"تم الاتصال تلقائيًا بالقمر الصناعي"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"‏يمكنك إرسال الرسائل واستلامها بدون شبكة الجوّال أو شبكة Wi-Fi."</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"فتح تطبيق \"الرسائل\""</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 6117086..8b3f832 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ম’বাইল নেটৱৰ্কৰ লগত সংযোগ কৰিব পৰা নাই"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"পচন্দৰ নেটৱৰ্ক সলনি কৰি চেষ্টা কৰি চাওক। সলনি কৰিবলৈ টিপক।"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"জৰুৰীকালীন কল কৰাৰ সুবিধা উপলব্ধ নহয়"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"জৰুৰীকালীন কল কৰিবলৈ ম’বাইল নেটৱৰ্কৰ প্ৰয়োজন"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"সতৰ্কবাণীসমূহ"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"কল ফৰৱাৰ্ডিং"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"জৰুৰীকালীন ক\'লবেক ম\'ড"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"মচক"</string>
     <string name="inputMethod" msgid="1784759500516314751">"ইনপুট পদ্ধতি"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"পাঠ বিষয়ক কাৰ্য"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"এই ক্ষেত্ৰত হস্তলিপি সমৰ্থিত নহয়"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"পাছৱৰ্ড ক্ষেত্ৰসমূহত হস্তলিপি সমৰ্থিত নহয়"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"উভতি যাওক"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"ইনপুটৰ পদ্ধতি সলনি কৰক"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"ষ্ট’ৰেজৰ খালী ঠাই শেষ হৈ আছে"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ পৰিচালনা কৰা"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"অন আছে"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"অফ আছে"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"যিকোনো কেলেণ্ডাৰ"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>এ কিছুমান ধ্বনি মিউট কৰি আছে"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"আপোনাৰ ডিভাইচত এটা আভ্যন্তৰীণ সমস্যা আছে আৰু আপুনি ফেক্টৰী ডেটা ৰিছেট নকৰালৈকে ই সুস্থিৰভাৱে কাম নকৰিব পাৰে।"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"আপোনাৰ ডিভাইচত এটা আভ্যন্তৰীণ সমস্যা আছে। সবিশেষ জানিবৰ বাবে আপোনাৰ ডিভাইচ নির্মাতাৰ সৈতে যোগাযোগ কৰক।"</string>
@@ -1993,7 +1993,7 @@
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"জৰুৰীকালীন"</string>
     <string name="set_up_screen_lock_title" msgid="8346083801616474030">"এটা স্ক্ৰীন লক ছেট কৰক"</string>
     <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"স্ক্ৰীন লক ছেট কৰা"</string>
-    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"আপোনাৰ প্ৰাইভেট স্পেচ ব্যৱহাৰ কৰিবলৈ এই ডিভাইচটোত স্ক্ৰীন লক ছেট কৰক"</string>
+    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"আপোনাৰ প্ৰাইভেট স্পে\'চ ব্যৱহাৰ কৰিবলৈ এই ডিভাইচটোত স্ক্ৰীন লক ছেট কৰক"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"এপ্‌টো উপলব্ধ নহয়"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"এই মুহূৰ্তত <xliff:g id="APP_NAME">%1$s</xliff:g> উপলব্ধ নহয়।"</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> উপলব্ধ নহয়"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"পৰীক্ষা"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"শ্বেয়াৰ কৰা"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"উপগ্ৰহৰ সৈতে স্বয়ংক্ৰিয়ভাৱে সংযুক্ত হৈছে"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"আপুনি ম’বাইল বা ৱাই-ফাই নেটৱৰ্কৰ জৰিয়তে পাঠ বাৰ্তা পঠিয়াব বা লাভ কৰিব পাৰে"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages খোলক"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index a186815..c0b886b 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobil şəbəkəyə daxil olmaq mümkün deyil"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tərcih edilən şəbəkəni dəyişin. Dəyişmək üçün klikləyin."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Təcili zəng əlçatan deyil"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Təcili zənglər üçün mobil şəbəkə tələb olunur"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Siqnallar"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Zəng yönləndirmə"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Təcili geriyə zəng rejimi"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Sil"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Daxiletmə metodu"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Mətn əməliyyatları"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Bu xanada əlyazma dəstəklənmir"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Parol sahələrində əlyazma dəstəklənmir"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Geriyə"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Daxiletmə metodunu dəyişdirin"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Yaddaş yeri bitir"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> idarə edir"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Aktiv"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Deaktiv"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"İstənilən təqvim"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> bəzi səsləri səssiz rejimə salır"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Cihazınızın daxili problemi var və istehsalçı sıfırlanması olmayana qədər qeyri-stabil ola bilər."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Cihazınızın daxili problemi var. Əlavə məlumat üçün istehsalçı ilə əlaqə saxlayın."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Kommunal"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Peykə avtomatik qoşulub"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil və ya Wi-Fi şəbəkəsi olmadan mesaj göndərə və qəbul edə bilərsiniz"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajı açın"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 76554fb..a275cab 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Povezivanje sa mobilnom mrežom nije uspelo"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Probajte da promenite željenu mrežu. Dodirnite da biste promenili."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hitni pozivi nisu dostupni"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Hitni pozivi zahtevaju mobilnu mrežu"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozorenja"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Preusmeravanje poziva"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Režim za hitan povratni poziv"</string>
@@ -616,7 +615,7 @@
     <string name="permlab_disableKeyguard" msgid="3605253559020928505">"onemogućavanje zaključavanja ekrana"</string>
     <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"Dozvoljava aplikaciji da onemogući zaključavanje tastature i sve povezane bezbednosne mere sa lozinkama. Na primer, telefon onemogućava zaključavanje tastature pri prijemu dolaznog telefonskog poziva, a zatim ga ponovo omogućava po završetku poziva."</string>
     <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"traženje složenosti zaključavanja ekrana"</string>
-    <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Dozvoljava aplikaciji da sazna nivo složenosti zaključavanja ekrana (visoka, srednja, niska ili nijedna), što ukazuje na mogući opseg trajanja i tip zaključavanja ekrana. Aplikacija može i da predlaže korisnicima da ažuriraju zaključavanje ekrana na određeni nivo, ali korisnici slobodno mogu da zanemare to i da idu na druge stranice. Imajte na umu da se podaci za zaključavanje ekrana ne čuvaju kao običan tekst, pa aplikacija ne zna tačnu lozinku."</string>
+    <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Dozvoljava aplikaciji da sazna nivo složenosti zaključavanja ekrana (visoka, srednja, niska ili nijedna), što ukazuje na mogući opseg trajanja i tip zaključavanja ekrana. Aplikacija može i da predlaže korisnicima da ažuriraju otključavanje ekrana na određeni nivo, ali korisnici slobodno mogu da zanemare to i da idu na druge stranice. Imajte na umu da se podaci za otključavanje ekrana ne čuvaju kao običan tekst, pa aplikacija ne zna tačnu lozinku."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"prikazivanje obaveštenja"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Dozvoljava aplikaciji da prikazuje obaveštenja"</string>
     <string name="permlab_turnScreenOn" msgid="219344053664171492">"uključivanje ekrana"</string>
@@ -636,10 +635,10 @@
     <string name="permlab_mediaLocation" msgid="7368098373378598066">"čitanje lokacija iz medijske kolekcije"</string>
     <string name="permdesc_mediaLocation" msgid="597912899423578138">"Dozvoljava aplikaciji da čita lokacije iz medijske kolekcije."</string>
     <string name="biometric_app_setting_name" msgid="3339209978734534457">"Koristite biometriju"</string>
-    <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Koristite biometriju ili zaključavanje ekrana"</string>
+    <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Koristite biometriju ili otključavanje ekrana"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Potvrdite svoj identitet"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Koristite biometrijski podatak da biste nastavili"</string>
-    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Koristite biometrijski podatak ili zaključavanje ekrana da biste nastavili"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Koristite biometrijski podatak ili otključavanje ekrana da biste nastavili"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometrijski hardver nije dostupan"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Potvrda identiteta je otkazana"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Nije prepoznato"</string>
@@ -647,8 +646,8 @@
     <string name="biometric_error_canceled" msgid="8266582404844179778">"Potvrda identiteta je otkazana"</string>
     <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Niste podesili ni PIN, ni šablon, ni lozinku"</string>
     <string name="biometric_error_generic" msgid="6784371929985434439">"Greška pri potvrdi identiteta"</string>
-    <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Koristite zaključavanje ekrana"</string>
-    <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Upotrebite zaključavanje ekrana da biste nastavili"</string>
+    <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Koristite otključavanje ekrana"</string>
+    <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Upotrebite otključavanje ekrana da biste nastavili"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Čvrsto pritisnite senzor"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2410176550915730974">"Otisak prsta nije prepoznat. Probajte ponovo."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Obrišite senzor za otisak prsta i probajte ponovo"</string>
@@ -673,8 +672,8 @@
     <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Vreme za podešavanje otiska prsta je isteklo. Probajte ponovo."</string>
     <string name="fingerprint_error_canceled" msgid="5541771463159727513">"Radnja sa otiskom prsta je otkazana"</string>
     <string name="fingerprint_error_user_canceled" msgid="2017941773466506863">"Korisnik je otkazao radnju sa otiskom prsta"</string>
-    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Previše pokušaja. Koristite zaključavanje ekrana umesto toga."</string>
-    <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Previše pokušaja. Koristite zaključavanje ekrana umesto toga."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Previše pokušaja. Koristite otključavanje ekrana umesto toga."</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Previše pokušaja. Koristite otključavanje ekrana umesto toga."</string>
     <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Obrađivanje otiska prsta nije uspelo. Probajte ponovo."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="3144806556204061862">"Nije registrovan nijedan otisak prsta"</string>
     <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Ovaj uređaj nema senzor za otisak prsta"</string>
@@ -683,9 +682,9 @@
     <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Pritisnuto je dugme za uključivanje"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Prst <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Koristite otisak prsta"</string>
-    <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristite otisak prsta ili zaključavanje ekrana"</string>
+    <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Koristite otisak prsta ili otključavanje ekrana"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Nastavite pomoću otiska prsta"</string>
-    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Koristite otisak prsta ili zaključavanje ekrana da biste nastavili"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Koristite otisak prsta ili otključavanje ekrana da biste nastavili"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"Došlo je do problema. Probajte ponovo."</string>
@@ -737,16 +736,16 @@
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Korisnik je otkazao otključavanje licem"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Previše pokušaja. Probajte ponovo kasnije."</string>
     <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Previše pokušaja. Otključavanje licem nije dostupno."</string>
-    <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Previše pokušaja. Koristite zaključavanje ekrana za to."</string>
+    <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Previše pokušaja. Koristite otključavanje ekrana za to."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Provera lica nije uspela. Probajte ponovo."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Niste podesili otključavanje licem"</string>
     <string name="face_error_hw_not_present" msgid="7940978724978763011">"Otključavanje licem nije podržano na ovom uređaju"</string>
     <string name="face_error_security_update_required" msgid="5076017208528750161">"Senzor je privremeno onemogućen."</string>
     <string name="face_name_template" msgid="3877037340223318119">"Lice <xliff:g id="FACEID">%d</xliff:g>"</string>
     <string name="face_app_setting_name" msgid="5854024256907828015">"Koristite otključavanje licem"</string>
-    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Koristite zaključavanje licem ili zaključavanje ekrana"</string>
+    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Koristite zaključavanje licem ili otključavanje ekrana"</string>
     <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Potvrdite identitet licem da biste nastavili"</string>
-    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Koristite lice ili zaključavanje ekrana da biste nastavili"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Koristite lice ili otključavanje ekrana da biste nastavili"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_error_vendor_unknown" msgid="7387005932083302070">"Došlo je do problema. Probajte ponovo."</string>
@@ -828,7 +827,7 @@
     <string name="permlab_writeVerificationStateE2eeContactKeys" msgid="3990742344778360457">"Ažuriranje statusa verifikacije ključeva za šifrovanje kontakata s kraja na kraj u vlasništvu drugih aplikacija"</string>
     <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"Dozvoljava aplikaciji da ažurira statuse verifikacije ključeva za šifrovanje kontakata s kraja na kraj (E2EE) u vlasništvu drugih aplikacija"</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Podešavanje pravila za lozinku"</string>
-    <string name="policydesc_limitPassword" msgid="4105491021115793793">"Kontroliše dužinu i znakove dozvoljene u lozinkama i PIN-ovima za zaključavanje ekrana."</string>
+    <string name="policydesc_limitPassword" msgid="4105491021115793793">"Kontroliše dužinu i znakove dozvoljene u lozinkama i PIN-ovima za otključavanje ekrana."</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"Nadzor pokušaja otključavanja ekrana"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Prati broj netačno unetih lozinki prilikom otključavanja ekrana i zaključava tablet ili briše podatke sa tableta ako je netačna lozinka uneta previše puta."</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava Android TV uređaj ili briše sve podatke sa Android TV uređaja ako se unese previše netačnih lozinki."</string>
@@ -839,7 +838,7 @@
     <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava sistem za info-zabavu ili briše sve podatke ovog profila ako se unese previše netačnih lozinki."</string>
     <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Nadgleda broj netačnih lozinki unetih pri otključavanju ekrana i zaključava telefon ili briše sve podatke ovog korisnika ako se unese previše netačnih lozinki."</string>
     <string name="policylab_resetPassword" msgid="214556238645096520">"Promena zaključavanja ekrana"</string>
-    <string name="policydesc_resetPassword" msgid="4626419138439341851">"Menja zaključavanje ekrana."</string>
+    <string name="policydesc_resetPassword" msgid="4626419138439341851">"Menja otključavanje ekrana."</string>
     <string name="policylab_forceLock" msgid="7360335502968476434">"Zaključavanje ekrana"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"Kontrola načina i vremena zaključavanja ekrana."</string>
     <string name="policylab_wipeData" msgid="1359485247727537311">"Brisanje svih podataka"</string>
@@ -856,7 +855,7 @@
     <string name="policylab_setGlobalProxy" msgid="215332221188670221">"Podesite globalni proksi server uređaja"</string>
     <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"Podešava globalni proksi uređaja koji će se koristiti dok su smernice omogućene. Samo vlasnik uređaja može da podesi globalni proksi."</string>
     <string name="policylab_expirePassword" msgid="6015404400532459169">"Podesi istek. lozin. za zaklj. ekr."</string>
-    <string name="policydesc_expirePassword" msgid="9136524319325960675">"Menja koliko često lozinka, PIN ili šablon za zaključavanje ekrana mora da se menja."</string>
+    <string name="policydesc_expirePassword" msgid="9136524319325960675">"Menja koliko često lozinka, PIN ili šablon za otključavanje ekrana mora da se menja."</string>
     <string name="policylab_encryptedStorage" msgid="9012936958126670110">"Podešavanje šifrovanja skladišta"</string>
     <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"Zahteva da sačuvani podaci aplikacije budu šifrovani."</string>
     <string name="policylab_disableCamera" msgid="5749486347810162018">"Onemogućavanje kamera"</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Izbriši"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Metod unosa"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Radnje u vezi sa tekstom"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Pisanje rukom nije podržano u ovom polju"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Pisanje rukom nije podržano u poljima za lozinke"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Nazad"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Promenite metod unosa"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Memorijski prostor je na izmaku"</string>
@@ -1933,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Upravlja: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Uključeno"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Isključeno"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bilo koji kalendar"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> isključuje neke zvuke"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Došlo je do internog problema u vezi sa uređajem i možda će biti nestabilan dok ne obavite resetovanje na fabrička podešavanja."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Došlo je do internog problema u vezi sa uređajem. Potražite detalje od proizvođača."</string>
@@ -1992,9 +1992,9 @@
     <string name="work_mode_off_title" msgid="6367463960165135829">"Uključiti poslovne aplikacije?"</string>
     <string name="work_mode_turn_on" msgid="5316648862401307800">"Ponovo aktiviraj"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Hitan slučaj"</string>
-    <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Podesite zaključavanje ekrana"</string>
-    <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Podesi zaključavanje ekrana"</string>
-    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Da biste koristili privatni prostor, podesite zaključavanje ekrana na ovom uređaju"</string>
+    <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Podesite otključavanje ekrana"</string>
+    <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Podesi otključavanje ekrana"</string>
+    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Da biste koristili privatni prostor, podesite otključavanje ekrana na ovom uređaju"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – nije dostupno"</string>
@@ -2395,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Zajedničko"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automatski povezano sa satelitom"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Možete da šaljete i primate poruke bez mobilne ili WiFi mreže"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvori Messages"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index c7d4224..c0d930f 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -86,8 +86,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Сетка мабільнай сувязі недаступная"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Націсніце, каб выбраць іншую сетку."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Экстранныя выклікі недаступныя"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Для экстранных выклікаў патрабуецца мабільная сетка"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Абвесткі"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Пераадрасацыя выкліку"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Рэжым экстранных зваротных выклікаў"</string>
@@ -1186,10 +1185,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Выдалiць"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Метад уводу"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Дзеянні з тэкстам"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Гэта поле не падтрымлівае рукапісны ўвод"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Палі для ўказання пароля не падтрымліваюць рукапісны ўвод"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Назад"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Пераключэнне рэжыму ўводу"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Месца для захавання на зыходзе"</string>
@@ -1934,6 +1931,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Пад кіраваннем праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Уключана"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Выключана"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Любы каляндар"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> выключае некаторыя гукі"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"На вашай прыладзе ўзнікла ўнутраная праблема, і яна можа працаваць нестабільна, пакуль вы не зробіце скід да заводскіх налад."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"На вашай прыладзе ўзнікла ўнутраная праблема. Для атрымання дадатковай інфармацыі звярніцеся да вытворцы."</string>
@@ -2396,6 +2396,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Тэставы"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Супольны"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Аўтаматычна падключана да сістэм спадарожнікавай сувязі"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Вы можаце адпраўляць і атрымліваць паведамленні без доступу да мабільнай сеткі або Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Адкрыць Паведамленні"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index d5b59a8..5c793e5 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Не може да се установи връзка с мобилната мрежа"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Изберете друга предпочитана мрежа. Докоснете за промяна."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Няма достъп до спешните обаждания"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"За спешните обаждания се изисква мобилна мрежа"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Сигнали"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Пренасочване на обаждания"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Режим на обратно обаждане при спешност"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Изтриване"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Метод на въвеждане"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Действия с текста"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"В това поле не се поддържа ръкописно въвеждане"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"В полета за парола не се поддържа ръкописно въвеждане"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Назад"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Превключване на метода на въвеждане"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Мястото в хранилището е на изчерпване"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Управлява се от <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Вкл."</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Изкл."</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Всички календари"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> заглушава някои звуци"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Възникна вътрешен проблем с устройството ви. То може да е нестабилно, докато не възстановите фабричните настройки."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Възникна вътрешен проблем с устройството ви. За подробности се свържете с производителя."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Тестване"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Общи"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Автоматично установена връзка със сателит"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Можете да изпращате и получавате съобщения без мобилна или Wi-Fi мрежа"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Отваряне на Messages"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index ef02111..8946607 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"মোবাইল নেটওয়ার্কে কানেক্ট করা যাচ্ছে না"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"পছন্দের নেটওয়ার্ক পরিবর্তন করে দেখুন। অন্য নেটওয়ার্ক বেছে নিতে ট্যাপ করুন।"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"জরুরি কল করা যাবে না"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"জরুরি কলের জন্য মোবাইল নেটওয়ার্ক থাকতে হবে"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"সতর্কতা"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"কল ফরওয়ার্ড করা"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"জরুরি কলব্যাক মোড"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"মুছুন"</string>
     <string name="inputMethod" msgid="1784759500516314751">"ইনপুট পদ্ধতি"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"পাঠ্য ক্রিয়াগুলি"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"এই ফিল্ডে হাতের লেখা কাজ করে না"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"পাসওয়ার্ডের ফিল্ডে হাতের লেখা কাজ করে না"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"ফিরে যান"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"ইনপুট পদ্ধতি পাল্টান"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"স্টোরেজ পূর্ণ হতে চলেছে"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> ম্যানেজ করে"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"চালু আছে"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"বন্ধ আছে"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"যেকোনও ক্যালেন্ডার"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> কিছু সাউন্ডকে মিউট করে দিচ্ছে"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"আপনার ডিভাইসে একটি অভ্যন্তরীন সমস্যা হয়েছে, এবং আপনি যতক্ষণ না পর্যন্ত এটিকে ফ্যাক্টরি ডেটা রিসেট করছেন ততক্ষণ এটি ঠিকভাবে কাজ নাও করতে পারে৷"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"আপনার ডিভাইসে একটি অভ্যন্তরীন সমস্যা হয়েছে৷ বিস্তারিত জানার জন্য প্রস্তুতকারকের সাথে যোগাযোগ করুন৷"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"পরীক্ষা"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"কমিউনাল"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"স্যাটেলাইটের সাথে অটোমেটিক কানেক্ট করা হয়েছে"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"আপনি কোনও মেবাইল বা ওয়াই-ফাই নেটওয়ার্ক ছাড়াই মেসেজ পাঠাতে ও পেতে পারবেন"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages খুলুন"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 9f0a387..2d08a22 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nije moguće dosegnuti mobilnu mrežu"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Pokušajte promijeniti preferiranu mrežu. Dodirnite za promjenu."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hitni pozivi su nedostupni"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Za hitne pozive potrebna je mreža"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozorenja"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Prosljeđivanje poziva"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Način rada za hitni povratni poziv"</string>
@@ -829,7 +828,7 @@
     <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"Dozvoljava aplikaciji da ažurira stanja potvrđivanja E2EE kontaktnih ključeva u vlasništvu drugih aplikacija"</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Postavljanje pravila za lozinke"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Kontrolira dužinu i znakove koji su dozvoljeni u lozinkama za zaključavanje ekrana i PIN-ovima."</string>
-    <string name="policylab_watchLogin" msgid="7599669460083719504">"Prati pokušaje otključavanja ekrana"</string>
+    <string name="policylab_watchLogin" msgid="7599669460083719504">"Praćenje pokušaja otključavanja ekrana"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Prati broj pogrešno unijetih lozinki prilikom otključavanja ekrana i zaključava tablet ili briše sve podatke s njega ukoliko se previše puta unese pogrešna lozinka."</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Praćenje broja unosa netačnih lozinki pri otključavanju ekrana i zaključavanje Android TV uređaja ili brisanje svih podataka Android TV uređaja u slučaju prevelikog broja unosa netačnih lozinki."</string>
     <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Prati koliko puta je lozinka neispravno unijeta prilikom otključavanja ekrana i zaključava informativno-zabavni sistem ili briše sve podatke informativno-zabavnog sistema ako se lozinka neispravno unese previše puta."</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Izbriši"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Način unosa"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Akcije za tekst"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Rukopis nije podržan u ovom polju"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Rukopis nije podržan u poljima za lozinku"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Nazad"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Promjena načina unosa"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Ponestaje prostora za pohranu"</string>
@@ -1933,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Upravlja <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Uključeno"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Isključeno"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bilo koji kalendar"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> isključuje neke zvukove"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Postoji problem u vašem uređaju i može biti nestabilan dok ga ne vratite na fabričke postavke."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Postoji problem u vašem uređaju. Za više informacija obratite se proizvođaču."</string>
@@ -1994,7 +1994,7 @@
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Hitan slučaj"</string>
     <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Postavite zaključavanje ekrana"</string>
     <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Postavite zaključavanje ekrana"</string>
-    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Za upotrebu privatn. prostora postavite zaklj. ekr. na uređ."</string>
+    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Za upotrebu privatnog prostora postavite zaključavanje ekrana na uređaju"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutno nije dostupna."</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"Nedostupno: <xliff:g id="ACTIVITY">%1$s</xliff:g>"</string>
@@ -2395,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Testno"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Opće"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automatski je povezano sa satelitom"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Možete slati i primati poruke bez mobilne ili WiFi mreže"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvorite Messages"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 7aad1a7..263d129 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"No es pot accedir a la xarxa mòbil"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prova de canviar de xarxa preferent. Toca per canviar-la."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Les trucades d\'emergència no estan disponibles"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Per poder fer trucades d\'emergència, cal tenir connexió a una xarxa mòbil"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertes"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Desviació de trucades"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Mode de devolució de trucada d\'emergència"</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Suprimeix"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Mètode d\'introducció de text"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Accions de text"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"L\'escriptura a mà no s\'admet en aquest camp"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"L\'escriptura a mà no s\'admet als camps de contrasenya"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Enrere"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Canvia el mètode d\'introducció de text"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"L\'espai d\'emmagatzematge s\'està esgotant"</string>
@@ -1933,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Gestionat per <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activat"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desactivat"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualsevol calendari"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> està silenciant alguns sons"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"S\'ha produït un error intern al dispositiu i és possible que funcioni de manera inestable fins que restableixis les dades de fàbrica."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"S\'ha produït un error intern al dispositiu. Contacta amb el fabricant del dispositiu per obtenir més informació."</string>
@@ -1994,7 +1994,7 @@
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergència"</string>
     <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Defineix un bloqueig de pantalla"</string>
     <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Defineix un bloqueig de pantalla"</string>
-    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Per utilitzar l\'espai privat, defineix un bloq. de pantalla"</string>
+    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Per utilitzar l\'espai privat, defineix un bloqueig de pantalla en aquest dispositiu"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"L\'aplicació no està disponible"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"Ara mateix, <xliff:g id="APP_NAME">%1$s</xliff:g> no està disponible."</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> no està disponible"</string>
@@ -2395,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Prova"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Compartit"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"S\'ha connectat automàticament a un satèl·lit"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Pots enviar i rebre missatges sense una xarxa mòbil o Wi‑Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Obre Missatges"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index eba1796..a8ad543 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -86,8 +86,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobilní síť není dostupná"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Zkuste změnit preferovanou síť. Změníte ji klepnutím."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Tísňová volání jsou nedostupná"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Tísňová volání vyžadují mobilní síť"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozornění"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Přesměrování hovorů"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Režim tísňového zpětného volání"</string>
@@ -1186,10 +1185,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Smazat"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Metoda zadávání dat"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Operace s textem"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"V tomto poli není psaní rukou podporováno"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"V polích pro hesla není psaní rukou podporováno"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Zpět"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Přepnout metodu zadávání"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"V úložišti je málo místa"</string>
@@ -1934,6 +1931,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Spravováno aplikací <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Zapnuto"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Vypnuto"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"V libovolném kalendáři"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> vypíná určité zvuky"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"V zařízení došlo k internímu problému. Dokud neprovedete obnovení továrních dat, může být nestabilní."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"V zařízení došlo k internímu problému. Další informace vám sdělí výrobce."</string>
@@ -1993,7 +1993,7 @@
     <string name="work_mode_off_title" msgid="6367463960165135829">"Zrušit pozastavení pracovních aplikací?"</string>
     <string name="work_mode_turn_on" msgid="5316648862401307800">"Zrušit pozastavení"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Stav nouze"</string>
-    <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Nastavení zámku obrazovky"</string>
+    <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Nastavte si zámek obrazovky"</string>
     <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Nastavit zámek obrazovky"</string>
     <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Pokud chcete používat soukromý prostor, nastavte na tomto zařízení zámek obrazovky"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Aplikace není k dispozici"</string>
@@ -2396,6 +2396,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Komunální"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automaticky připojeno k satelitu"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Zprávy můžete odesílat a přijímat bez mobilní sítě nebo sítě Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otevřít Zprávy"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index d0dca41..59be3dd 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Der er ingen forbindelse til mobilnetværket"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prøv at skifte dit foretrukne netværk. Tryk for skifte."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Det er ikke muligt at foretage nødopkald"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Nødopkald kræver adgang til et mobilnetværk"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Underretninger"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Viderestilling af opkald"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Nødtilbagekaldstilstand"</string>
@@ -828,7 +827,7 @@
     <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"Giver appen tilladelse til at opdatere tilstandene for verificering E2EE-kontaktnøgler, som ejes af andre apps"</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Angiv regler for adgangskoder"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Tjek længden samt tilladte tegn i adgangskoder og pinkoder til skærmlåsen."</string>
-    <string name="policylab_watchLogin" msgid="7599669460083719504">"Overvåg forsøg på oplåsning af skærm"</string>
+    <string name="policylab_watchLogin" msgid="7599669460083719504">"Overvåge forsøg på oplåsning af skærm"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Overvåg antallet af forkert indtastede adgangskoder, når du låser skærmen op, og lås din tablet, eller slet alle data i den, hvis der er indtastet for mange forkerte adgangskoder."</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Registrer antallet af forkerte adgangskoder, der angives ved oplåsning af skærmen, og lås din Android TV-enhed, eller ryd alle dataene på din Android TV-enhed, hvis adgangskoden angives forkert for mange gange."</string>
     <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Registrer antallet af forkert indtastede adgangskoder, når du låser skærmen op, og lås infotainmentsystemet, eller slet alle data i infotainmentsystemet, hvis der er indtastet for mange forkerte adgangskoder."</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Slet"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Inputmetode"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Teksthandlinger"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Håndskrift understøttes ikke for dette felt"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Håndskrift understøttes ikke for adgangskodefelter"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Tilbage"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Skift indtastningsmetode"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Der er snart ikke mere lagerplads"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Administreres af <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Til"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Fra"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Alle kalendere"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> slår nogle lyde fra"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Der er et internt problem med enheden, og den vil muligvis være ustabil, indtil du gendanner fabriksdataene."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Der er et internt problem med enheden. Kontakt producenten for at få yderligere oplysninger."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Fælles"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Der blev automatisk oprettet forbindelse til satellit"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kan sende og modtage beskeder uden et mobil- eller Wi-Fi-netværk"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Åbn Beskeder"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index fea2777..b4882fe 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobilfunknetz nicht erreichbar"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Versuche, das bevorzugte Netzwerk zu ändern. Tippe, um ein anderes auszuwählen."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Notrufe nicht möglich"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Für Notrufe ist ein Mobilfunknetz erforderlich"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Warnmeldungen"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Anrufweiterleitung"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Notfallrückrufmodus"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Löschen"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Eingabemethode"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Textaktionen"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Handschrift wird in diesem Feld nicht unterstützt"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Handschrift wird in Passwortfeldern nicht unterstützt"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Zurück"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Eingabemethode wechseln"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Der Speicherplatz wird knapp"</string>
@@ -1932,6 +1929,12 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Verwaltet von <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"An"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Aus"</string>
+    <!-- no translation found for zen_mode_trigger_summary_divider_text (7461583466043698862) -->
+    <skip />
+    <!-- no translation found for zen_mode_trigger_summary_range_symbol_combination (1804900738798069619) -->
+    <skip />
+    <!-- no translation found for zen_mode_trigger_event_calendar_any (2086784607921121803) -->
+    <skip />
     <string name="muted_by" msgid="91464083490094950">"Einige Töne werden von <xliff:g id="THIRD_PARTY">%1$s</xliff:g> stummgeschaltet"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Es liegt ein internes Problem mit deinem Gerät vor. Möglicherweise verhält es sich instabil, bis du es auf die Werkseinstellungen zurücksetzt."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Es liegt ein internes Problem mit deinem Gerät vor. Bitte wende dich diesbezüglich an den Hersteller."</string>
@@ -2136,7 +2139,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Ausschalten"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Weitere Informationen"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Die adaptiven Benachrichtigungen wurden in Android 12 durch die Funktion „Erweiterte Benachrichtigungen“ ersetzt. Diese Funktion zeigt Vorschläge für Aktionen und Antworten an und sortiert Benachrichtigungen.\n\nDie Funktion hat Zugriff auf alle Benachrichtigungen, darunter auch personenbezogene Daten wie Kontaktnamen und Nachrichten. Außerdem kann sie auf Benachrichtigungen antworten oder diese schließen und so beispielsweise Anrufe entgegennehmen oder „Bitte nicht stören“ steuern."</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Die adaptiven Benachrichtigungen wurden in Android 12 durch die Funktion „Erweiterte Benachrichtigungen“ ersetzt. Diese Funktion zeigt Vorschläge für Aktionen und Antworten an und sortiert Benachrichtigungen.\n\nDie Funktion hat Zugriff auf alle Benachrichtigungen, darunter auch personenbezogene Daten wie Namen von Kontakten und Nachrichten. Außerdem kann sie auf Benachrichtigungen antworten oder diese schließen und so unter anderem Anrufe entgegennehmen oder „Bitte nicht stören“ steuern."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Infomitteilung zum Ablaufmodus"</string>
     <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Energiesparmodus aktiviert"</string>
     <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Reduzierung der Akkunutzung, um die Akkulaufzeit zu verlängern"</string>
@@ -2394,6 +2397,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Gemeinsam genutzt"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automatisch mit Satellit verbunden"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kannst Nachrichten ohne Mobilfunknetz oder WLAN senden und empfangen"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages öffnen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index dec720f..1b88a6a 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Δεν είναι δυνατή η σύνδεση στο δίκτυο κινητής τηλεφωνίας"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Δοκιμάστε να αλλάξετε το προτιμώμενο δίκτυο. Πατήστε για αλλαγή."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Οι κλήσεις έκτακτης ανάγκης δεν είναι διαθέσιμες"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Για τις κλήσεις έκτακτης ανάγκης απαιτείται δίκτυο κινητής τηλεφωνίας"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Ειδοποιήσεις"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Προώθηση κλήσης"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Λειτουργία επιστροφής κλήσης έκτακτης ανάγκης"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Διαγραφή"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Μέθοδος εισόδου"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Ενέργειες κειμένου"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Η γραφή δεν υποστηρίζεται σε αυτό το πεδίο"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Η γραφή δεν υποστηρίζεται στα πεδία κωδικού πρόσβασης"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Πίσω"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Εναλλαγή μεθόδου εισαγωγής"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Ο αποθηκευτικός χώρος εξαντλείται"</string>
@@ -1761,7 +1758,7 @@
     <string name="user_switched" msgid="7249833311585228097">"Τρέχων χρήστης <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Εναλλαγή σε <xliff:g id="NAME">%1$s</xliff:g>…"</string>
     <string name="user_logging_out_message" msgid="7216437629179710359">"Αποσύνδεση <xliff:g id="NAME">%1$s</xliff:g>…"</string>
-    <string name="owner_name" msgid="8713560351570795743">"Κάτοχο"</string>
+    <string name="owner_name" msgid="8713560351570795743">"Κάτοχος"</string>
     <string name="guest_name" msgid="8502103277839834324">"Επισκέπτης"</string>
     <string name="error_message_title" msgid="4082495589294631966">"Σφάλμα"</string>
     <string name="error_message_change_not_allowed" msgid="843159705042381454">"Αυτή η αλλαγή δεν επιτρέπεται από το διαχειριστή σας"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Διαχείριση από <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Ενεργός"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Ανενεργός"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Οποιοδήποτε ημερολόγιο"</string>
     <string name="muted_by" msgid="91464083490094950">"Το τρίτο μέρος <xliff:g id="THIRD_PARTY">%1$s</xliff:g> θέτει ορισμένους ήχους σε σίγαση"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Υπάρχει ένα εσωτερικό πρόβλημα με τη συσκευή σας και ενδέχεται να είναι ασταθής μέχρι την επαναφορά των εργοστασιακών ρυθμίσεων."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Υπάρχει ένα εσωτερικό πρόβλημα με τη συσκευή σας. Επικοινωνήστε με τον κατασκευαστή σας για λεπτομέρειες."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Δοκιμή"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Κοινόχρηστο"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Συνδέθηκε αυτόματα με δορυφόρο"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Μπορείτε να στέλνετε και να λαμβάνετε μηνύματα χωρίς δίκτυο κινητής τηλεφωνίας ή Wi-Fi."</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Άνοιγμα Messages"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index dc36c8c..5a6c620 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Can’t reach mobile network"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Try changing preferred network. Tap to change."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Emergency calling unavailable"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Emergency calls require a mobile network"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerts"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Call forwarding"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Emergency callback mode"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Delete"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Input method"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Text actions"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Handwriting is not supported in this field"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Handwriting is not supported in password fields"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Back"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Switch input method"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Storage space running out"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Managed by <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"On"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Off"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Any calendar"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"There\'s an internal problem with your device. Contact your manufacturer for details."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Auto-connected to satellite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index c1316ed..86fe49c 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -1929,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Managed by <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"On"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Off"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Any calendar"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"There\'s an internal problem with your device. Contact your manufacturer for details."</string>
@@ -2391,6 +2394,7 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"App content hidden from screen share for security"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"Auto connected to satellite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 9f00023..4972e1b 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Can’t reach mobile network"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Try changing preferred network. Tap to change."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Emergency calling unavailable"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Emergency calls require a mobile network"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerts"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Call forwarding"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Emergency callback mode"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Delete"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Input method"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Text actions"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Handwriting is not supported in this field"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Handwriting is not supported in password fields"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Back"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Switch input method"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Storage space running out"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Managed by <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"On"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Off"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Any calendar"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"There\'s an internal problem with your device. Contact your manufacturer for details."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Auto-connected to satellite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 67ca701..c35c2ff 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Can’t reach mobile network"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Try changing preferred network. Tap to change."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Emergency calling unavailable"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Emergency calls require a mobile network"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerts"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Call forwarding"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Emergency callback mode"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Delete"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Input method"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Text actions"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Handwriting is not supported in this field"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Handwriting is not supported in password fields"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Back"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Switch input method"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Storage space running out"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Managed by <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"On"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Off"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Any calendar"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> is muting some sounds"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"There\'s an internal problem with your device. Contact your manufacturer for details."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Auto-connected to satellite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"You can send and receive messages without a mobile or Wi-Fi network"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Open Messages"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 4abc241..b7f49980 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -1929,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‎‏‎‏‎‏‎‏‎‎‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‎‏‏‏‎Managed by ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎On‎‏‎‎‏‎"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‏‏‎‏‎‏‎‏‏‎‏‏‎‎Off‎‏‎‎‏‎"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‎‎‏‏‎‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‏‏‏‎‎, ‎‏‎‎‏‎ "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‎‎‎‏‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="START">%1$s</xliff:g>‎‏‎‎‏‏‏‎ - ‎‏‎‎‏‏‎<xliff:g id="END">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎‎‎‎‏‎‏‏‎Any calendar‎‏‎‎‏‎"</string>
     <string name="muted_by" msgid="91464083490094950">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‎‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‎‎‎‏‏‎‎‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‏‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="THIRD_PARTY">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is muting some sounds‎‏‎‎‏‎"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‎‎‎‏‏‎‏‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎There\'s an internal problem with your device, and it may be unstable until you factory data reset.‎‏‎‎‏‎"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‏‎‏‎‎‎‏‎‏‏‎‎‏‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‎‏‏‎There\'s an internal problem with your device. Contact your manufacturer for details.‎‏‎‎‏‎"</string>
@@ -2391,6 +2394,7 @@
     <string name="profile_label_test" msgid="9168641926186071947">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‎‏‎‏‏‎Test‎‏‎‎‏‎"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‏‎‏‏‎Communal‎‏‎‎‏‎"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <string name="screen_not_shared_sensitive_content" msgid="7058419185079565001">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‎‏‎‏‏‎‎‏‎‎‏‎App content hidden from screen share for security‎‏‎‎‏‎"</string>
     <string name="satellite_notification_title" msgid="4026338973463121526">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‎‏‎‏‎‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‎Auto connected to satellite‎‏‎‎‏‎"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‎‏‏‎‎‎‎‏‎‏‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‎You can send and receive messages without a mobile or Wi-Fi network‎‏‎‎‏‎"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‎Open Messages‎‏‎‎‏‎"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 03660cb..4f7f7a7 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"No se puede acceder a la red móvil"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Presiona para cambiar la red preferida."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Servicio de llamadas de emergencia no disponible"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Las llamadas de emergencia requieren una red móvil"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Desvío de llamada"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modo de devolución de llamada de emergencia"</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Eliminar"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Método de entrada"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Acciones de texto"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"La función Escritura a mano no es compatible en este campo"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"La función Escritura a mano no es compatible en los campos de contraseñas"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Atrás"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Cambiar método de entrada"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Queda poco espacio de almacenamiento"</string>
@@ -1933,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Administradas por <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activado"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desactivado"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Cualquier calendario"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> silencia algunos sonidos"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Existe un problema interno con el dispositivo, de modo que el dispositivo puede estar inestable hasta que restablezcas la configuración de fábrica."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Existe un problema interno con el dispositivo. Comunícate con el fabricante para obtener más información."</string>
@@ -2137,7 +2137,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"Aceptar"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Desactivar"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Más información"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Las notificaciones mejoradas reemplazaron a las notificaciones adaptables en Android 12. Esta función muestra respuestas y acciones sugeridas, y organiza tus notificaciones.\n\nLas notificaciones mejoradas pueden acceder a todo el contenido de notificaciones, lo que incluye información personal, como nombres de contactos y mensajes. También pueden descartar o responder notificaciones (como contestar llamadas) y controlar la función No interrumpir."</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"Las notificaciones mejoradas reemplazaron a las notificaciones adaptables en Android 12. Esta función muestra respuestas y acciones sugeridas, y organiza tus notificaciones.\n\nLas notificaciones mejoradas pueden acceder a todo el contenido de notificaciones, incluida información personal, como nombres de contactos y mensajes. También pueden descartar o responder notificaciones (como contestar llamadas) y controlar la función No interrumpir."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Notificación de información del modo de Rutinas"</string>
     <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Ahorro de batería activado"</string>
     <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Reduciendo el uso de la batería para extender su duración"</string>
@@ -2395,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Probar"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Compartido"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Conexión automática a satélite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Puedes enviar y recibir mensajes incluso si no tienes conexión a una red móvil o Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensajes"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 1554b46..bf9d526 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"No se puede establecer conexión con la red móvil"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Toca para cambiar la red preferida."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Servicio de llamadas de emergencia no disponible"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Para hacer llamadas de emergencia, necesitas conectarte a una red móvil"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Desvío de llamadas"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modo de devolución de llamada de emergencia"</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Eliminar"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Método de introducción de texto"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Acciones de texto"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Escritura a mano no está disponible en este campo"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Escritura a mano no está disponible en campos de contraseña"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Atrás"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Cambiar método de introducción de texto"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Queda poco espacio"</string>
@@ -1933,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Gestionado por <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activado"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desactivado"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Cualquier calendario"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> silencia algunos sonidos"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Se ha producido un problema interno en el dispositivo y es posible que este no sea estable hasta que restablezcas el estado de fábrica."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Se ha producido un problema interno en el dispositivo. Ponte en contacto con el fabricante para obtener más información."</string>
@@ -2395,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Prueba"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Común"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automáticamente al satélite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Puedes enviar y recibir mensajes sin una red móvil o Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre Mensajes"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 9b9760c..cc82e47 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1929,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Haldab <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Sees"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Väljas"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Mis tahes kalender"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> vaigistab teatud helid"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Seadmes ilmnes sisemine probleem ja seade võib olla ebastabiilne seni, kuni lähtestate seadme tehase andmetele."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Seadmes ilmnes sisemine probleem. Üksikasjaliku teabe saamiseks võtke ühendust tootjaga."</string>
@@ -2391,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Jagatud"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Satelliidiga loodi automaatselt ühendus"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Teil on võimalik sõnumeid saata ja vastu võtta ilma mobiilside- ja WiFi-võrguta"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ava rakendus Messages"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 7f9919d..34c0663 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Ezin da konektatu sare mugikorrera"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Aldatu sare hobetsia. Sakatu aldatzeko."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Ezin da egin larrialdi-deirik"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Sare mugikorrera konektatuta egon behar duzu larrialdi-deiak egin ahal izateko"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertak"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Dei-desbideratzea"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Larrialdi-zerbitzuen deiak jasotzeko modua"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Ezabatu"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Idazketa-metodoa"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Testu-ekintzak"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Eremu honetan ez da onartzen eskuzko idazketa"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Pasahitzen eremuetan ez da onartzen eskuzko idazketa"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Atzera"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Aldatu idazketa-metodoa"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Memoria betetzen ari da"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Kudeatzailea: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Aktibatuta"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desaktibatuta"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Edozein egutegi"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> soinu batzuk isilarazten ari da"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Barneko arazo bat dago zure gailuan eta agian ezegonkor egongo da jatorrizko datuak berrezartzen dituzun arte."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Barneko arazo bat dago zure gailuan. Xehetasunak jakiteko, jarri fabrikatzailearekin harremanetan."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Probakoa"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Partekatua"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automatikoki konektatu da satelitera"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Mezuak bidal eta jaso ditzakezu sare mugikorrik edo wifi-sarerik gabe"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ireki Mezuak"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index af97c90..4f2484e 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"شبکه تلفن همراه دردسترس نیست"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"تغییر شبکه ترجیحی را امتحان کنید. برای تغییر، ضربه بزنید."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"تماس اضطراری امکان‌پذیر نیست"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"برای برقراری تماس اضطراری به شبکه تلفن همراه نیاز دارید"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"هشدارها"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"بازارسال تماس"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"حالت پاسخ تماس اضطراری"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"حذف"</string>
     <string name="inputMethod" msgid="1784759500516314751">"روش ورودی"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"کنش‌های متنی"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"در این فیلد از دست‌نویسی پشتیبانی نمی‌شود"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"در فیلدهای گذرواژه از دست‌نویسی پشتیبانی نمی‌شود"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"برگشت"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"تغییر روش ورودی"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"فضای ذخیره‌سازی درحال پر شدن است"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"تحت‌مدیریت <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"روشن"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"خاموش"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"، "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"هر تقویمی"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> درحال قطع کردن بعضی از صداهاست"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"دستگاهتان یک مشکل داخلی دارد، و ممکن است تا زمانی که بازنشانی داده‌های کارخانه انجام نگیرد، بی‌ثبات بماند."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"دستگاهتان یک مشکل داخلی دارد. برای جزئیات آن با سازنده‌تان تماس بگیرید."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"آزمایش"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"عمومی"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"به‌طور خودکار به ماهواره متصل شد"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"‏می‌توانید بدون شبکه تلفن همراه یا Wi-Fi پیام ارسال و دریافت کنید"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"باز کردن «پیام‌ها»"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 823a26a..81b9848 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobiiliverkkoon ei saada yhteyttä"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Kokeile vaihtaa ensisijaista verkkoa. Vaihda se napauttamalla."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hätäpuhelut eivät ole käytettävissä"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Hätäpuhelu edellyttää mobiiliverkkoa"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Ilmoitukset"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Soitonsiirto"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Hätäpuhelujen takaisinsoittotila"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Poista"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Syöttötapa"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Tekstitoiminnot"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Käsinkirjoitusta ei tueta tässä kentässä"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Käsinkirjoitusta ei tueta salasanakentissä"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Takaisin"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Vaihda syöttötapaa"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Tallennustila loppumassa"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Ylläpitäjä: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Päällä"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Pois päältä"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Kaikki kalenterit"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> mykistää joitakin ääniä"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Laitteellasi on sisäinen ongelma, joka aiheuttaa epävakautta. Voit korjata tilanteen palauttamalla tehdasasetukset."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Laitteesi yhdistäminen ei onnistu sisäisen virheen takia. Saat lisätietoja valmistajalta."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Testi"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Jaettu"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Yhdistetty automaattisesti satelliittiin"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Voit lähettää ja vastaanottaa viestejä ilman mobiili‑ tai Wi-Fi-verkkoa"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Avaa Messages"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 87af6b0..15d36f5 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Impossible de joindre le réseau cellulaire"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Essayez de changer de réseau préféré. Touchez l\'écran pour changer."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Le service d\'appel d\'urgence n\'est pas accessible"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Les appels d\'urgence nécessitent un réseau cellulaire"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertes"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Transfert d\'appel"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Mode de rappel d\'urgence"</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Supprimer"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Mode de saisie"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Actions sur le texte"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Ce champ ne prend pas en charge l\'écriture manuscrite"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Les champs de mot de passe ne prennent pas en charge l\'écriture manuscrite"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Retour"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Changer de méthode d\'entrée"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Espace de stockage bientôt saturé"</string>
@@ -1933,6 +1930,12 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Géré par <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activé"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Désactivé"</string>
+    <!-- no translation found for zen_mode_trigger_summary_divider_text (7461583466043698862) -->
+    <skip />
+    <!-- no translation found for zen_mode_trigger_summary_range_symbol_combination (1804900738798069619) -->
+    <skip />
+    <!-- no translation found for zen_mode_trigger_event_calendar_any (2086784607921121803) -->
+    <skip />
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> désactive certains sons"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Un problème interne est survenu avec votre appareil. Il se peut qu\'il soit instable jusqu\'à ce que vous le réinitialisiez à ses paramètres par défaut."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Un problème interne est survenu avec votre appareil. Communiquez avec le fabricant pour obtenir plus de détails."</string>
@@ -2395,6 +2398,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Commun"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Connecté au satellite automatiquement"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Vous pouvez envoyer et recevoir des messages sans avoir recours à un appareil mobile ou à un réseau Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 9037bb7..0346822 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Impossible d\'accéder au réseau mobile"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Essayez de changer le réseau préféré. Appuyez pour le modifier."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Appels d\'urgence non disponibles"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Les appels d\'urgence requièrent un réseau mobile"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertes"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Transfert d\'appel"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Mode de rappel d\'urgence"</string>
@@ -829,7 +828,7 @@
     <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"Autorise l\'appli à mettre à jour les états de validation des clés de contact E2EE possédées par d\'autres applis."</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Définir les règles du mot de passe"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Gérer le nombre et le type de caractères autorisés dans les mots de passe et les codes d\'accès de verrouillage de l\'écran"</string>
-    <string name="policylab_watchLogin" msgid="7599669460083719504">"Gérer les tentatives de déverrouillage de l\'écran"</string>
+    <string name="policylab_watchLogin" msgid="7599669460083719504">"Contrôler les tentatives de déverrouillage de l\'écran"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Contrôler le nombre de mots de passe incorrects saisis pour le déverrouillage de l\'écran, puis verrouiller la tablette ou effacer toutes ses données si le nombre maximal de tentatives de saisie du mot de passe est atteint"</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Contrôle le nombre de fois qu\'un mot de passe incorrect est saisi lors du déverrouillage de l\'écran, et verrouille votre appareil Android TV ou en efface toutes les données si le nombre maximal de mots de passe incorrects autorisé est dépassé."</string>
     <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Contrôler le nombre de mots de passe incorrects saisis pour le déverrouillage de l\'écran, puis verrouiller le système d\'infoloisirs ou effacer toutes ses données si le nombre maximal de tentatives de saisie du mot de passe est atteint."</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Supprimer"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Mode de saisie"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Actions sur le texte"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Ce champ ne prend pas en charge l\'écriture manuscrite"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Les champs de mot de passe ne prennent pas en charge l\'écriture manuscrite"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Retour"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Changer le mode de saisie"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Espace de stockage bientôt saturé"</string>
@@ -1933,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Géré par <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activé"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Désactivé"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Tous les agendas"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> coupe certains sons"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Un problème interne lié à votre appareil est survenu. Ce dernier risque d\'être instable jusqu\'à ce que vous rétablissiez la configuration d\'usine."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Un problème interne lié à votre appareil est survenu. Veuillez contacter le fabricant pour en savoir plus."</string>
@@ -1992,9 +1992,9 @@
     <string name="work_mode_off_title" msgid="6367463960165135829">"Réactiver les applis pro ?"</string>
     <string name="work_mode_turn_on" msgid="5316648862401307800">"Réactiver"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Urgence"</string>
-    <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Définir verrouillage écran"</string>
+    <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Activer verrouillage écran"</string>
     <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Activer verrouillage écran"</string>
-    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Pour utiliser votre espace privé, définissez un verrouillage de l\'écran sur cet appareil"</string>
+    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Pour utiliser votre espace privé, activez le verrouillage de l\'écran sur cet appareil"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Application non disponible"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'est pas disponible pour le moment."</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponible"</string>
@@ -2395,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Commun"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Connecté automatiquement au réseau satellite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Vous pouvez envoyer et recevoir des messages sans connexion au réseau mobile ou Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Ouvrir Messages"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index ff819f1..fa48e96 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1929,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Xestionada por <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activada"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desactivada"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Calquera calendario"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está silenciando algúns sons"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Produciuse un erro interno no teu dispositivo e quizais funcione de maneira inestable ata o restablecemento dos datos de fábrica."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Produciuse un erro interno co teu dispositivo. Contacta co teu fabricante para obter máis información."</string>
@@ -2391,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Proba"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Compartido"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Conexión automática ao satélite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Podes enviar e recibir mensaxes sen unha rede de telefonía móbil ou wifi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir Mensaxes"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 49a29d2..fb202ba 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"મોબાઇલ નેટવર્ક સુધી પહોંચી શકાતું નથી"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"પસંદગીનું નેટવર્ક બદલવાનો પ્રયાસ કરો. બદલવા માટે ટૅપ કરો."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"કટોકટીની કૉલિંગ સેવા અનુપલબ્ધ"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ઇમર્જન્સી કૉલ માટે મોબાઇલ નેટવર્કની આવશ્યકતા છે"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"અલર્ટ"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"કૉલ ફૉર્વર્ડિંગ"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"કટોકટી કૉલબૅક મોડ"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"ડિલીટ કરો"</string>
     <string name="inputMethod" msgid="1784759500516314751">"ઇનપુટ પદ્ધતિ"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"ટેક્સ્ટ ક્રિયાઓ"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"આ ફીલ્ડમાં હસ્તલેખન સપોર્ટેડ નથી"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"પાસવર્ડ ફીલ્ડમાં હસ્તલેખન સપોર્ટેડ નથી"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"પાછળ"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"ઇનપુટ પદ્ધતિ સ્વિચ કરો"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"સ્ટોરેજ સ્થાન સમાપ્ત થયું"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> દ્વારા મેનેજ કરવામાં આવે છે"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ચાલુ છે"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"બંધ છે"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"કોઈપણ કૅલેન્ડર"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> અમુક અવાજોને મ્યૂટ કરે છે"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"તમારા ઉપકરણમાં આંતરિક સમસ્યા છે અને જ્યાં સુધી તમે ફેક્ટરી ડેટા ફરીથી સેટ કરશો નહીં ત્યાં સુધી તે અસ્થિર રહી શકે છે."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"તમારા ઉપકરણમાં આંતરિક સમસ્યા છે. વિગતો માટે તમારા નિર્માતાનો સંપર્ક કરો."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"પરીક્ષણ કરો"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"કૉમ્યુનલ"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"સેટેલાઇટ સાથે ઑટોમૅટિક રીતે કનેક્ટેડ"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"તમે મોબાઇલ અથવા વાઇ-ફાઇ નેટવર્ક વિના મેસેજ મોકલી અને પ્રાપ્ત કરી શકો છો"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ખોલો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index b3a0dce..fd99d19 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"मोबाइल नेटवर्क से कनेक्ट नहीं किया जा सका"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"पसंदीदा नेटवर्क बदलकर देखें. बदलने के लिए टैप करें."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"आपातकालीन कॉल करने की सुविधा उपलब्ध नहीं है"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"आपातकालीन कॉल के लिए मोबाइल नेटवर्क ज़रूरी है"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"सूचनाएं"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"कॉल को दूसरे नंबर पर भेजना"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"आपातकालीन कॉलबैक मोड"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"मिटाएं"</string>
     <string name="inputMethod" msgid="1784759500516314751">"इनपुट विधि"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"लेख क्रियाएं"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"इस फ़ील्ड में हैंडराइटिंग की सुविधा मौजूद नहीं है"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"पासवर्ड वाले फ़ील्ड में हैंडराइटिंग की सुविधा मौजूद नहीं है"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"वापस जाएं"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"इनपुट का तरीका बदलें"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"मेमोरी में जगह नहीं बची है"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"मैनेज करने वाला ऐप्लिकेशन: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"चालू है"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"बंद है"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"कोई भी कैलेंडर"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> कुछ आवाज़ें म्‍यूट कर रहा है"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"आपके डिवाइस में कोई अंदरूनी समस्या है और यह तब तक ठीक नहीं होगी जब तक आप फ़ैक्‍टरी डेटा रीसेट नहीं करते."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"आपके डिवाइस के साथ कोई आंतरिक गड़बड़ी हुई. विवरणों के लिए अपने निर्माता से संपर्क करें."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"टेस्ट"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"कम्यूनिटी"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"सैटलाइट से अपने-आप कनेक्ट हो गया"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"मोबाइल या वाई-फ़ाई नेटवर्क के बिना भी मैसेज भेजे और पाए जा सकते हैं"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ऐप्लिकेशन खोलें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 2f93a53..5ac09ec 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobilna mreža nije dostupna"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Pokušajte promijeniti preferiranu mrežu. Dodirnite da biste je promijenili."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hitni pozivi nisu dostupni"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Za hitne pozive potrebna je mobilna mreža"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozorenja"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Preusmjeravanje poziva"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Način hitnog povratnog poziva"</string>
@@ -331,7 +330,7 @@
     <string name="permgroupdesc_microphone" msgid="1047786732792487722">"snimati zvuk"</string>
     <string name="permgrouplab_activityRecognition" msgid="3324466667921775766">"Tjelesna aktivnost"</string>
     <string name="permgroupdesc_activityRecognition" msgid="4725624819457670704">"pristupiti vašoj tjelesnoj aktivnosti"</string>
-    <string name="permgrouplab_camera" msgid="9090413408963547706">"Fotoaparat"</string>
+    <string name="permgrouplab_camera" msgid="9090413408963547706">"Kamera"</string>
     <string name="permgroupdesc_camera" msgid="7585150538459320326">"snimati fotografije i videozapise"</string>
     <string name="permgrouplab_nearby_devices" msgid="5529147543651181991">"Uređaji u blizini"</string>
     <string name="permgroupdesc_nearby_devices" msgid="3213561597116913508">"otkrivanje i povezivanje s uređajima u blizini"</string>
@@ -1060,7 +1059,7 @@
     <string name="keyguard_accessibility_widget" msgid="6776892679715699875">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget."</string>
     <string name="keyguard_accessibility_user_selector" msgid="1466067610235696600">"Birač korisnika"</string>
     <string name="keyguard_accessibility_status" msgid="6792745049712397237">"Status"</string>
-    <string name="keyguard_accessibility_camera" msgid="7862557559464986528">"Fotoaparat"</string>
+    <string name="keyguard_accessibility_camera" msgid="7862557559464986528">"Kamera"</string>
     <string name="keygaurd_accessibility_media_controls" msgid="2267379779900620614">"Nadzor medija"</string>
     <string name="keyguard_accessibility_widget_reorder_start" msgid="7066213328912939191">"Pokrenuta je promjena redoslijeda widgeta."</string>
     <string name="keyguard_accessibility_widget_reorder_end" msgid="1083806817600593490">"Završena je promjena redoslijeda widgeta."</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Izbriši"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Način unosa"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Radnje s tekstom"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Rukopis nije podržan u ovom polju"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Rukopis nije podržan u poljima za zaporku"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Natrag"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Promjena načina unosa"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Ponestaje prostora za pohranu"</string>
@@ -1933,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Upravlja <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Uključeno"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Isključeno"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bilo koji kalendar"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> isključuje neke zvukove"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Na vašem uređaju postoji interni problem i možda neće biti stabilan dok ga ne vratite na tvorničko stanje."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Na vašem uređaju postoji interni problem. Obratite se proizvođaču za više pojedinosti."</string>
@@ -1994,7 +1994,7 @@
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Hitni slučaj"</string>
     <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Postavite zaključavanje zaslona"</string>
     <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Postavi zaključavanje zaslona"</string>
-    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Za upotrebu privatnog prostora postavite zaključavanje zaslona na ovom uređaju"</string>
+    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Da biste upotrebljavali privatni prostor, postavite zaključavanje zaslona na ovom uređaju"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Aplikacija nije dostupna"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> trenutačno nije dostupna."</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – nije dostupno"</string>
@@ -2124,7 +2124,7 @@
     <string name="review_notification_settings_dismiss" msgid="4160916504616428294">"Odbaci"</string>
     <string name="notification_app_name_system" msgid="3045196791746735601">"Sustav"</string>
     <string name="notification_app_name_settings" msgid="9088548800899952531">"Postavke"</string>
-    <string name="notification_appops_camera_active" msgid="8177643089272352083">"Fotoaparat"</string>
+    <string name="notification_appops_camera_active" msgid="8177643089272352083">"Kamera"</string>
     <string name="notification_appops_microphone_active" msgid="581333393214739332">"Mikrofon"</string>
     <string name="notification_appops_overlay_active" msgid="5571732753262836481">"prikazuje se preko drugih aplikacija na zaslonu"</string>
     <string name="notification_feedback_indicator" msgid="663476517711323016">"Slanje povratnih informacija"</string>
@@ -2336,7 +2336,7 @@
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Uključite u Postavkama"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Odbaci"</string>
     <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Deblokiraj mikrofon uređaja"</string>
-    <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Deblokiraj fotoaparat uređaja"</string>
+    <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Deblokiraj kameru uređaja"</string>
     <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Za &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; i sve aplikacije i usluge"</string>
     <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Deblokiraj"</string>
     <string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"Privatnost senzora"</string>
@@ -2395,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Zajedničko"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automatski povezano sa satelitom"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Možete slati i primati poruke bez mobilne mreže ili Wi-Fi mreže"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvori Poruke"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 286d55e..06ca1b6 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"A mobilhálózat nem érhető el"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Próbálja meg módosítani a preferált hálózatot. Koppintson a módosításhoz."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Segélyhívás nem lehetséges"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"A segélyhíváshoz mobilhálózatra van szükség"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Értesítések"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Hívásátirányítás"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Sürgősségi visszahívás mód"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Törlés"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Beviteli mód"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Műveletek szöveggel"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"A kézírás nem támogatott ebben a mezőben"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"A kézírás nem támogatott a jelszómezőkben"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Vissza"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Beviteli módszer váltása"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Kevés a szabad terület"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Kezelő: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Bekapcsolva"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Kikapcsolva"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bármilyen naptár"</string>
     <string name="muted_by" msgid="91464083490094950">"A(z) <xliff:g id="THIRD_PARTY">%1$s</xliff:g> lenémít néhány hangot"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Belső probléma van az eszközzel, és instabil lehet, amíg vissza nem állítja a gyári adatokat."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Belső probléma van az eszközzel. A részletekért vegye fel a kapcsolatot a gyártóval."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Teszt"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Közös"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automatikusan csatlakozva a műholdhoz"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Küldhet és fogadhat üzeneteket mobil- és Wi-Fi-hálózat nélkül is"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"A Messages megnyitása"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 5ad4415..89e087e 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Չհաջողվեց միանալ բջջային ցանցին"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Փորձեք այլ ցանցի միանալ: Հպեք՝ նախընտրած ցանցը փոխելու համար:"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Շտապ կանչերը հասանելի չեն"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Շտապ կանչերի համար բջջային ցանց է անհրաժեշտ"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Ծանուցումներ"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Զանգի վերահասցեավորում"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Շտապ հետզանգի ռեժիմ"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Ջնջել"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Մուտքագրման եղանակը"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Տեքստի գործողությունները"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Ձեռագիր ներածումը չի աջակցվում այս դաշտում"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Ձեռագիր ներածումը չի աջակցվում գաղտնաբառերի դաշտերում"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Հետ"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Փոխել ներածման եղանակը"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Հիշողությունը սպառվում է"</string>
@@ -1633,7 +1630,7 @@
     <string name="validity_period" msgid="1717724283033175968">"Վավերականություն`"</string>
     <string name="issued_on" msgid="5855489688152497307">"Թողարկվել է`"</string>
     <string name="expires_on" msgid="1623640879705103121">"Սպառվում է`"</string>
-    <string name="serial_number" msgid="3479576915806623429">"Հերթական համարը`"</string>
+    <string name="serial_number" msgid="3479576915806623429">"Հերթական համար`"</string>
     <string name="fingerprints" msgid="148690767172613723">"Մատնահետքերը`"</string>
     <string name="sha256_fingerprint" msgid="7103976380961964600">"SHA-256 մատնահետք`"</string>
     <string name="sha1_fingerprint" msgid="2339915142825390774">"SHA-1 մատնահետք`"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Կառավարվում է <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի կողմից"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Միացված է"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Անջատված է"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Ցանկացած օրացույց"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>-ն անջատում է որոշ ձայներ"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Սարքում ներքին խնդիր է առաջացել և այն կարող է կրկնվել, մինչև չվերականգնեք գործարանային կարգավորումները:"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Սարքում ներքին խնդիր է առաջացել: Մանրամասների համար կապվեք արտադրողի հետ:"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Փորձնական"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Ընդհանուր"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Ավտոմատ միացել է արբանյակին"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Դուք կարող եք ուղարկել և ստանալ հաղորդագրություններ՝ առանց բջջային կամ Wi-Fi կապի"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Բացել Messages-ը"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 3230b02..616b30b 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Tidak dapat menjangkau jaringan seluler"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Coba ubah jaringan pilihan. Ketuk untuk mengubah."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Panggilan darurat tidak tersedia"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Panggilan darurat memerlukan jaringan seluler"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Notifikasi"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Penerusan panggilan"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Mode telepon balik darurat"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Hapus"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Metode masukan"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Tindakan teks"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Tulisan tangan tidak didukung di kolom ini"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Tulisan tangan tidak didukung di kolom sandi"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Kembali"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Beralih metode input"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Ruang penyimpanan hampir habis"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Dikelola oleh <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Aktif"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Nonaktif"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Kalender mana saja"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> mematikan beberapa suara"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Ada masalah dengan perangkat. Hal ini mungkin membuat perangkat jadi tidak stabil dan perlu dikembalikan ke setelan pabrik."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Ada masalah dengan perangkat. Hubungi produsen perangkat untuk informasi selengkapnya."</string>
@@ -1993,7 +1993,7 @@
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Darurat"</string>
     <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Setel kunci layar"</string>
     <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Setel kunci layar"</string>
-    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Untuk menggunakan ruang pribadi, setel kunci layar di perangkat ini"</string>
+    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Untuk menggunakan ruang privasi, setel kunci layar di perangkat ini"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Aplikasi tidak tersedia"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak tersedia saat ini."</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> tidak tersedia"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Pengujian"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Umum"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Menghubungkan otomatis ke satelit"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Anda dapat mengirim dan menerima pesan tanpa jaringan seluler atau Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Message"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 21f3bfe..5d55ba8 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Ekki næst samband við farsímakerfi"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prófaðu að velja annað símkerfi. Ýttu til að breyta."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Neyðarsímtöl eru ekki í boði"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Neyðarsímtöl krefjast farsímakerfis"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Tilkynningar"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Símtalsflutningur"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Stilling fyrir svarhringingu neyðarsímtala"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Eyða"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Innsláttaraðferð"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Textaaðgerðir"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Handskrift er ekki studd í þessum reit"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Handskrift er ekki studd í reitum fyrir aðgangsorð"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Til baka"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Skipta um innfærsluaðferð"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Geymslurýmið er senn á þrotum"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Stýrt af <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Kveikt"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Slökkt"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Öll dagatöl"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> þaggar í einhverjum hljóðum"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Innra vandamál kom upp í tækinu og það kann að vera óstöðugt þangað til þú núllstillir það."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Innra vandamál kom upp í tækinu. Hafðu samband við framleiðanda til að fá nánari upplýsingar."</string>
@@ -1974,7 +1974,7 @@
     <string name="user_creation_account_exists" msgid="2239146360099708035">"Viltu leyfa <xliff:g id="APP">%1$s</xliff:g> að stofna nýjan notanda með <xliff:g id="ACCOUNT">%2$s</xliff:g> (notandi með þennan reikning er þegar fyrir hendi)?"</string>
     <string name="user_creation_adding" msgid="7305185499667958364">"Leyfa <xliff:g id="APP">%1$s</xliff:g> að stofna nýjan notanda með <xliff:g id="ACCOUNT">%2$s</xliff:g> ?"</string>
     <string name="supervised_user_creation_label" msgid="6884904353827427515">"Bæta við stýrðum notanda"</string>
-    <string name="language_selection_title" msgid="52674936078683285">"Bæta við tungumáli"</string>
+    <string name="language_selection_title" msgid="52674936078683285">"Bæta tungumáli við"</string>
     <string name="country_selection_title" msgid="5221495687299014379">"Svæðisval"</string>
     <string name="search_language_hint" msgid="7004225294308793583">"Sláðu inn heiti tungumáls"</string>
     <string name="language_picker_section_suggested" msgid="6556199184638990447">"Tillögur"</string>
@@ -1992,7 +1992,7 @@
     <string name="work_mode_turn_on" msgid="5316648862401307800">"Ljúka hléi"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Neyðartilvik"</string>
     <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Stilltu skjálás"</string>
-    <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Stilltu skjálás"</string>
+    <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Stilla skjálás"</string>
     <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Stilltu skjálás í tækinu til að nota leynirými"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Forrit er ekki tiltækt"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> er ekki tiltækt núna."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Prófun"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Sameiginlegt"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Tengdist sjálfkrafa við gervihnött"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Þú getur sent og móttekið skilaboð án tengingar við farsímakerfi eða Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Opna Messages"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 25bde8fe..9d8d74a 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Impossibile raggiungere la rete mobile"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prova a cambiare la rete preferita. Tocca per cambiare."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Chiamate di emergenza non disponibili"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Per le chiamate di emergenza è necessaria una rete mobile"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Avvisi"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Deviazione chiamate"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modalità di richiamata di emergenza"</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Elimina"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Metodo inserimento"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Azioni testo"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"La scrittura a mano libera non è supportata in questo campo"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"La scrittura a mano libera non è supportata nei campi per le password"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Indietro"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Cambia metodo di immissione"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Spazio di archiviazione in esaurimento"</string>
@@ -1933,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Gestione: app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"On"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Off"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualsiasi calendario"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> sta disattivando alcuni suoni"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Si è verificato un problema interno con il dispositivo, che potrebbe essere instabile fino al ripristino dei dati di fabbrica."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Si è verificato un problema interno con il dispositivo. Per informazioni dettagliate, contatta il produttore."</string>
@@ -2395,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Condiviso"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Connessione automatica al satellite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Puoi inviare e ricevere messaggi senza una rete mobile o Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Apri Messaggi"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 734f26a..c256de9 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"לא ניתן להתחבר לרשת הסלולרית"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"אפשר לנסות לשנות את הרשת המועדפת. יש להקיש כדי לשנות אותה."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"שיחות חירום לא זמינות"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"כדי לבצע שיחות חירום, צריך להתחבר לרשת סלולרית"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"התראות"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"העברת שיחות"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"מצב \'התקשרות חזרה בחירום\'"</string>
@@ -259,7 +258,7 @@
     <string name="global_action_power_options" msgid="1185286119330160073">"הפעלה"</string>
     <string name="global_action_restart" msgid="4678451019561687074">"הפעלה מחדש"</string>
     <string name="global_action_emergency" msgid="1387617624177105088">"חירום"</string>
-    <string name="global_action_bug_report" msgid="5127867163044170003">"דיווח על באג"</string>
+    <string name="global_action_bug_report" msgid="5127867163044170003">"דוח איתור באגים"</string>
     <string name="global_action_logout" msgid="6093581310002476511">"סיום הפעלה"</string>
     <string name="global_action_screenshot" msgid="2610053466156478564">"צילום מסך"</string>
     <string name="bugreport_title" msgid="8549990811777373050">"דיווח על באג"</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"מחיקה"</string>
     <string name="inputMethod" msgid="1784759500516314751">"שיטת קלט"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"פעולות טקסט"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"אין תמיכה בכתיבה ידנית בשדה הזה"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"אין תמיכה בכתיבה ידנית בשדות של הזנת סיסמה"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"חזרה"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"החלפה של שיטת הקלט"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"מקום האחסון עומד להיגמר"</string>
@@ -1933,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"בניהול של <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"מצב פעיל"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"מצב מושבת"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"‫<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"כל יומן"</string>
     <string name="muted_by" msgid="91464083490094950">"חלק מהצלילים מושתקים על ידי <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"קיימת בעיה פנימית במכשיר שלך, וייתכן שהוא לא יתפקד כראוי עד שיבוצע איפוס לנתוני היצרן."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"קיימת בעיה פנימית במכשיר שלך. לקבלת פרטים, יש ליצור קשר עם היצרן."</string>
@@ -2395,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"בדיקה"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"שיתופי"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"חיבור אוטומטי ללוויין"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"‏אפשר לשלוח ולקבל הודעות ללא רשת סלולרית או רשת Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"‏לפתיחת Messages"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 5cff295..eee2e3d 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"モバイル ネットワークにアクセスできません"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"タップして、優先ネットワークを変更してください。"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"緊急通報は利用できません"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"緊急通報にはモバイル ネットワークが必要です"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"通知"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"電話の転送"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"緊急通報待機モード"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"削除"</string>
     <string name="inputMethod" msgid="1784759500516314751">"入力方法"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"テキスト操作"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"この欄は手書き入力には対応していません"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"パスワードの欄は手書き入力には対応していません"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"戻る"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"入力方法の切り替え"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"空き容量わずか"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> によって管理されています"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ON"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"OFF"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"、 "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>~<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"すべてのカレンダー"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> により一部の音はミュートに設定"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"デバイスで内部的な問題が発生しました。データが初期化されるまで不安定になる可能性があります。"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"デバイスで内部的な問題が発生しました。詳しくはメーカーにお問い合わせください。"</string>
@@ -2373,8 +2373,8 @@
     <string name="concurrent_display_notification_name" msgid="1526911253558311131">"デュアル スクリーン"</string>
     <string name="concurrent_display_notification_active_title" msgid="4892473462327943673">"デュアル スクリーン: ON"</string>
     <string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g>は 2 画面でコンテンツを表示しています"</string>
-    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"デバイスが熱くなりすぎています"</string>
-    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"スマートフォンが熱くなりすぎているため、デュアル スクリーンを使用できません"</string>
+    <string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"デバイスが熱くなっています"</string>
+    <string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"スマートフォンが熱いため、デュアル スクリーンを使用できません"</string>
     <string name="concurrent_display_notification_power_save_title" msgid="1794569070730736281">"デュアル スクリーンを使用できません"</string>
     <string name="concurrent_display_notification_power_save_content" msgid="2198116070583851493">"バッテリー セーバーが ON のため、デュアル スクリーンを使用できません。この動作は設定で OFF にできます。"</string>
     <string name="device_state_notification_settings_button" msgid="691937505741872749">"設定に移動"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"テスト"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"共用"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"衛星に自動接続しました"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"モバイル ネットワークや Wi-Fi ネットワークを使わずにメッセージを送受信できます"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"メッセージ アプリを開く"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index dc8e594..ececd92 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"მობილურ ქსელთან დაკავშირება ვერ ხერხდება"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ცადეთ უპირატესი ქსელის შეცვლა. შეეხეთ შესაცვლელად."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"გადაუდებელი ზარი მიუწვდომელია"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"გადაუდებელი ზარები საჭიროებს მობილურ ქსელს"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"გაფრთხილებები"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"ზარის გადამისამართება"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"გადაუდებელი გადმორეკვის რეჟიმი"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"წაშლა"</string>
     <string name="inputMethod" msgid="1784759500516314751">"შეყვანის მეთოდი"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"ქმედებები ტექსტზე"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"ამ ველში ხელით წერა არ არის მხარდაჭერილი"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"პაროლის ველში ხელით წერა არ არის მხარდაჭერილი"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"უკან"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"შეყვანის მეთოდის გადართვა"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"თავისუფალი ადგილი იწურება"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"მართავს <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ჩართული"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"გამორთული"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ნებისმიერი კალენდარი"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ზოგიერთ ხმას ადუმებს"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"ფიქსირდება თქვენი მ ოწყობილობის შიდა პრობლემა და შეიძლება არასტაბილური იყოს, სანამ ქარხნულ მონაცემების არ განაახლებთ."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"ფიქსირდება თქვენი მოწყობილობის შიდა პრობლემა. დეტალებისათვის, მიმართეთ თქვენს მწარმოებელს."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"სატესტო"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"საერთო"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"სატელიტთან ავტომატურად დაკავშირებულია"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"შეგიძლიათ გაგზავნოთ და მიიღოთ შეტყობინებები მობილური ან Wi-Fi ქსელის გარეშე"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages-ის გახსნა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index c91d14f..38c6f77 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Мобильдік желіге қосылу мүмкін емес"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Таңдаулы желіні өзгертіп көріңіз. Өзгерту үшін түртіңіз."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Жедел қызметке қоңырау шалу мүмкін емес"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Құтқару қызметіне қоңырау шалу үшін мобильдік желі қажет."</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Дабылдар"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Қоңырауды басқа нөмірге бағыттау"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Шұғыл кері қоңырау шалу режимі"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Жою"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Енгізу әдісі"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Мәтін әрекеттері"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Бұл өрісте қолмен жазу мүмкін емес."</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Құпия сөз өрістерінде қолмен жазу мүмкін емес."</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Артқа"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Енгізу әдісін ауыстыру"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Жадта орын азайып барады"</string>
@@ -1286,7 +1283,7 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Қолданбалар іске қосылуда."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Қосуды аяқтауда."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Қуат түймесін бастыңыз. Бұл әдетте экранды өшіреді.\n\nСаусақ ізін реттеу үшін, оны жайлап түртіп көріңіз."</string>
-    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Реттеуді аяқтау үшін экранды өшіріңіз"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Реттеуді аяқтау үшін экранды өшіріңіз."</string>
     <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Өшіру"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Саусақ ізін растауды жалғастырасыз ба?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Қуат түймесін бастыңыз. Бұл әдетте экранды өшіреді.\n\nСаусақ ізін растау үшін, оны жайлап түртіп көріңіз."</string>
@@ -1564,7 +1561,7 @@
     <string name="sync_really_delete" msgid="5657871730315579051">"Бұл нәрселер жойылсын"</string>
     <string name="sync_undo_deletes" msgid="5786033331266418896">"Жойылғандарды кері орындау"</string>
     <string name="sync_do_nothing" msgid="4528734662446469646">"Қазір ешқандай әрекет жасамаңыз"</string>
-    <string name="choose_account_label" msgid="5557833752759831548">"Аккаунт таңдау"</string>
+    <string name="choose_account_label" msgid="5557833752759831548">"Аккаунт таңдаңыз"</string>
     <string name="add_account_label" msgid="4067610644298737417">"Аккаунт қосу"</string>
     <string name="add_account_button_label" msgid="322390749416414097">"Аккаунт қосу."</string>
     <string name="number_picker_increment_button" msgid="7621013714795186298">"Арттыру"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> басқарады."</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Қосулы"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Өшірулі"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Кез келген күнтізбе"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> кейбір дыбыстарды өшіруде"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"There\'s an internal problem with your device. Contact your manufacturer for details."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Сынақ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Жалпы"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Жерсерік қызметіне автоматты түрде қосылды"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Мобильдік не Wi-Fi желісіне қосылмастан хабар жібере аласыз және ала аласыз."</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages қолданбасын ашу"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 92c3c5a..6c0a195 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"មិន​អាច​ភ្ជាប់​បណ្ដាញ​ទូរសព្ទ​ចល័តបានទេ"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"សាកល្បង​ប្ដូរ​ទៅបណ្ដាញ​ដែល​ចង់ប្រើ។ សូមចុច​ដើម្បីផ្លាស់​ប្ដូរ។"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"មិន​អាច​ប្រើ​ការ​ហៅ​បន្ទាន់​បានទេ"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ការហៅទៅលេខសង្គ្រោះបន្ទាន់តម្រូវឱ្យមានបណ្ដាញ​ទូរសព្ទ​ចល័ត"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"ការជូនដំណឹង"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"ការបញ្ជូន​ការហៅ​ទូរសព្ទ​បន្ត"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"មុខងារ​ហៅត្រឡប់​វិញ​បន្ទាន់"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"លុប"</string>
     <string name="inputMethod" msgid="1784759500516314751">"វិធីបញ្ចូល"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"សកម្មភាព​អត្ថបទ"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"មិនអាចប្រើការសរសេរដោយដៃនៅក្នុងកន្លែងបញ្ចូលនេះបានទេ"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"មិនអាចប្រើការសរសេរដោយដៃនៅក្នុងកន្លែងបញ្ចូលពាក្យសម្ងាត់បានទេ"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"ថយក្រោយ"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"ប្ដូរវិធីសាស្ត្រ​បញ្ចូល"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"អស់​ទំហំ​ផ្ទុក"</string>
@@ -1746,7 +1743,7 @@
     <string name="color_inversion_feature_name" msgid="2672824491933264951">"ការបញ្ច្រាស​ពណ៌"</string>
     <string name="color_correction_feature_name" msgid="7975133554160979214">"ការកែតម្រូវ​ពណ៌"</string>
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"មុខងារប្រើដៃម្ខាង"</string>
-    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ពន្លឺតិចខ្លាំង"</string>
+    <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"ងងឹតខ្លាំង"</string>
     <string name="hearing_aids_feature_name" msgid="1125892105105852542">"ឧបករណ៍ជំនួយការស្ដាប់"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"បានសង្កត់​គ្រាប់ចុច​កម្រិតសំឡេង​ជាប់។ បាន​បើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string>
     <string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"បានសង្កត់​គ្រាប់ចុច​កម្រិតសំឡេង​ជាប់។ បាន​បិទ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"គ្រប់គ្រងដោយ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"បើក"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"បិទ"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ប្រតិទិនណាមួយ"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> កំពុង​បិទសំឡេង​មួយចំនួន"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"មានបញ្ហាខាងក្នុងឧបករណ៍របស់អ្នក ហើយវាអ្នកមិនមានស្ថេរភាព រហូតទាល់តែអ្នកកំណត់ដូចដើមវិញទាំងស្រុង។"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"មានបញ្ហាខាងក្នុងឧបករណ៍របស់អ្នក ទំនាក់ទំនងក្រុមហ៊ុនផលិតឧបករណ៍របស់អ្នកសម្រាប់ព័ត៌មានបន្ថែម។"</string>
@@ -1974,7 +1974,7 @@
     <string name="user_creation_account_exists" msgid="2239146360099708035">"អនុញ្ញាតឱ្យ <xliff:g id="APP">%1$s</xliff:g> បង្កើតអ្នកប្រើប្រាស់​ថ្មីដោយប្រើ <xliff:g id="ACCOUNT">%2$s</xliff:g> (អ្នកប្រើប្រាស់ដែលមានគណនីនេះមានរួចហើយ) ដែរឬទេ?"</string>
     <string name="user_creation_adding" msgid="7305185499667958364">"អនុញ្ញាតឱ្យ <xliff:g id="APP">%1$s</xliff:g> បង្កើតអ្នកប្រើប្រាស់​ថ្មីដោយប្រើ <xliff:g id="ACCOUNT">%2$s</xliff:g> ដែរឬទេ?"</string>
     <string name="supervised_user_creation_label" msgid="6884904353827427515">"បញ្ចូលអ្នកប្រើប្រាស់ដែលស្ថិតក្រោមការគ្រប់គ្រង"</string>
-    <string name="language_selection_title" msgid="52674936078683285">"បន្ថែមភាសា"</string>
+    <string name="language_selection_title" msgid="52674936078683285">"បញ្ចូលភាសា"</string>
     <string name="country_selection_title" msgid="5221495687299014379">"ចំណូលចិត្តតំបន់"</string>
     <string name="search_language_hint" msgid="7004225294308793583">"វាយបញ្ចូលឈ្មោះភាសា"</string>
     <string name="language_picker_section_suggested" msgid="6556199184638990447">"បាន​ណែនាំ"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"ការធ្វើ​តេស្ត"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"ទូទៅ"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"ភ្ជាប់ដោយស្វ័យប្រវត្តិទៅផ្កាយរណប"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"អ្នកអាចផ្ញើ និងទទួលសារដោយមិនប្រើបណ្តាញទូរសព្ទចល័ត ឬ Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"បើក​កម្មវិធី Messages"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index d93d9b8..faa46ba 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ಮೊಬೈಲ್‌ ನೆಟ್‌ವರ್ಕ್ ತಲುಪಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ಆದ್ಯತೆಗೊಳಿಸಿದ ನೆಟ್‌ವರ್ಕ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಪ್ರಯತ್ನಿಸಿ. ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್‌ ಮಾಡಿ."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ತುರ್ತು ಕರೆ ಮಾಡುವಿಕೆ ಲಭ್ಯವಿಲ್ಲ"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ತುರ್ತು ಕರೆಗಳಿಗೆ ಮೊಬೈಲ್ ನೆಟ್‌ವರ್ಕ್‌ನ ಅಗತ್ಯವಿದೆ"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"ಎಚ್ಚರಿಕೆಗಳು"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"ಕರೆ ಫಾರ್ವರ್ಡ್‌ ಮಾಡುವಿಕೆ"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"ತುರ್ತು ಕಾಲ್‌ಬ್ಯಾಕ್‌ ಮೋಡ್‌"</string>
@@ -616,7 +615,7 @@
     <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"ಕೀಲಾಕ್ ಮತ್ತು ಯಾವುದೇ ಸಂಬಂಧಿತ ಭದ್ರತಾ ಪಾಸ್‍‍ವರ್ಡ್ ಭದ್ರತೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್‍‍ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ. ಉದಾಹರಣೆಗೆ, ಒಳಬರುವ ಕರೆಯನ್ನು ಸ್ವೀಕರಿಸುವಾಗ ಕೀಲಾಕ್ ಅನ್ನು ಫೋನ್ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ, ನಂತರ ಕರೆಯು ಅಂತ್ಯಗೊಂಡಾಗ ಕೀಲಾಕ್ ಅನ್ನು ಮರು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ."</string>
     <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಸಂಕೀರ್ಣತೆಯನ್ನು ವಿನಂತಿಸಿ"</string>
     <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"ಆ್ಯಪ್‌ಗೆ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಸಂಕೀರ್ಣತೆ ಮಟ್ಟವನ್ನು (ಅಧಿಕ, ಮಧ್ಯಮ, ಕಡಿಮೆ ಅಥವಾ ಯಾವುದೂ ಅಲ್ಲ) ತಿಳಿದುಕೊಳ್ಳಲು ಅನುಮತಿಸುತ್ತದೆ, ಅದು ಉದ್ದದ ಸಂಭವನೀಯ ಶ್ರೇಣಿ ಮತ್ತು ಸ್ಕ್ರೀನ್ ಲಾಕ್‌ನ ವಿಧವನ್ನು ಸೂಚಿಸುತ್ತದೆ. ಬಳಕೆದಾರರು ನಿರ್ದಿಷ್ಟ ಹಂತದವರೆಗೆ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಬಹುದು, ಆದರೆ ಅವರು ಅದನ್ನು ನಿರ್ಲಕ್ಷಿಸಬಹುದು ಮತ್ತು ಅದರಿಂದ ಹೊರಬರಬಹುದು ಎಂಬುದನ್ನು ಸಹ ಆ್ಯಪ್ ಬಳಕೆದಾರರಿಗೆ ಸೂಚಿಸುತ್ತದೆ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಪಠ್ಯದ ರೂಪದಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವುದಿಲ್ಲ, ಇದರಿಂದಾಗಿ ಆ್ಯಪ್‌ಗೆ ಸರಿಯಾದ ಪಾಸ್‌ವರ್ಡ್ ಗೊತ್ತಿರುವುದಿಲ್ಲ ಎಂಬುದನ್ನು ಗಮನಿಸಿ."</string>
-    <string name="permlab_postNotification" msgid="4875401198597803658">"ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸಿ"</string>
+    <string name="permlab_postNotification" msgid="4875401198597803658">"ನೋಟಿಫಿಕೇಶನ್‌ಗಳನ್ನು ತೋರಿಸಿ"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸಲು ಆ್ಯಪ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ"</string>
     <string name="permlab_turnScreenOn" msgid="219344053664171492">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಆನ್ ಮಾಡಿ"</string>
     <string name="permdesc_turnScreenOn" msgid="4394606875897601559">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಆನ್ ಮಾಡಲು ಆ್ಯಪ್ ಅನ್ನು ಅನುಮತಿಸುತ್ತದೆ."</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"ಅಳಿಸಿ"</string>
     <string name="inputMethod" msgid="1784759500516314751">"ಇನ್‌ಪುಟ್ ವಿಧಾನ"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"ಪಠ್ಯದ ಕ್ರಮಗಳು"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"ಈ ಫೀಲ್ಡ್‌ನಲ್ಲಿ ಕೈಬರಹವನ್ನು ಬೆಂಬಲಿಸಲಾಗುವುದಿಲ್ಲ"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"ಪಾಸ್‌ವರ್ಡ್ ಫೀಲ್ಡ್‌ಗಳಲ್ಲಿ ಕೈಬರಹವನ್ನು ಬೆಂಬಲಿಸಲಾಗುವುದಿಲ್ಲ"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"ಹಿಂದಕ್ಕೆ"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"ಇನ್‌ಪುಟ್ ವಿಧಾನವನ್ನು ಬದಲಿಸಿ"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"ಸಂಗ್ರಹಣೆ ಸ್ಥಳವು ತುಂಬಿದೆ"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಮೂಲಕ ನಿರ್ವಹಿಸಲಾಗಿದೆ"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ಆನ್ ಆಗಿದೆ"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ಆಫ್ ಆಗಿದೆ"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ಯಾವುದೇ ಕ್ಯಾಲೆಂಡರ್"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ಧ್ವನಿ ಮ್ಯೂಟ್ ಮಾಡುತ್ತಿದ್ದಾರೆ"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಂತರಿಕ ಸಮಸ್ಯೆಯಿದೆ ಹಾಗೂ ನೀವು ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾವನ್ನು ರೀಸೆಟ್ ಮಾಡುವವರೆಗೂ ಅದು ಅಸ್ಥಿರವಾಗಬಹುದು."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಂತರಿಕ ಸಮಸ್ಯೆಯಿದೆ. ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ತಯಾರಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
@@ -1977,7 +1977,7 @@
     <string name="language_selection_title" msgid="52674936078683285">"ಭಾಷೆ ಸೇರಿಸಿ"</string>
     <string name="country_selection_title" msgid="5221495687299014379">"ಪ್ರದೇಶ ಪ್ರಾಶಸ್ತ್ಯ"</string>
     <string name="search_language_hint" msgid="7004225294308793583">"ಭಾಷೆ ಹೆಸರನ್ನು ಟೈಪ್ ಮಾಡಿ"</string>
-    <string name="language_picker_section_suggested" msgid="6556199184638990447">"ಸೂಚಿತ ಭಾಷೆ"</string>
+    <string name="language_picker_section_suggested" msgid="6556199184638990447">"ಸೂಚಿತ ಭಾಷೆಗಳು"</string>
     <string name="language_picker_regions_section_suggested" msgid="6080131515268225316">"ಸೂಚಿಸಲಾಗಿರುವುದು"</string>
     <string name="language_picker_section_suggested_bilingual" msgid="5932198319583556613">"ಸೂಚಿಸಲಾದ ಭಾಷೆಗಳು"</string>
     <string name="region_picker_section_suggested_bilingual" msgid="704607569328224133">"ಸೂಚಿಸಲಾದ ಪ್ರದೇಶಗಳು"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"ಪರೀಕ್ಷೆ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"ಸಮುದಾಯ"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"ಸ್ಯಾಟಲೈಟ್‌ಗೆ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಕನೆಕ್ಟ್ ಆಗಿದೆ"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"ನೀವು ಮೊಬೈಲ್ ಅಥವಾ ವೈ-ಫೈ ನೆಟ್‌ವರ್ಕ್ ಇಲ್ಲದೆಯೇ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬಹುದು ಮತ್ತು ಸ್ವೀಕರಿಸಬಹುದು"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ಅನ್ನು ತೆರೆಯಿರಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index fd15f81..9eaa414 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"모바일 네트워크에 연결할 수 없습니다."</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"기본 네트워크를 변경해 보세요. 탭하여 변경할 수 있습니다."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"긴급 전화를 사용할 수 없습니다."</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"긴급 전화를 걸려면 모바일 네트워크 연결이 필요함"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"알림"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"착신전환"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"긴급 콜백 모드"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"삭제"</string>
     <string name="inputMethod" msgid="1784759500516314751">"입력 방법"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"텍스트 작업"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"이 입력란은 필기 입력을 지원하지 않습니다."</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"비밀번호 입력란은 필기 입력을 지원하지 않습니다."</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"뒤로"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"입력 방법 전환"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"저장 공간이 부족함"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"관리자: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"사용"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"사용 중지"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>~<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"모든 캘린더"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>(이)가 일부 소리를 음소거함"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"사용 중인 기기 내부에 문제가 발생했습니다. 초기화할 때까지 불안정할 수 있습니다."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"사용 중인 기기 내부에 문제가 발생했습니다. 자세한 내용은 제조업체에 문의하세요."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"테스트"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"공동"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"위성에 자동 연결됨"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"모바일 또는 Wi-Fi 네트워크 없이 메시지를 주고 받을 수 있습니다"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"메시지 열기"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 13c94d1..9efccff 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Мобилдик тармакка туташпай жатат"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Тандалган тармакты өзгөртүп көрүңүз. Өзгөртүү үчүн таптаңыз."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Шашылыш чалуу жеткиликсиз"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Шашылыш чалуу үчүн мобилдик тармак талап кылынат"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Шашылыш билдирүүлөр"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Чалууну башка номерге багыттоо"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Шашылыш кайра чалуу режими"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Өчүрүү"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Киргизүү ыкмасы"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Текст боюнча иштер"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Бул талаада жазып киргизүү колдоого алынбайт"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Сырсөз талаасында жазып киргизүү колдоого алынбайт"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Артка"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Киргизүү ыкмасын өзгөртүү"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Сактагычта орун калбай баратат"</string>
@@ -1286,7 +1283,7 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Колдонмолорду иштетип баштоо"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Жүктөлүүдө"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Кубат баскычын бастыңыз — адатта, бул экранды өчүрөт.\n\nМанжаңыздын изин жөндөп жатканда аны акырын басып көрүңүз."</string>
-    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Кошуп бүтүрүү үчүн экранды өчүрүңүз"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Бүтүрүү үчүн экранды өчүрүңүз"</string>
     <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Өчүрүү"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Манжаңыздын изин ырастоону улантасызбы?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Кубат баскычын бастыңыз — адатта, бул экранды өчүрөт.\n\nМанжаңыздын изин ырастоо үчүн аны акырын басып көрүңүз."</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> башкарат"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Күйүк"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Өчүк"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>, <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Бардык жылнаамалар"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> айрым үндөрдү өчүрүүдө"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Түзмөгүңүздө ички көйгөй бар жана ал баштапкы абалга кайтарылмайынча туруктуу иштебей коюшу мүмкүн."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Түзмөгүңүздө ички көйгөй бар. Анын чоо-жайын билүү үчүн өндүрүүчүңүзгө кайрылыңыз."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Сыноо"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Жалпы"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Спутникке автоматтык түрдө туташтырылган"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Сиз мобилдик же Wi-Fi тармагы жок эле билдирүүлөрдү жөнөтүп, ала аласыз"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Жазышуулар колдонмосун ачуу"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 4b78b08..752e68e 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ບໍ່ສາມາດຕິດຕໍ່ເຄືອຂ່າຍມືຖືໄດ້"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ໃຫ້ລອງປ່ຽນເຄືອຂ່າຍທີ່ຕ້ອງການ. ແຕະເພື່ອປ່ຽນ."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ບໍ່ສາມາດໃຊ້ການໂທສຸກເສີນໄດ້"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ໂທ​ສຸກ​ເສີນຕ້ອງໃຊ້ເຄືອຂ່າຍມືຖື"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"ການເຕືອນ"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"ການໂອນສາຍ"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"ໂໝດໂທກັບສຸກເສີນ"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"ລຶບ"</string>
     <string name="inputMethod" msgid="1784759500516314751">"ຮູບແບບການປ້ອນຂໍ້ມູນ"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"ການເຮັດວຽກຂອງຂໍ້ຄວາມ"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"ການຂຽນດ້ວຍມືບໍ່ຖືກຮອງຮັບໃນຊ່ອງຂໍ້ມູນນີ້"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"ການຂຽນດ້ວຍມືບໍ່ຖືກຮອງຮັບໃນຊ່ອງຂໍ້ມູນລະຫັດຜ່ານ"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"ກັບຄືນ"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"ສະຫຼັບວິທີການປ້ອນຂໍ້ມູນ"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"ພື້ນທີ່ຈັດເກັບຂໍ້ມູນກຳລັງຈະເຕັມ"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"ຈັດການໂດຍ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ເປີດຢູ່"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ປິດຢູ່"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ປະ​ຕິ​ທິນ​ໃດ​ກໍໄດ້"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ປິດສຽງບາງຢ່າງໄວ້"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"ມີ​ບັນ​ຫາ​ພາຍ​ໃນ​ກັບ​ອຸ​ປະ​ກອນ​ຂອງ​ທ່ານ, ແລະ​ມັນ​ອາດ​ຈະ​ບໍ່​ສະ​ຖຽນ​ຈົນ​ກວ່າ​ທ່ານ​ຕັ້ງ​ເປັນ​ຂໍ້​ມູນ​ໂຮງ​ງານ​ຄືນ​ແລ້ວ."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"ມີ​ບັນ​ຫາ​ພາຍ​ໃນ​ກັບ​ອຸ​ປະ​ກອນ​ຂອງ​ທ່ານ. ຕິດ​ຕໍ່ຜູ້​ຜະ​ລິດ​ຂອງ​ທ່ານ​ສຳ​ລັບ​ລາຍ​ລະ​ອຽດ​ຕ່າງໆ."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"ທົດສອບ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"ສ່ວນກາງ"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"ເຊື່ອມຕໍ່ກັບດາວທຽມໂດຍອັດຕະໂນມັດ"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"ທ່ານສາມາດສົ່ງ ແລະ ຮັບຂໍ້ຄວາມໂດຍບໍ່ຕ້ອງໃຊ້ເຄືອຂ່າຍມືຖື ຫຼື Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"ເປີດ Messages"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 46d69c7..2fd6ded 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -86,8 +86,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nepavyko pasiekti mobiliojo ryšio tinklo"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Pabandykite pakeisti pageidaujamą tinklą. Palieskite, kad pakeistumėte."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Skambučių pagalbos numeriu paslauga nepasiekiama"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Kad būtų galima skambinti pagalbos numeriais, būtina naudoti mobiliojo ryšio tinklą"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Įspėjimai"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Skambučio peradresavimas"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Atskambinimo pagalbos numeriu režimas"</string>
@@ -1186,10 +1185,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Ištrinti"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Įvesties būdas"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Teksto veiksmai"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Rašymas ranka nepalaikomas šiame lauke"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Rašymas ranka nepalaikomas slaptažodžių laukuose"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Atgal"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Perjungti įvesties metodą"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Mažėja laisvos saugyklos vietos"</string>
@@ -1934,6 +1931,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Tvarko „<xliff:g id="APP_NAME">%1$s</xliff:g>“"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Įjungti"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Išjungti"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bet kuris kalendorius"</string>
     <string name="muted_by" msgid="91464083490094950">"„<xliff:g id="THIRD_PARTY">%1$s</xliff:g>“ nutildo kai kuriuos garsus"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Iškilo vidinė su jūsų įrenginiu susijusi problema, todėl įrenginys gali veikti nestabiliai, kol neatkursite gamyklinių duomenų."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Iškilo vidinė su jūsų įrenginiu susijusi problema. Jei reikia išsamios informacijos, susisiekite su gamintoju."</string>
@@ -2396,6 +2396,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Bandymas"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Bendruomenės"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automatiškai prisijungta prie palydovinio ryšio"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Galite siųsti ir gauti pranešimus be mobiliojo ryšio ar „Wi-Fi“ tinklo"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Atidaryti programą „Messages“"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 7ddeb4c..066cd4b 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nevar sasniegt mobilo tīklu"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Mēģiniet nomainīt vēlamo tīklu. Pieskarieties, lai to mainītu."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Nav pieejami ārkārtas izsaukumi"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Lai veiktu ārkārtas zvanus, ir nepieciešams mobilais tīkls."</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Brīdinājumi"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Zvanu pāradresācija"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Ārkārtas atzvana režīms"</string>
@@ -829,7 +828,7 @@
     <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"Atļauj lietotnei atjaunināt citām lietotnēm piederošu E2EE sakaru atslēgu verifikācijas statusus."</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Paroles kārtulu iestatīšana"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Kontrolēt ekrāna bloķēšanas paroļu un PIN garumu un tajos atļautās rakstzīmes."</string>
-    <string name="policylab_watchLogin" msgid="7599669460083719504">"Ekrāna atbloķēšanas mēģinājumu pārraudzīšana"</string>
+    <string name="policylab_watchLogin" msgid="7599669460083719504">"Pārraudzīt ekrāna atbloķēšanas mēģinājumus"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Pārrauga nepareizi ievadīto paroļu skaitu, atbloķējot ekrānu, un bloķē planšetdatoru vai dzēš visus planšetdatora datus, ja tiek ievadīts pārāk daudz nepareizu paroļu."</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Pārraudzīt nepareizi ievadīto ekrāna atbloķēšanas paroļu skaitu un bloķēt Android TV vai dzēst visus Android TV ierīces datus, ja tiek ievadīts pārāk daudz nepareizu paroļu."</string>
     <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Ekrāna atbloķēšanas laikā pārraudzīt nepareizi ievadīto paroļu skaitu un bloķēt informatīvi izklaidējošo sistēmu vai dzēst visus informatīvi izklaidējošās sistēmas datus, ja tiek ievadīts pārāk daudz nepareizu paroļu."</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Dzēst"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Ievades metode"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Teksta darbības"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Šajā laukā netiek atbalstīta rokraksta funkcija."</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Paroļu laukā netiek atbalstīta rokraksta funkcija."</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Atpakaļ"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Pārslēgt ievades metodi"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Paliek maz brīvas vietas"</string>
@@ -1933,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Pārvalda <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Ieslēgta"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Izslēgta"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Jebkurš kalendārs"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> izslēdz noteiktas skaņas"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Jūsu ierīcē ir radusies iekšēja problēma, un ierīce var darboties nestabili. Lai to labotu, veiciet rūpnīcas datu atiestatīšanu."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Jūsu ierīcē ir radusies iekšēja problēma. Lai iegūtu plašāku informāciju, lūdzu, sazinieties ar ražotāju."</string>
@@ -2395,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Testēšanai"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Kopīgs"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automātiski izveidots savienojums ar satelītu"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Varat sūtīt un saņemt ziņojumus bez mobilā vai Wi-Fi tīkla."</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Atvērt lietotni Ziņojumi"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 4bef670..a8d5ea4 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Мобилната мрежа е недостапна"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Сменете ја претпочитаната мрежа. Допрете за промена."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Итните повици се недостапни"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"За итните повици е потребна мобилна мрежа"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Предупредувања"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Проследување повик"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Режим на итен повратен повик"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Избриши"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Метод на внес"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Дејства со текст"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Ракописот не е поддржан во полево"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Ракописот не е поддржан во полињата за лозинка"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Назад"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Префрлете го методот за внесување"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Капацитетот е речиси полн"</string>
@@ -1308,7 +1305,7 @@
     <string name="dump_heap_ready_text" msgid="5849618132123045516">"Слика од меморијата на <xliff:g id="PROC">%1$s</xliff:g> ви е достапна за споделување. Бидете внимателни: оваа слика од меморијата можеби ги содржи сите чувствителни лични информации до коишто процесот има пристап, што може да вклучуваат работи што сте ги напишале."</string>
     <string name="sendText" msgid="493003724401350724">"Избери дејство за текст"</string>
     <string name="volume_ringtone" msgid="134784084629229029">"Јачина на звук на ѕвонче"</string>
-    <string name="volume_music" msgid="7727274216734955095">"Јачина на аудио/видео звук"</string>
+    <string name="volume_music" msgid="7727274216734955095">"Јачина на звук за аудио/видео"</string>
     <string name="volume_music_hint_playing_through_bluetooth" msgid="2614142915948898228">"Се репродуцира преку Bluetooth"</string>
     <string name="volume_music_hint_silent_ringtone_selected" msgid="1514829655029062233">"Поставено ѕвонење на тивко"</string>
     <string name="volume_call" msgid="7625321655265747433">"Јачина на звук на дојдовен повик"</string>
@@ -1319,7 +1316,7 @@
     <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Јачина на звук на Bluetooth"</string>
     <string name="volume_icon_description_ringer" msgid="2187800636867423459">"Јачина на звук на мелодија"</string>
     <string name="volume_icon_description_incall" msgid="4491255105381227919">"Јачина на звук на повик"</string>
-    <string name="volume_icon_description_media" msgid="4997633254078171233">"Јачина на аудио/видео звук"</string>
+    <string name="volume_icon_description_media" msgid="4997633254078171233">"Јачина на звук за аудио/видео"</string>
     <string name="volume_icon_description_notification" msgid="579091344110747279">"Јачина на звук за известување"</string>
     <string name="ringtone_default" msgid="9118299121288174597">"Стандардна мелодија"</string>
     <string name="ringtone_default_with_actual" msgid="2709686194556159773">"Стандардна (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Управувано од <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Вклучено"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Исклучено"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Кој било календар"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> исклучи некои звуци"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Настана внатрешен проблем со уредот и може да биде нестабилен сè додека не ресетирате на фабричките податоци."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Настана внатрешен проблем со уредот. Контактирајте го производителот за детали."</string>
@@ -1992,7 +1992,7 @@
     <string name="work_mode_turn_on" msgid="5316648862401307800">"Прекини ја паузата"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Итен случај"</string>
     <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Поставете заклучување екран"</string>
-    <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Поставување заклучување екран"</string>
+    <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Поставете заклучување екран"</string>
     <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"За да користите „Приватен простор“, поставете заклучување екран на уредов"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Апликацијата не е достапна"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> не е достапна во моментов."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Профил за тестирање"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Профил на заедницата"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Поврзано со сателит автоматски"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Може да испраќате и примате пораки без мобилна или Wi-Fi мрежа"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Отворете ја Messages"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 70aeadd..32f2daf 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"മൊബൈൽ നെറ്റ്‌വർക്കിലേക്ക് കണക്റ്റ് ചെയ്യാനാവുന്നില്ല"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"തിര‌ഞ്ഞെടുത്ത നെറ്റ്‌വർക്ക് മാറ്റുന്നത് പരീക്ഷിക്കുക. മാറ്റാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"എമർജൻസി കോളിംഗ് ലഭ്യമല്ല"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"എമർജൻസി കോളുകൾ ചെയ്യാൻ ഒരു മൊബൈൽ നെറ്റ്‌വർക്ക് ആവശ്യമാണ്"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"അലേർട്ടുകൾ"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"കോൾ ഫോർവേഡിംഗ്"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"അടിയന്തര കോൾബാക്ക് മോഡ്"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"ഇല്ലാതാക്കുക"</string>
     <string name="inputMethod" msgid="1784759500516314751">"ടൈപ്പുചെയ്യൽ രീതി"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"ടെക്‌സ്‌റ്റ് പ്രവർത്തനങ്ങൾ"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"ഈ ഫീൽഡിൽ കയ്യെഴുത്ത് പിന്തുണയ്ക്കുന്നില്ല"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"പാസ്‍വേഡ് ഫീൽഡുകളിൽ കയ്യെഴുത്ത് പിന്തുണയ്ക്കുന്നില്ല"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"മടങ്ങുക"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"ഇൻപുട്ട് രീതി മാറുക"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"സംഭരണയിടം കഴിഞ്ഞു"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യുന്നത്"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ഓണാണ്"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ഓഫാണ്"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"എല്ലാ കലണ്ടറിലും"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ചില ശബ്‌ദങ്ങൾ മ്യൂട്ട് ചെയ്യുന്നു"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"നിങ്ങളുടെ ഉപകരണത്തിൽ ഒരു ആന്തരിക പ്രശ്‌നമുണ്ട്, ഫാക്‌ടറി വിവര പുനഃസജ്ജീകരണം ചെയ്യുന്നതുവരെ ഇതു അസ്ഥിരമായിരിക്കാനിടയുണ്ട്."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"നിങ്ങളുടെ ഉപകരണത്തിൽ ഒരു ആന്തരിക പ്രശ്‌നമുണ്ട്. വിശദാംശങ്ങൾക്കായി നിർമ്മാതാവിനെ ബന്ധപ്പെടുക."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"ടെസ്‌റ്റ്"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"കമ്മ്യൂണൽ"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"സാറ്റലൈറ്റിലേക്ക് സ്വയമേവ കണക്റ്റ് ചെയ്തു"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"മൊബൈലോ വൈഫൈ നെറ്റ്‌വർക്കോ ഇല്ലാതെ തന്നെ സന്ദേശങ്ങൾ അയയ്‌ക്കാനും സ്വീകരിക്കാനും നിങ്ങൾക്ക് കഴിയും"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages തുറക്കുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index adb1f87..a926e60 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Мобайл сүлжээнд холбогдох боломжгүй байна"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Сонгосон сүлжээг өөрчлөхөөр оролдоно уу. Өөрчлөхийн тулд товшино уу."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Яаралтай дуудлага хийх боломжгүй"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Яаралтай дуудлагуудад мобайл сүлжээ шаардлагатай"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Сануулга"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Дуудлага шилжүүлэх"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Яаралтай дуудлага хийх горим"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Устгах"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Оруулах арга"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Текст үйлдэл"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Гараар бичихийг энэ талбарт дэмждэггүй"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Гараар бичихийг нууц үгний талбаруудад дэмждэггүй"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Буцах"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Оруулах аргыг сэлгэх"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Сангийн хэмжээ дутагдаж байна"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g>-с удирддаг"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Асаалттай"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Унтраалттай"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Дурын календарь"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> зарим дууны дууг хааж байна"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Таны төхөөрөмжид дотоод алдаа байна.Та төхөөрөмжөө үйлдвэрээс гарсан төлөвт шилжүүлэх хүртэл таны төхөөрөмж чинь тогтворгүй байж болох юм."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Таны төхөөрөмжид дотоод алдаа байна. Дэлгэрэнгүй мэдээлэл авахыг хүсвэл үйлдвэрлэгчтэйгээ холбоо барина уу."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Туршилт"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Нийтийн"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Хиймэл дагуулд автоматаар холбогдсон"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Та мобайл эсвэл Wi-Fi сүлжээгүйгээр мессеж илгээх болон хүлээн авах боломжтой"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Мессежийг нээх"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 393f95e..c10b741 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"मोबाइल नेटवर्क उपलब्ध नाही"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"प्राधान्य दिलेले नेटवर्क बदलण्याचा प्रयत्न करा. बदलण्यासाठी टॅप करा."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"आणीबाणी कॉलिंग अनुपलब्ध"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"आणीबाणी कॉलसाठी मोबाइल नेटवर्क आवश्यक आहे"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"अलर्ट"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"कॉल फॉरवर्डिंग"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"इमर्जन्सी कॉलबॅक मोड"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"हटवा"</string>
     <string name="inputMethod" msgid="1784759500516314751">"इनपुट पद्धत"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"मजकूर क्रिया"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"या फील्डमध्ये हस्तलेखनला सपोर्ट नाही"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"पासवर्ड फील्डमध्ये हस्तलेखनला सपोर्ट नाही"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"मागे जा"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"इनपुट पद्धत स्विच करा"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"संचयन स्थान संपत आहे"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> द्वारे व्यवस्थापित"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"सुरू आहे"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"बंद आहे"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"कोणतेही कॅलेंडर"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> काही ध्‍वनी म्‍यूट करत आहे"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"आपल्‍या डिव्‍हाइसमध्‍ये अंतर्गत समस्‍या आहे आणि तुमचा फॅक्‍टरी डेटा रीसेट होईपर्यंत ती अस्‍थिर असू शकते."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"आपल्‍या डिव्‍हाइसमध्‍ये अंतर्गत समस्‍या आहे. तपशीलांसाठी आपल्‍या निर्मात्याशी संपर्क साधा."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"चाचणी"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"सामुदायिक"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"उपग्रहाशी आपोआप कनेक्ट केलेले आहे"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"तुम्ही मोबाइल किंवा वाय-फाय नेटवर्कशिवाय मेसेज पाठवू आणि मिळवू शकता"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages उघडा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 9274c51..4a4ea88 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Tidak dapat mencapai rangkaian mudah alih"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Cuba tukar rangkaian pilihan. Ketik untuk menukar."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Panggilan kecemasan tidak tersedia"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Rangkaian mudah alih diperlukan untuk membuat panggilan kecemasan"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Makluman"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Pemajuan panggilan"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Mod paggil balik kecemasan"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Padam"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Kaedah input"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Tindakan teks"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Tulisan tangan tidak disokong dalam medan ini"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Tulisan tangan tidak disokong dalam medan kata laluan"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Kembali"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Tukar kaedah masukan"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Ruang storan semakin berkurangan"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Diurus oleh <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Hidup"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Mati"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Sebarang kalendar"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> meredamkan sesetengah bunyi"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Terdapat masalah dalaman dengan peranti anda. Peranti mungkin tidak stabil sehingga anda membuat tetapan semula data kilang."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Terdapat masalah dalaman dengan peranti anda. Hubungi pengilang untuk mengetahui butirannya."</string>
@@ -1993,7 +1993,7 @@
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Kecemasan"</string>
     <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Tetapkan kunci skrin"</string>
     <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Tetapkan kunci skrin"</string>
-    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Tetapkan kunci skrin pada peranti untuk guna ruang privasi"</string>
+    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Tetapkan kunci skrin pada peranti untuk menggunakan ruang privasi"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Apl tidak tersedia"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak tersedia sekarang."</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> tidak tersedia"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Ujian"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Umum"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Disambungkan secara automatik kepada satelit"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Anda boleh menghantar dan menerima mesej tanpa rangkaian mudah alih atau Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buka Messages"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 9e3ec9e..8346134 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"မိုဘိုင်းကွန်ရက် လိုင်းမရပါ"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ဦးစားပေးကွန်ရက်သို့ ပြောင်းကြည့်ပါ။ ပြောင်းရန် တို့ပါ။"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"အရေးပေါ်ခေါ်ဆိုမှု မရနိုင်ပါ"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"အရေးပေါ်ဖုန်းခေါ်ရန် မိုဘိုင်းကွန်ရက် လိုအပ်သည်"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"သတိပေးချက်များ"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"အဝင်ခေါ်ဆိုမှုအား ထပ်ဆင့်ပို့ခြင်း"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"အရေးပေါ် ပြန်လည်ခေါ်ဆိုနိုင်သောမုဒ်"</string>
@@ -828,7 +827,7 @@
     <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"အခြားအက်ပ်များ ပိုင်ဆိုင်သော E2EE အဆက်အသွယ်ကီးများ၏ အတည်ပြုခြင်းအခြေအနေများကို အက်ပ်အား အပ်ဒိတ်လုပ်ခွင့်ပြုသည်"</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"စကားဝှက်စည်းမျဥ်းကိုသတ်မှတ်ရန်"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"မျက်နှာပြင်သော့ခတ်သည့် စကားဝှက်များနှင့် PINများရှိ ခွင့်ပြုထားသည့် စာလုံးအရေအတွက်နှင့် အက္ခရာများအား ထိန်းချုပ်ရန်။"</string>
-    <string name="policylab_watchLogin" msgid="7599669460083719504">"မျက်နှာပြင်လော့ခ်ဖွင့်ရန် ကြိုးပမ်းမှုများကို စောင့်ကြည့်ပါ"</string>
+    <string name="policylab_watchLogin" msgid="7599669460083719504">"မျက်နှာပြင်လော့ခ်ဖွင့်ရန် ကြိုးပမ်းမှုများကို စောင့်ကြည့်ခြင်း"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"မျက်နှာပြင်ကို သော့ဖွင့်ရန် အတွက် စကားဝှက် မမှန်မကန် ထည့်သွင်းမှု အရေအတွက်ကို စောင့်ကြည့်လျက်၊ စကားဝှက် ရိုက်ထည့်မှု သိပ်များနေလျှင် တက်ဘလက်ကို သော့ခတ်ရန် သို့မဟုတ် တက်ဘလက် ဒေတာ အားလုံးကို ဖျက်ရန်။"</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"မျက်နှာပြင်ကို လော့ခ်ဖွင့်သည့်အခါ စကားဝှက်မှားယွင်းစွာ ရိုက်သွင်းသည့်အကြိမ်ရေကို စောင့်ကြည့်ပြီး မှားယွင်းသည့်အကြိမ်ရေ အလွန်များလာပါက သင့် Android TV စက်ပစ္စည်းကို လော့ခ်ချခြင်း သို့မဟုတ် သင့် Android TV ရှိ အသုံးပြုသူဒေတာများအားလုံးကို ဖျက်ခြင်းတို့ ပြုလုပ်သွားပါမည်။"</string>
     <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"ဖန်သားပြင်လော့ခ်ဖွင့်ရန် အတွက် စကားဝှက် မမှန်မကန် ထည့်သွင်းမှု အရေအတွက်ကို စောင့်ကြည့်လျက် စကားဝှက် မမှန်မကန် ရိုက်ထည့်မှု များနေလျှင် သတင်းနှင့်ဖျော်ဖြေရေး စနစ်ကို လော့ခ်ချသည် (သို့) ၎င်း၏ ဒေတာအားလုံးကို ဖျက်သည်။"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"ဖျက်ရန်"</string>
     <string name="inputMethod" msgid="1784759500516314751">"ထည့်သွင်းရန်နည်းလမ်း"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"စာတို လုပ်ဆောင်ချက်"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"ဤအကွက်တွင် လက်ရေးကို မပံ့ပိုးပါ"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"စကားဝှက်အကွက်များတွင် လက်ရေးကို မပံ့ပိုးပါ"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"နောက်သို့"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"လက်ကွက်ပြောင်းရန်"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"သိမ်းဆည်သော နေရာ နည်းနေပါသည်"</string>
@@ -1903,8 +1900,8 @@
     <string name="package_updated_device_owner" msgid="7560272363805506941">"သင်၏ စီမံခန့်ခွဲသူက အပ်ဒိတ်လုပ်ထားသည်"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"သင်၏ စီမံခန့်ခွဲသူက ဖျက်လိုက်ပါပြီ"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
-    <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"‘ဘက်ထရီ အားထိန်း’ က ‘အမှောင်နောက်ခံ’ ကို ဖွင့်ပြီး နောက်ခံလုပ်ဆောင်ချက်၊ ပြသမှုဆိုင်ရာ အထူးပြုလုပ်ချက်အချို့၊ ဝန်ဆောင်မှုအချို့နှင့် ကွန်ရက်ချိတ်ဆက်မှုအချို့တို့ကို ကန့်သတ်သည် သို့မဟုတ် ပိတ်သည်။"</string>
-    <string name="battery_saver_description" msgid="8518809702138617167">"‘ဘက်ထရီ အားထိန်း’ က ‘အမှောင်နောက်ခံ’ ကို ဖွင့်ပြီး နောက်ခံလုပ်ဆောင်ချက်၊ ပြသမှုဆိုင်ရာ အထူးပြုလုပ်ချက်အချို့၊ ဝန်ဆောင်မှုအချို့နှင့် ကွန်ရက်ချိတ်ဆက်မှုအချို့တို့ကို ကန့်သတ်သည် သို့မဟုတ် ပိတ်သည်။"</string>
+    <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"‘ဘက်ထရီ အားထိန်း’ က ‘အမှောင်နောက်ခံ’ ကို ဖွင့်ပြီး နောက်ခံလုပ်ဆောင်ချက်၊ ဖန်တီးပြသချက်အချို့၊ ဝန်ဆောင်မှုအချို့နှင့် ကွန်ရက်ချိတ်ဆက်မှုအချို့တို့ကို ကန့်သတ်သည် သို့မဟုတ် ပိတ်သည်။"</string>
+    <string name="battery_saver_description" msgid="8518809702138617167">"‘ဘက်ထရီ အားထိန်း’ က ‘အမှောင်နောက်ခံ’ ကို ဖွင့်ပြီး နောက်ခံလုပ်ဆောင်ချက်၊ ဖန်တီးပြသချက်အချို့၊ ဝန်ဆောင်မှုအချို့နှင့် ကွန်ရက်ချိတ်ဆက်မှုအချို့တို့ကို ကန့်သတ်သည် သို့မဟုတ် ပိတ်သည်။"</string>
     <string name="data_saver_description" msgid="4995164271550590517">"ဒေတာအသုံးလျှော့ချနိုင်ရန်အတွက် အက်ပ်များကို နောက်ခံတွင် ဒေတာပို့ခြင်းနှင့် လက်ခံခြင်းမပြုရန် \'ဒေတာချွေတာမှု\' စနစ်က တားဆီးထားပါသည်။ ယခုအက်ပ်ဖြင့် ဒေတာအသုံးပြုနိုင်သော်လည်း အကြိမ်လျှော့၍သုံးရပါမည်။ ဥပမာ၊ သင်က မတို့မချင်း ပုံများပေါ်လာမည် မဟုတ်ပါ။"</string>
     <string name="data_saver_enable_title" msgid="7080620065745260137">"ဒေတာချွေတာမှုစနစ် ဖွင့်မလား။"</string>
     <string name="data_saver_enable_button" msgid="4399405762586419726">"ဖွင့်ရန်"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> က စီမံသည်"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ဖွင့်"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ပိတ်"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"၊ "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"မည်သည့်ပြက္ခဒိန်မဆို"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> သည် အချို့အသံကို ပိတ်နေသည်"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေပြီး၊ မူလစက်ရုံထုတ်အခြေအနေအဖြစ် ပြန်လည်ရယူနိုင်သည်အထိ အခြေအနေမတည်ငြိမ်နိုင်ပါ။"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေ၏။ အသေးစိတ်သိရန်အတွက် ပစ္စည်းထုတ်လုပ်သူအား ဆက်သွယ်ပါ။"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"စမ်းသပ်မှု"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"အများသုံး"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"ဂြိုဟ်တုနှင့် အလိုအလျောက် ချိတ်ဆက်ထားသည်"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"မိုဘိုင်း (သို့) Wi-Fi ကွန်ရက်မရှိဘဲ မက်ဆေ့ဂျ်များကို ပို့နိုင်၊ လက်ခံနိုင်သည်"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ဖွင့်ရန်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 551b4d5..252b413 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Får ikke kontakt med mobilnettverket"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Prøv å endre foretrukket nettverk. Trykk for å endre."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Nødanrop er utilgjengelig"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Du må være koblet til et mobilnettverk for å utføre nødanrop"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Varsler"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Viderekobling"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modusen nødsamtale-tilbakeringing"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Slett"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Inndatametode"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Teksthandlinger"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Håndskrift støttes ikke i dette feltet"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Håndskrift støttes ikke i passordfelt"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Tilbake"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Bytt inndatametode"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Lite ledig lagringsplass"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Administreres av <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"På"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Av"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Hvilken som helst kalender"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> slår av noen lyder"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Det har oppstått et internt problem på enheten din, og den kan være ustabil til du tilbakestiller den til fabrikkdata."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Det har oppstått et internt problem på enheten din. Ta kontakt med produsenten for mer informasjon."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Felles"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automatisk tilkoblet satellitt"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kan sende og motta meldinger uten mobil- eller wifi-nettverk"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Åpne Meldinger"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 24426eb..6035bb1 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"मोबाइल नेटवर्कमाथि पहुँच राख्न सकिएन"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"रुचाइएको नेटवर्क परिवर्तन गरी हेर्नुहोस्‌। परिवर्तन गर्न ट्याप गर्नुहोस्‌।"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"आपत्‌कालीन कल सेवा अनुपलब्ध छ"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"आपत्कालीन कलहरू गर्न मोबाइल नेटवर्क चाहिन्छ"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"अलर्टहरू"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"कल फर्वार्ड गर्ने सेवा"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"आपत्‌कालीन कलब्याक मोड"</string>
@@ -828,7 +827,7 @@
     <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"यसले एपलाई अन्य एपको स्वामित्वमा रहेका E2EE कन्ट्याक्ट कीहरूको प्रमाणीकरणको स्थिति अपडेट गर्न दिन्छ"</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"पासवर्ड नियमहरू मिलाउनुहोस्"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"स्क्रिन लक पासवर्ड र PIN हरूमा अनुमति दिइएको लम्बाइ र वर्णहरूको नियन्त्रण गर्नुहोस्।"</string>
-    <string name="policylab_watchLogin" msgid="7599669460083719504">"मनिटरको स्क्रिन अनलक गर्ने प्रयासहरू"</string>
+    <string name="policylab_watchLogin" msgid="7599669460083719504">"स्क्रिन अनलक गर्न गरिएको प्रयासको अनुगमन गर्ने"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप भएको संख्या निरीक्षण गर्नुहोस् र यदि निकै धेरै गलत पासवर्डहरू टाइप भएका छन भने ट्याब्लेट लक गर्नुहोस् वा ट्याब्लेटका सबै डेटा मेट्नुहोस्।"</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"स्क्रिन अनलक गर्दा गलत पासवर्ड टाइप गरेको सङ्ख्या निरीक्षण गर्नुहोस्, र धेरै पटक गलत पासवर्डहरू टाइप गरिएको खण्डमा आफ्नो Android टिभी यन्त्र लक गर्नुहोस् वा डिभाइसमा भएको सम्पूर्ण डेटा मेटाउनुहोस्।"</string>
     <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"स्क्रिन अनलक गर्दा कति पटक गलत पासवर्ड टाइप गरिन्छ भन्ने कुरा निगरानी गरियोस् र अत्यन्तै धेरै पटक गलत पासवर्ड टाइप गरिएका खण्डमा यो इन्फोटेनमेन्ट प्रणाली लक गरियोस् वा यस इन्फोटेनमेन्ट प्रणालीका सबै डेटा मेटाइयोस्।"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"मेट्नुहोस्"</string>
     <string name="inputMethod" msgid="1784759500516314751">"निवेश विधि"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"पाठ कार्यहरू"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"यो फिल्डमा हस्तलेखन गर्न मिल्दैन"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"पासवर्ड हाल्ने फिल्डहरूमा हस्तलेखन गर्न मिल्दैन"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"पछाडि"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"इनपुट विधि बदल्नुहोस्"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"भण्डारण ठाउँ सकिँदै छ"</string>
@@ -1566,7 +1563,7 @@
     <string name="sync_do_nothing" msgid="4528734662446469646">"अहिलेको लागि केही नगर्नुहोस्"</string>
     <string name="choose_account_label" msgid="5557833752759831548">"एउटा खाता छान्‍नुहोस्"</string>
     <string name="add_account_label" msgid="4067610644298737417">"खाता हाल्नुहोस्"</string>
-    <string name="add_account_button_label" msgid="322390749416414097">"खाता थप्नुहोस्"</string>
+    <string name="add_account_button_label" msgid="322390749416414097">"खाता हाल्नुहोस्"</string>
     <string name="number_picker_increment_button" msgid="7621013714795186298">"बढाउनुहोस्"</string>
     <string name="number_picker_decrement_button" msgid="5116948444762708204">"घटाउनुहोस्"</string>
     <string name="number_picker_increment_scroll_mode" msgid="8403893549806805985">"<xliff:g id="VALUE">%s</xliff:g> टच एण्ड होल्ड गर्नुहोस्।"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले व्यवस्थापन गरेको"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"अन छ"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"अफ छ"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"कुनै पनि पात्रो"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ले केही ध्वनिहरू म्युट गर्दै छ"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"तपाईंको यन्त्रसँग आन्तरिक समस्या छ, र तपाईंले फ्याक्ट्री डाटा रिसेट नगर्दासम्म यो अस्थिर रहन्छ।"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"तपाईंको यन्त्रसँग आन्तरिक समस्या छ। विवरणहरूको लागि आफ्नो निर्मातासँग सम्पर्क गर्नुहोस्।"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"परीक्षण"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"सामुदायिक"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"स्याटलाइटमा स्वतः कनेक्ट गरियो"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"तपाईं मोबाइल वा Wi-Fi नेटवर्कविनै म्यासेज पठाउन र प्राप्त गर्न सक्नुहुन्छ"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages खोल्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index fbf93be..5870ca3 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Kan mobiel netwerk niet bereiken"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Probeer een ander voorkeursnetwerk. Tik om te wijzigen."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Noodoproepen niet beschikbaar"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Voor noodoproepen is een mobiel netwerk vereist"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Meldingen"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Gesprek doorschakelen"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modus voor noodoproepen"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Verwijderen"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Invoermethode"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Tekstacties"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Handschrift wordt in dit veld niet ondersteund"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Handschrift wordt niet ondersteund in wachtwoordvelden"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Terug"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Invoermethode wijzigen"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Opslagruimte is bijna vol"</string>
@@ -1651,7 +1648,7 @@
     <string name="default_audio_route_name" product="default" msgid="9213546147739983977">"Telefoon"</string>
     <string name="default_audio_route_name_dock_speakers" msgid="1551166029093995289">"Dockluidsprekers"</string>
     <string name="default_audio_route_name_external_device" msgid="8124229858618975">"Extern apparaat"</string>
-    <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Hoofdtelefoon"</string>
+    <string name="default_audio_route_name_headphones" msgid="6954070994792640762">"Koptelefoon"</string>
     <string name="default_audio_route_name_usb" msgid="895668743163316932">"USB"</string>
     <string name="default_audio_route_category_name" msgid="5241740395748134483">"Systeem"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="4214648773120426288">"Bluetooth-audio"</string>
@@ -1869,7 +1866,7 @@
     <string name="print_service_installed_title" msgid="6134880817336942482">"<xliff:g id="NAME">%s</xliff:g>-service geïnstalleerd"</string>
     <string name="print_service_installed_message" msgid="7005672469916968131">"Tik om aan te zetten"</string>
     <string name="restr_pin_enter_admin_pin" msgid="1199419462726962697">"Beheerderspincode invoeren"</string>
-    <string name="restr_pin_enter_pin" msgid="373139384161304555">"Geef de pincode op"</string>
+    <string name="restr_pin_enter_pin" msgid="373139384161304555">"Voer pincode in"</string>
     <string name="restr_pin_incorrect" msgid="3861383632940852496">"Onjuist"</string>
     <string name="restr_pin_enter_old_pin" msgid="7537079094090650967">"Huidige pincode"</string>
     <string name="restr_pin_enter_new_pin" msgid="3267614461844565431">"Nieuwe pincode"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Beheerd door <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Aan"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Uit"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Elke agenda"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> zet sommige geluiden uit"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Er is een intern probleem met je apparaat. Het apparaat kan instabiel zijn totdat u het apparaat terugzet naar de fabrieksinstellingen."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Er is een intern probleem met je apparaat. Neem contact op met de fabrikant voor meer informatie."</string>
@@ -1993,7 +1993,7 @@
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Noodgeval"</string>
     <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Schermvergrendeling instellen"</string>
     <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Schermvergrendeling instellen"</string>
-    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Als je je privéruimte wilt gebruiken, stel je een schermvergrendeling op dit apparaat in"</string>
+    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Als je je privégedeelte wilt gebruiken, stel je een schermvergrendeling op dit apparaat in"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"App is niet beschikbaar"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"<xliff:g id="APP_NAME">%1$s</xliff:g> is momenteel niet beschikbaar."</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> niet beschikbaar"</string>
@@ -2203,7 +2203,7 @@
     <string name="resolver_cant_access_work_apps_explanation" msgid="1129960195389373279">"Deze content kan niet worden geopend met werk-apps"</string>
     <string name="resolver_cant_share_with_personal_apps_explanation" msgid="6349766201904601544">"Deze content kan niet worden gedeeld met persoonlijke apps"</string>
     <string name="resolver_cant_access_personal_apps_explanation" msgid="1679399548862724359">"Deze content kan niet worden geopend met persoonlijke apps"</string>
-    <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Werk-apps zijn onderbroken"</string>
+    <string name="resolver_turn_on_work_apps" msgid="1535946298236678122">"Werk-apps zijn gepauzeerd"</string>
     <string name="resolver_switch_on_work" msgid="4527096360772311894">"Hervatten"</string>
     <string name="resolver_no_work_apps_available" msgid="3298291360133337270">"Geen werk-apps"</string>
     <string name="resolver_no_personal_apps_available" msgid="6284837227019594881">"Geen persoonlijke apps"</string>
@@ -2334,7 +2334,7 @@
     <string name="window_magnification_prompt_content" msgid="8159173903032344891">"Je kunt nu een deel van je scherm vergroten"</string>
     <string name="turn_on_magnification_settings_action" msgid="8521433346684847700">"Aanzetten in Instellingen"</string>
     <string name="dismiss_action" msgid="1728820550388704784">"Sluiten"</string>
-    <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Blokkeren van apparaatmicrofoon opheffen"</string>
+    <string name="sensor_privacy_start_use_mic_notification_content_title" msgid="2420858361276370367">"Microfoon van apparaat niet meer blokkeren"</string>
     <string name="sensor_privacy_start_use_camera_notification_content_title" msgid="7287720213963466672">"Blokkeren van apparaatcamera opheffen"</string>
     <string name="sensor_privacy_start_use_notification_content_text" msgid="7595608891015777346">"Voor &lt;b&gt;<xliff:g id="APP">%s</xliff:g>&lt;/b&gt; en alle andere apps en services"</string>
     <string name="sensor_privacy_start_use_dialog_turn_on_button" msgid="7089318886628390827">"Niet meer blokkeren"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Gemeenschappelijk"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automatisch verbonden met satelliet"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Je kunt berichten sturen en krijgen zonder een mobiel of wifi-netwerk"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Berichten openen"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 2b12d82..4174d04 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ମୋବାଇଲ୍‌ ନେଟ୍‌ୱର୍କ ମିଳୁନାହିଁ"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ନିଜ ପସନ୍ଦର ନେଟ୍‌ୱର୍କକୁ ଯିବାପାଇଁ ଚେଷ୍ଟା କରନ୍ତୁ। ବଦଳାଇବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ଜରୁରୀକାଳୀନ କଲ୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ଜରୁରୀକାଳୀନ କଲ କରିବା ପାଇଁ ଏକ ମୋବାଇଲ ନେଟୱାର୍କ ଆବଶ୍ୟକ"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"ଆଲର୍ଟ"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"କଲ୍‌ ଫରୱାର୍ଡିଂ"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"ଜରୁରୀକାଳୀନ କଲବ୍ୟାକ୍‍ ମୋଡ୍‍"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"ଡିଲିଟ କରନ୍ତୁ"</string>
     <string name="inputMethod" msgid="1784759500516314751">"ଇନପୁଟ୍ ପଦ୍ଧତି"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"ଟେକ୍ସଟ୍‌ କାର୍ଯ୍ୟ"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"ଏହି ଫିଲ୍ଡରେ ହେଣ୍ଡରାଇଟିଂ ସମର୍ଥିତ ନୁହେଁ"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"ପାସୱାର୍ଡ ଫିଲ୍ଡଗୁଡ଼ିକରେ ହେଣ୍ଡରାଇଟିଂ ସମର୍ଥିତ ନୁହେଁ"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"ପଛକୁ ଫେରନ୍ତୁ"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"ଇନପୁଟ ପଦ୍ଧତି ସ୍ୱିଚ କରନ୍ତୁ"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"ଷ୍ଟୋରେଜ୍‌ ସ୍ପେସ୍‌ ଶେଷ ହେବାରେ ଲାଗିଛି"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଦ୍ୱାରା ପରିଚାଳିତ"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ଚାଲୁ ଅଛି"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ବନ୍ଦ ଅଛି"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ଯେକୌଣସି କ୍ୟାଲେଣ୍ଡର୍‌"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> କିଛି ସାଉଣ୍ଡକୁ ମ୍ୟୁଟ୍ କରୁଛି"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"ଆପଣଙ୍କ ଡିଭାଇସ୍‍ରେ ଏକ ସମସ୍ୟା ରହିଛି ଏବଂ ଆପଣ ଫ୍ୟାକ୍ଟୋରୀ ଡାଟା ରିସେଟ୍‍ ନକରିବା ପର୍ଯ୍ୟନ୍ତ ଏହା ଅସ୍ଥିର ରହିପାରେ।"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"ଆପଣଙ୍କ ଡିଭାଇସରେ ଏକ ସମସ୍ୟା ରହିଛି। ବିବରଣୀ ପାଇଁ ଆପଣଙ୍କ ଉତ୍ପାଦକଙ୍କ ସହ କଣ୍ଟାକ୍ଟ କରନ୍ତୁ।"</string>
@@ -1976,7 +1976,7 @@
     <string name="supervised_user_creation_label" msgid="6884904353827427515">"ନିରୀକ୍ଷିତ ୟୁଜର ଯୋଗ କରନ୍ତୁ"</string>
     <string name="language_selection_title" msgid="52674936078683285">"ଏକ ଭାଷା ଯୋଗ କରନ୍ତୁ"</string>
     <string name="country_selection_title" msgid="5221495687299014379">"ପସନ୍ଦର ଅଞ୍ଚଳ"</string>
-    <string name="search_language_hint" msgid="7004225294308793583">"ଭାଷାର ନାମ ଟାଇପ୍‍ କରନ୍ତୁ"</string>
+    <string name="search_language_hint" msgid="7004225294308793583">"ଭାଷାର ନାମ ଟାଇପ କରନ୍ତୁ"</string>
     <string name="language_picker_section_suggested" msgid="6556199184638990447">"ପ୍ରସ୍ତାବିତ"</string>
     <string name="language_picker_regions_section_suggested" msgid="6080131515268225316">"ପ୍ରସ୍ତାବିତ"</string>
     <string name="language_picker_section_suggested_bilingual" msgid="5932198319583556613">"ପ୍ରସ୍ତାବିତ ଭାଷାଗୁଡ଼ିକ"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"ଟେଷ୍ଟ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"କମ୍ୟୁନାଲ"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"ସାଟେଲାଇଟ ସହ ସ୍ୱତଃ କନେକ୍ଟ ହୋଇଛି"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"ଏକ ମୋବାଇଲ କିମ୍ବା ୱାଇ-ଫାଇ ନେଟୱାର୍କ ବିନା ଆପଣ ମେସେଜ ପଠାଇପାରିବେ ଏବଂ ପାଇପାରିବେ"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ଖୋଲନ୍ତୁ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 8e22644..3e7b27e 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਤੱਕ ਪਹੁੰਚ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ਤਰਜੀਹੀ ਨੈੱਟਵਰਕ ਨੂੰ ਬਦਲ ਕੇ ਦੇਖੋ। ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ਸੰਕਟਕਾਲੀਨ ਕਾਲਿੰਗ ਉਪਲਬਧ ਨਹੀਂ"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ਐਮਰਜੈਂਸੀ ਕਾਲਾਂ ਲਈ ਕਿਸੇ ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"ਅਲਰਟ"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"ਕਾਲ ਫਾਰਵਰਡਿੰਗ"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"ਸੰਕਟਕਾਲੀਨ ਕਾਲਬੈਕ ਮੋਡ"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"ਮਿਟਾਓ"</string>
     <string name="inputMethod" msgid="1784759500516314751">"ਇਨਪੁੱਟ ਵਿਧੀ"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"ਟੈਕਸਟ ਕਿਰਿਆਵਾਂ"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"ਇਸ ਖੇਤਰ ਵਿੱਚ ਲਿਖਾਈ ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"ਪਾਸਵਰਡ ਖੇਤਰਾਂ ਵਿੱਚ ਲਿਖਾਈ ਸਮਰਥਿਤ ਨਹੀਂ ਹੈ"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"ਪਿੱਛੇ"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"ਇਨਪੁੱਟ ਵਿਧੀ ਨੂੰ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"ਸਟੋਰੇਜ ਦੀ ਜਗ੍ਹਾ ਖਤਮ ਹੋ ਰਹੀ ਹੈ"</string>
@@ -1564,7 +1561,7 @@
     <string name="sync_really_delete" msgid="5657871730315579051">"ਆਈਟਮਾਂ ਹਟਾਓ"</string>
     <string name="sync_undo_deletes" msgid="5786033331266418896">"ਮਿਟਾਏ ਗਏ ਨੂੰ ਅਣਕੀਤਾ ਕਰੋ"</string>
     <string name="sync_do_nothing" msgid="4528734662446469646">"ਹੁਣ ਕੁਝ ਨਾ ਕਰੋ"</string>
-    <string name="choose_account_label" msgid="5557833752759831548">"ਇੱਕ ਖਾਤਾ ਚੁਣੋ"</string>
+    <string name="choose_account_label" msgid="5557833752759831548">"ਕੋਈ ਖਾਤਾ ਚੁਣੋ"</string>
     <string name="add_account_label" msgid="4067610644298737417">"ਇੱਕ ਖਾਤਾ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="add_account_button_label" msgid="322390749416414097">"ਖਾਤਾ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="number_picker_increment_button" msgid="7621013714795186298">"ਵਧਾਓ"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ਚਾਲੂ ਹੈ"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ਬੰਦ ਹੈ"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ਕੋਈ ਵੀ ਕੈਲੰਡਰ"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ਕੁਝ ਧੁਨੀਆਂ ਨੂੰ ਮਿਊਟ ਕਰ ਰਹੀ ਹੈ"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਇੱਕ ਅੰਦਰੂਨੀ ਸਮੱਸਿਆ ਹੈ ਅਤੇ ਇਹ ਅਸਥਿਰ ਹੋ ਸਕਦੀ ਹੈ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈੱਟ ਨਹੀਂ ਕਰਦੇ।"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਨਾਲ ਇੱਕ ਅੰਦਰੂਨੀ ਸਮੱਸਿਆ ਸੀ। ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਨਿਰਮਾਤਾ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"ਜਾਂਚ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"ਭਾਈਚਾਰਕ"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"ਸੈਟੇਲਾਈਟ ਨਾਲ ਸਵੈ-ਕਨੈਕਟ ਹੋਇਆ"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"ਤੁਸੀਂ ਮੋਬਾਈਲ ਜਾਂ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕ ਤੋਂ ਬਿਨਾਂ ਸੁਨੇਹੇ ਭੇਜ ਅਤੇ ਪ੍ਰਾਪਤ ਕਰ ਸਕਦੇ ਹੋ"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ਐਪ ਖੋਲ੍ਹੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index bb7ccaa..ca126f7 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1317,7 +1317,7 @@
     <string name="volume_unknown" msgid="4041914008166576293">"Głośność"</string>
     <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Głośność Bluetooth"</string>
     <string name="volume_icon_description_ringer" msgid="2187800636867423459">"Głośność dzwonka"</string>
-    <string name="volume_icon_description_incall" msgid="4491255105381227919">"Głośność w czasie połączenia"</string>
+    <string name="volume_icon_description_incall" msgid="4491255105381227919">"Głośność połączeń"</string>
     <string name="volume_icon_description_media" msgid="4997633254078171233">"Głośność multimediów"</string>
     <string name="volume_icon_description_notification" msgid="579091344110747279">"Głośność powiadomień"</string>
     <string name="ringtone_default" msgid="9118299121288174597">"Dzwonek domyślny"</string>
@@ -1931,6 +1931,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Zarządzana przez aplikację <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Włączono"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Wyłączono"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Dowolny kalendarz"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> wycisza niektóre dźwięki"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"W Twoim urządzeniu wystąpił problem wewnętrzny. Może być ono niestabilne, dopóki nie przywrócisz danych fabrycznych."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"W Twoim urządzeniu wystąpił problem wewnętrzny. Skontaktuj się z jego producentem, by otrzymać szczegółowe informacje."</string>
@@ -2393,6 +2396,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Testowy"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Wspólny"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automatycznie połączono z satelitą"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Możesz wymieniać wiadomości bez dostępu do sieci komórkowej lub Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otwórz Wiadomości"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 1da3965..c53b1d5 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Não foi possível acessar a rede móvel"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tente alterar a rede preferencial. Toque para alterar."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Chamadas de emergência indisponíveis"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"As chamadas de emergência exigem uma rede móvel"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Encaminhamento de chamada"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modo de retorno de chamada de emergência"</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Excluir"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Método de entrada"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Ações de texto"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Não há suporte para escrita à mão neste campo"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Não há suporte para escrita à mão em campos de senha"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Voltar"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Mudar o método de entrada"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Pouco espaço de armazenamento"</string>
@@ -1746,7 +1743,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar atalho"</string>
     <string name="color_inversion_feature_name" msgid="2672824491933264951">"Inversão de cores"</string>
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Correção de cor"</string>
-    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo para uma mão"</string>
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo uma mão"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Escurecer a tela"</string>
     <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Aparelhos auditivos"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
@@ -1933,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Gerenciada pelo app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Ativada"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desativada"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualquer agenda"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está silenciando alguns sons"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Há um problema interno com seu dispositivo. Ele pode ficar instável até que você faça a redefinição para configuração original."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Há um problema interno com seu dispositivo. Entre em contato com o fabricante para saber mais detalhes."</string>
@@ -2395,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Teste"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Público"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automaticamente ao satélite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Você pode enviar e receber mensagens sem um dispositivo móvel ou uma rede Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 70862a8..6b6f5c5 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1148,7 +1148,7 @@
     <string name="duration_days_shortest_future" msgid="3392722163935571543">"em <xliff:g id="COUNT">%d</xliff:g> d"</string>
     <string name="duration_years_shortest_future" msgid="5537464088352970388">"em <xliff:g id="COUNT">%d</xliff:g> a"</string>
     <string name="duration_minutes_relative" msgid="8620337701051015593">"{count,plural, =1{Há # minuto}many{Há # minutos}other{Há # minutos}}"</string>
-    <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{Há # hora}many{Há # horas}other{Há # horas}}"</string>
+    <string name="duration_hours_relative" msgid="4836449961693180253">"{count,plural, =1{há # hora}many{há # horas}other{há # horas}}"</string>
     <string name="duration_days_relative" msgid="621965767567258302">"{count,plural, =1{Há # dia}many{Há # dias}other{Há # dias}}"</string>
     <string name="duration_years_relative" msgid="8731202348869424370">"{count,plural, =1{Há # ano}many{Há # anos}other{Há # anos}}"</string>
     <string name="duration_minutes_relative_future" msgid="5259574171747708115">"{count,plural, =1{# minuto}many{# minutos}other{# minutos}}"</string>
@@ -1312,13 +1312,13 @@
     <string name="volume_call" msgid="7625321655265747433">"Volume da chamada recebida"</string>
     <string name="volume_bluetooth_call" msgid="2930204618610115061">"Volume de chamada recebida em Bluetooth"</string>
     <string name="volume_alarm" msgid="4486241060751798448">"Volume do alarme"</string>
-    <string name="volume_notification" msgid="6864412249031660057">"Volume de notificações"</string>
+    <string name="volume_notification" msgid="6864412249031660057">"Volume das notificações"</string>
     <string name="volume_unknown" msgid="4041914008166576293">"Volume"</string>
     <string name="volume_icon_description_bluetooth" msgid="7540388479345558400">"Volume de Bluetooth"</string>
     <string name="volume_icon_description_ringer" msgid="2187800636867423459">"Volume do toque"</string>
     <string name="volume_icon_description_incall" msgid="4491255105381227919">"Volume de chamadas"</string>
     <string name="volume_icon_description_media" msgid="4997633254078171233">"Volume de multimédia"</string>
-    <string name="volume_icon_description_notification" msgid="579091344110747279">"Volume de notificações"</string>
+    <string name="volume_icon_description_notification" msgid="579091344110747279">"Volume das notificações"</string>
     <string name="ringtone_default" msgid="9118299121288174597">"Toque predefinido"</string>
     <string name="ringtone_default_with_actual" msgid="2709686194556159773">"Predefinição (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
     <string name="ringtone_silent" msgid="397111123930141876">"Nenhum"</string>
@@ -1930,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Gerido por <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Ativada"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desativada"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualquer calendário"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está a desativar alguns sons."</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Existe um problema interno no seu dispositivo e pode ficar instável até efetuar uma reposição de dados de fábrica."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Existe um problema interno no seu dispositivo. Contacte o fabricante para obter mais informações."</string>
@@ -1991,7 +1994,7 @@
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Emergência"</string>
     <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Defina um bloqueio de ecrã"</string>
     <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Definir bloqueio de ecrã"</string>
-    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Para usar espaço privado, defina bloqueio de ecrã no disp."</string>
+    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Defina um bloqueio para usar o espaço privado"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"A app não está disponível"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"De momento, a app <xliff:g id="APP_NAME">%1$s</xliff:g> não está disponível."</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> indisponível"</string>
@@ -2068,7 +2071,7 @@
     <string name="autofill_update_title_with_2types" msgid="1797514386321086273">"Quer atualizar <xliff:g id="TYPE_0">%1$s</xliff:g> e <xliff:g id="TYPE_1">%2$s</xliff:g> em "<b>"<xliff:g id="LABEL">%3$s</xliff:g>"</b>"?"</string>
     <string name="autofill_update_title_with_3types" msgid="8285767070604652626">"Atualizar estes itens no serviço "<b>"<xliff:g id="LABEL">%4$s</xliff:g>"</b>": <xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> e <xliff:g id="TYPE_2">%3$s</xliff:g>?"</string>
     <string name="autofill_save_yes" msgid="8035743017382012850">"Guardar"</string>
-    <string name="autofill_save_no" msgid="9212826374207023544">"Não, obrigado"</string>
+    <string name="autofill_save_no" msgid="9212826374207023544">"Não"</string>
     <string name="autofill_save_notnow" msgid="2853932672029024195">"Agora não"</string>
     <string name="autofill_save_never" msgid="6821841919831402526">"Nunca"</string>
     <string name="autofill_update_yes" msgid="4608662968996874445">"Atualizar"</string>
@@ -2392,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Teste"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Comum"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Ligação de satélite estabelecida automaticamente"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Pode enviar e receber mensagens sem uma rede móvel ou Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abre a app Mensagens"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 1da3965..c53b1d5 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Não foi possível acessar a rede móvel"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tente alterar a rede preferencial. Toque para alterar."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Chamadas de emergência indisponíveis"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"As chamadas de emergência exigem uma rede móvel"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alertas"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Encaminhamento de chamada"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modo de retorno de chamada de emergência"</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Excluir"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Método de entrada"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Ações de texto"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Não há suporte para escrita à mão neste campo"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Não há suporte para escrita à mão em campos de senha"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Voltar"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Mudar o método de entrada"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Pouco espaço de armazenamento"</string>
@@ -1746,7 +1743,7 @@
     <string name="leave_accessibility_shortcut_on" msgid="6543362062336990814">"Usar atalho"</string>
     <string name="color_inversion_feature_name" msgid="2672824491933264951">"Inversão de cores"</string>
     <string name="color_correction_feature_name" msgid="7975133554160979214">"Correção de cor"</string>
-    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo para uma mão"</string>
+    <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"Modo uma mão"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"Escurecer a tela"</string>
     <string name="hearing_aids_feature_name" msgid="1125892105105852542">"Aparelhos auditivos"</string>
     <string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
@@ -1933,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Gerenciada pelo app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Ativada"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Desativada"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> a <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Qualquer agenda"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> está silenciando alguns sons"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Há um problema interno com seu dispositivo. Ele pode ficar instável até que você faça a redefinição para configuração original."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Há um problema interno com seu dispositivo. Entre em contato com o fabricante para saber mais detalhes."</string>
@@ -2395,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Teste"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Público"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Conectado automaticamente ao satélite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Você pode enviar e receber mensagens sem um dispositivo móvel ou uma rede Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Abrir o app Mensagens"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 2ca2082..5a449e3 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nu se poate stabili conexiunea la rețeaua mobilă"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Încearcă să schimbi rețeaua preferată. Atinge pentru a schimba."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Apelurile de urgență nu sunt disponibile"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Apelurile de urgență necesită o rețea mobilă"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Alerte"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Redirecționarea apelurilor"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Mod de apelare inversă de urgență"</string>
@@ -829,7 +828,7 @@
     <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"Permite aplicației să actualizeze starea verificării cheilor E2EE deținute de alte aplicații"</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Să seteze reguli pentru parolă"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"Stabilește lungimea și tipul de caractere permise pentru parolele și codurile PIN de blocare a ecranului."</string>
-    <string name="policylab_watchLogin" msgid="7599669460083719504">"Să monitorizeze încercările de deblocare a ecranului"</string>
+    <string name="policylab_watchLogin" msgid="7599669460083719504">"să monitorizeze încercările de deblocare a ecranului"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Monitorizează numărul de parole incorecte introduse la deblocarea ecranului și blochează tableta sau șterge datele acesteia dacă sunt introduse prea multe parole incorecte."</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Monitorizează numărul de parole incorecte introduse la deblocarea ecranului și blochează dispozitivul Android TV sau șterge toate datele de pe acesta dacă se introduc prea multe parole incorecte."</string>
     <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"Monitorizează numărul de parole incorecte introduse la deblocarea ecranului și blochează sistemul de infotainment sau șterge toate datele acestuia dacă sunt introduse prea multe parole incorecte."</string>
@@ -842,7 +841,7 @@
     <string name="policydesc_resetPassword" msgid="4626419138439341851">"Modifică blocarea ecranului."</string>
     <string name="policylab_forceLock" msgid="7360335502968476434">"Să blocheze ecranul"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"Stabilește cum și când se blochează ecranul."</string>
-    <string name="policylab_wipeData" msgid="1359485247727537311">"Să șteargă toate datele"</string>
+    <string name="policylab_wipeData" msgid="1359485247727537311">"să șteargă toate datele"</string>
     <string name="policydesc_wipeData" product="tablet" msgid="7245372676261947507">"Șterge datele de pe tabletă fără avertisment, efectuând resetarea configurării din fabrică."</string>
     <string name="policydesc_wipeData" product="tv" msgid="513862488950801261">"Șterge datele de pe dispozitivul Android TV fără avertisment, efectuând o revenire la setările din fabrică."</string>
     <string name="policydesc_wipeData" product="automotive" msgid="660804547737323300">"Șterge datele din sistemul de infotainment fără avertisment, prin revenirea la setările din fabrică."</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Șterge"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Metodă de intrare"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Acțiuni pentru text"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Scrierea de mână nu este acceptată în acest câmp"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Scrierea de mână nu este acceptată în câmpurile pentru parole"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Înapoi"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Schimbă metoda de introducere"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Spațiul de stocare aproape ocupat"</string>
@@ -1933,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Gestionat de <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Activată"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Dezactivată"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Orice calendar"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> dezactivează anumite sunete"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"A apărut o problemă internă pe dispozitiv, iar acesta poate fi instabil până la revenirea la setările din fabrică."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"A apărut o problemă internă pe dispozitiv. Pentru detalii, contactează producătorul."</string>
@@ -2395,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Comun"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"S-a conectat automat la satelit"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Poți să trimiți și să primești mesaje fără o rețea mobilă sau Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Deschide Mesaje"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 5875450..59982ef 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -86,8 +86,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Мобильная сеть недоступна"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Нажмите, чтобы выбрать другую сеть."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Экстренные вызовы недоступны"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Для экстренных вызовов нужна мобильная сеть."</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Оповещения"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Переадресация вызовов"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Режим экстренных обратных вызовов"</string>
@@ -1186,10 +1185,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Удалить"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Способ ввода"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Операции с текстом"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Это поле не поддерживает рукописный ввод"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Поля для указания пароля не поддерживают рукописный ввод"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Назад"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Сменить способ ввода"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Недостаточно памяти"</string>
@@ -1288,7 +1285,7 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Запуск приложений."</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"Окончание загрузки..."</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Вы нажали кнопку питания. Обычно это приводит к отключению экрана.\n\nПри добавлении отпечатка пальца слегка прикоснитесь к кнопке."</string>
-    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Для завершения нужно отключить экран"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Для завершения нужно отключить экран."</string>
     <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Отключить"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"Продолжить сканирование отпечатка?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"Вы нажали кнопку питания. Обычно это приводит к отключению экрана.\n\nЧтобы отсканировать отпечаток пальца, слегка прикоснитесь к кнопке."</string>
@@ -1934,6 +1931,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Под управлением приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Включено"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Отключено"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Любой календарь"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> приглушает некоторые звуки."</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Произошла внутренняя ошибка, и устройство может работать нестабильно, пока вы не выполните сброс настроек."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Произошла внутренняя ошибка. Обратитесь к производителю устройства за подробными сведениями."</string>
@@ -2396,6 +2396,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Тестовый"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Совместный"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Автоматически подключено к системам спутниковой связи"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Вы можете отправлять и получать сообщения без доступа к мобильной сети или Wi-Fi."</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Открыть Сообщения"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 58ef919..04b2c52 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"ජංගම ජාලය වෙත ළඟා විය නොහැකිය"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"කැමති ජාලය වෙනස් කිරීමට උත්සාහ කරන්න. වෙනස් කිරීමට තට්ටු කරන්න."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"හදිසි ඇමතුම් ලබා ගත නොහැකිය"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"හදිසි ඇමතුම් සඳහා ජංගම ජාලයක් අවශ්‍ය වේ"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"ඇඟවීම්"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"ඇමතුම ප්‍රතියොමු කිරීම"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"හදිසි අවස්ථා පසු ඇමතුම් ප්‍රකාරය"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"මකන්න"</string>
     <string name="inputMethod" msgid="1784759500516314751">"ආදාන ක්‍රමය"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"පෙළ ක්‍රියාවන්"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"මෙම ක්ෂේත්‍රය අත් අකුරු සඳහා සහය නොදක්වයි"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"මුරපද ක්ෂේත්‍ර අත් අකුරු සඳහා සහය නොදක්වයි"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"ආපසු"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"ආදාන ක්‍රමය මාරු කිරීම"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"ආචයනය ඉඩ ප්‍රමාණය අඩු වී ඇත"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> විසින් කළමනාකරණය කරයි"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ක්‍රියාත්මකයි"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ක්‍රියාවිරහිතයි"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ඕනෑම දින දර්ශනයක්"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> සමහර ශබ්ද නිහඬ කරමින්"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"ඔබේ උපාංගය සමගින් ගැටලුවක් ඇති අතර, ඔබේ කර්මාන්තශාලා දත්ත යළි සකසන තෙක් එය අස්ථායි විය හැකිය."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"ඔබේ උපාංගය සමගින් අභ්‍යන්තර ගැටලුවක් ඇත. විස්තර සඳහා ඔබේ නිෂ්පාදක අමතන්න."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"පරීක්ෂණය"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"වාර්ගික"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"චන්ද්‍රිකාවට ස්වයංක්‍රීයව සම්බන්ධ වේ"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"ඔබට ජංගම හෝ Wi-Fi ජාලයක් නොමැතිව පණිවිඩ යැවීමට සහ ලැබීමට හැක"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages විවෘත කරන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 915c5eb..76cad30 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -86,8 +86,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Nepodarilo sa pripojiť k mobilnej sieti"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Skúste zmeniť predvolenú sieť. Zmeníte ju klepnutím."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Tiesňové volania nie sú k dispozícii"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Tiesňové volania vyžadujú mobilnú sieť"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Upozornenia"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Presmerovanie hovorov"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Režim tiesňového spätného volania"</string>
@@ -1186,10 +1185,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Odstrániť"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Metóda vstupu"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Operácie s textom"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Ručné písanie nie je v tomto poli podporované"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"V poliach pre heslá nie je ručné písanie podporované"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Späť"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Prepnúť metódu vstupu"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Nedostatok ukladacieho priestoru"</string>
@@ -1934,6 +1931,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Spravované aplikáciou <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Zapnuté"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Vypnuté"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Ľubovoľný kalendár"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> vypína niektoré zvuky"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Vo vašom zariadení došlo k internému problému. Môže byť nestabilné, kým neobnovíte jeho výrobné nastavenia."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Vo vašom zariadení došlo k internému problému. Ak chcete získať podrobné informácie, obráťte sa na jeho výrobcu."</string>
@@ -1994,7 +1994,7 @@
     <string name="work_mode_turn_on" msgid="5316648862401307800">"Zrušiť pozastavenie"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Tiesňová linka"</string>
     <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Nastavte zámku obrazovky"</string>
-    <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Nastavte zámku obrazovky"</string>
+    <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Nastaviť zámku obrazovky"</string>
     <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Ak chcete používať súkromný priestor, nastavte v tomto zariadení zámku obrazovky"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Aplikácia nie je dostupná"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> nie je teraz dostupná."</string>
@@ -2396,6 +2396,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Testovací"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Spoločný"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automaticky pripojené k satelitu"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Správy môžete odosielať a prijímať bez mobilnej siete či siete Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Otvoriť Správy"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 4c13c00..5983929 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -86,8 +86,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobilnega omrežja ni mogoče doseči"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Poskusite spremeniti prednostno omrežje. Dotaknite se, če ga želite spremeniti."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Klicanje v sili ni na voljo"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Za klice v sili potrebujete mobilno omrežje"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Opozorila"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Preusmerjanje klicev"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Način za povratni klic v sili"</string>
@@ -1186,10 +1185,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Izbriši"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Način vnosa"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Besedilna dejanja"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Rokopis ni podprt v tem polju"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Rokopis ni podprt v poljih za vnos gesla"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Nazaj"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Preklop načina vnosa"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Prostor za shranjevanje bo pošel"</string>
@@ -1934,6 +1931,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Upravlja <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Vklopljeno"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Izklopljeno"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Kateri koli koledar"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> izklaplja nekatere zvoke"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Vaša naprava ima notranjo napako in bo morda nestabilna, dokler je ne ponastavite na tovarniške nastavitve."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Vaša naprava ima notranjo napako. Če želite več informacij, se obrnite na proizvajalca."</string>
@@ -2396,6 +2396,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Preizkus"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Skupno"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Samodejno vzpostavljena povezava s satelitom"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Sporočila SMS lahko pošiljate in prejemate brez mobilnega omrežja ali omrežja Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Odpri Sporočila"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index c344c7d..5a02d56 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Rrjeti celular është i paarritshëm"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Provo të ndryshosh rrjetin e preferuar. Trokit për ta ndryshuar."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Telefonatat e urgjencës nuk ofrohen"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Telefonatat e urgjencës kërkojnë një rrjet celular"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Sinjalizimet"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Transferimi i telefonatave"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Modaliteti i \"Kthimit të telefonatës së urgjencës\""</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Fshi"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Metoda e hyrjes"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Veprimet e tekstit"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Shkrimi i dorës nuk mbështetet në këtë fushë"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Shkrimi i dorës nuk mbështetet në fushat e fjalëkalimeve"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Pas"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Ndërro metodën e hyrjes"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Hapësira ruajtëse po mbaron"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Menaxhohet nga <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Aktivizuar"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Çaktivizuar"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Çdo kalendar"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> po çaktivizon disa tinguj"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Ka një problem të brendshëm me pajisjen tënde. Ajo mund të jetë e paqëndrueshme derisa të rivendosësh të dhënat në gjendje fabrike."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Ka një problem të brendshëm me pajisjen tënde. Kontakto prodhuesin tënd për detaje."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"I përbashkët"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"U lidh automatikisht me satelitin"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Mund të dërgosh dhe të marrësh mesazhe pa një rrjet celular apo rrjet Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Hap \"Mesazhet\""</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 0c5557f..637371c 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -85,8 +85,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Повезивање са мобилном мрежом није успело"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Пробајте да промените жељену мрежу. Додирните да бисте променили."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Хитни позиви нису доступни"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Хитни позиви захтевају мобилну мрежу"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Упозорења"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Преусмеравање позива"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Режим за хитан повратни позив"</string>
@@ -616,7 +615,7 @@
     <string name="permlab_disableKeyguard" msgid="3605253559020928505">"онемогућавање закључавања екрана"</string>
     <string name="permdesc_disableKeyguard" msgid="3223710003098573038">"Дозвољава апликацији да онемогући закључавање тастатуре и све повезане безбедносне мере са лозинкама. На пример, телефон онемогућава закључавање тастатуре при пријему долазног телефонског позива, а затим га поново омогућава по завршетку позива."</string>
     <string name="permlab_requestPasswordComplexity" msgid="1808977190557794109">"тражење сложености закључавања екрана"</string>
-    <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Дозвољава апликацији да сазна ниво сложености закључавања екрана (висока, средња, ниска или ниједна), што указује на могући опсег трајања и тип закључавања екрана. Апликација може и да предлаже корисницима да ажурирају закључавање екрана на одређени ниво, али корисници слободно могу да занемаре то и да иду на друге странице. Имајте на уму да се подаци за закључавање екрана не чувају као обичан текст, па апликација не зна тачну лозинку."</string>
+    <string name="permdesc_requestPasswordComplexity" msgid="1130556896836258567">"Дозвољава апликацији да сазна ниво сложености закључавања екрана (висока, средња, ниска или ниједна), што указује на могући опсег трајања и тип закључавања екрана. Апликација може и да предлаже корисницима да ажурирају откључавање екрана на одређени ниво, али корисници слободно могу да занемаре то и да иду на друге странице. Имајте на уму да се подаци за откључавање екрана не чувају као обичан текст, па апликација не зна тачну лозинку."</string>
     <string name="permlab_postNotification" msgid="4875401198597803658">"приказивање обавештења"</string>
     <string name="permdesc_postNotification" msgid="5974977162462877075">"Дозвољава апликацији да приказује обавештења"</string>
     <string name="permlab_turnScreenOn" msgid="219344053664171492">"укључивање екрана"</string>
@@ -636,10 +635,10 @@
     <string name="permlab_mediaLocation" msgid="7368098373378598066">"читање локација из медијске колекције"</string>
     <string name="permdesc_mediaLocation" msgid="597912899423578138">"Дозвољава апликацији да чита локације из медијске колекције."</string>
     <string name="biometric_app_setting_name" msgid="3339209978734534457">"Користите биометрију"</string>
-    <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Користите биометрију или закључавање екрана"</string>
+    <string name="biometric_or_screen_lock_app_setting_name" msgid="5348462421758257752">"Користите биометрију или откључавање екрана"</string>
     <string name="biometric_dialog_default_title" msgid="55026799173208210">"Потврдите свој идентитет"</string>
     <string name="biometric_dialog_default_subtitle" msgid="8457232339298571992">"Користите биометријски податак да бисте наставили"</string>
-    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Користите биометријски податак или закључавање екрана да бисте наставили"</string>
+    <string name="biometric_or_screen_lock_dialog_default_subtitle" msgid="159539678371552009">"Користите биометријски податак или откључавање екрана да бисте наставили"</string>
     <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Биометријски хардвер није доступан"</string>
     <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Потврда идентитета је отказана"</string>
     <string name="biometric_not_recognized" msgid="5106687642694635888">"Није препознато"</string>
@@ -647,8 +646,8 @@
     <string name="biometric_error_canceled" msgid="8266582404844179778">"Потврда идентитета је отказана"</string>
     <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Нисте подесили ни PIN, ни шаблон, ни лозинку"</string>
     <string name="biometric_error_generic" msgid="6784371929985434439">"Грешка при потврди идентитета"</string>
-    <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Користите закључавање екрана"</string>
-    <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Употребите закључавање екрана да бисте наставили"</string>
+    <string name="screen_lock_app_setting_name" msgid="6054944352976789228">"Користите откључавање екрана"</string>
+    <string name="screen_lock_dialog_default_subtitle" msgid="120359538048533695">"Употребите откључавање екрана да бисте наставили"</string>
     <string name="fingerprint_acquired_partial" msgid="4323789264604479684">"Чврсто притисните сензор"</string>
     <string name="fingerprint_acquired_insufficient" msgid="2410176550915730974">"Отисак прста није препознат. Пробајте поново."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1770676120848224250">"Обришите сензор за отисак прста и пробајте поново"</string>
@@ -673,8 +672,8 @@
     <string name="fingerprint_error_timeout" msgid="7361192266621252164">"Време за подешавање отиска прста је истекло. Пробајте поново."</string>
     <string name="fingerprint_error_canceled" msgid="5541771463159727513">"Радња са отиском прста је отказана"</string>
     <string name="fingerprint_error_user_canceled" msgid="2017941773466506863">"Корисник је отказао радњу са отиском прста"</string>
-    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Превише покушаја. Користите закључавање екрана уместо тога."</string>
-    <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Превише покушаја. Користите закључавање екрана уместо тога."</string>
+    <string name="fingerprint_error_lockout" msgid="6626753679019351368">"Превише покушаја. Користите откључавање екрана уместо тога."</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="9060651300306264843">"Превише покушаја. Користите откључавање екрана уместо тога."</string>
     <string name="fingerprint_error_unable_to_process" msgid="2446280592818621224">"Обрађивање отиска прста није успело. Пробајте поново."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="3144806556204061862">"Није регистрован ниједан отисак прста"</string>
     <string name="fingerprint_error_hw_not_present" msgid="5898827259419366359">"Овај уређај нема сензор за отисак прста"</string>
@@ -683,9 +682,9 @@
     <string name="fingerprint_error_power_pressed" msgid="5479524500542129414">"Притиснуто је дугме за укључивање"</string>
     <string name="fingerprint_name_template" msgid="8941662088160289778">"Прст <xliff:g id="FINGERID">%d</xliff:g>"</string>
     <string name="fingerprint_app_setting_name" msgid="4253767877095495844">"Користите отисак прста"</string>
-    <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користите отисак прста или закључавање екрана"</string>
+    <string name="fingerprint_or_screen_lock_app_setting_name" msgid="3501743523487644907">"Користите отисак прста или откључавање екрана"</string>
     <string name="fingerprint_dialog_default_subtitle" msgid="3879832845486835905">"Наставите помоћу отиска прста"</string>
-    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Користите отисак прста или закључавање екрана да бисте наставили"</string>
+    <string name="fingerprint_or_screen_lock_dialog_default_subtitle" msgid="5195808203117992200">"Користите отисак прста или откључавање екрана да бисте наставили"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
     <string name="fingerprint_error_vendor_unknown" msgid="4170002184907291065">"Дошло је до проблема. Пробајте поново."</string>
@@ -737,16 +736,16 @@
     <string name="face_error_user_canceled" msgid="5766472033202928373">"Корисник је отказао откључавање лицем"</string>
     <string name="face_error_lockout" msgid="7864408714994529437">"Превише покушаја. Пробајте поново касније."</string>
     <string name="face_error_lockout_permanent" msgid="8533257333130473422">"Превише покушаја. Откључавање лицем није доступно."</string>
-    <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Превише покушаја. Користите закључавање екрана за то."</string>
+    <string name="face_error_lockout_screen_lock" msgid="5062609811636860928">"Превише покушаја. Користите откључавање екрана за то."</string>
     <string name="face_error_unable_to_process" msgid="5723292697366130070">"Провера лица није успела. Пробајте поново."</string>
     <string name="face_error_not_enrolled" msgid="1134739108536328412">"Нисте подесили откључавање лицем"</string>
     <string name="face_error_hw_not_present" msgid="7940978724978763011">"Откључавање лицем није подржано на овом уређају"</string>
     <string name="face_error_security_update_required" msgid="5076017208528750161">"Сензор је привремено онемогућен."</string>
     <string name="face_name_template" msgid="3877037340223318119">"Лице <xliff:g id="FACEID">%d</xliff:g>"</string>
     <string name="face_app_setting_name" msgid="5854024256907828015">"Користите откључавање лицем"</string>
-    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Користите закључавање лицем или закључавање екрана"</string>
+    <string name="face_or_screen_lock_app_setting_name" msgid="1603149075605709106">"Користите закључавање лицем или откључавање екрана"</string>
     <string name="face_dialog_default_subtitle" msgid="6620492813371195429">"Потврдите идентитет лицем да бисте наставили"</string>
-    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Користите лице или закључавање екрана да бисте наставили"</string>
+    <string name="face_or_screen_lock_dialog_default_subtitle" msgid="5006381531158341844">"Користите лице или откључавање екрана да бисте наставили"</string>
   <string-array name="face_error_vendor">
   </string-array>
     <string name="face_error_vendor_unknown" msgid="7387005932083302070">"Дошло је до проблема. Пробајте поново."</string>
@@ -828,7 +827,7 @@
     <string name="permlab_writeVerificationStateE2eeContactKeys" msgid="3990742344778360457">"Ажурирање статуса верификације кључева за шифровање контаката с краја на крај у власништву других апликација"</string>
     <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"Дозвољава апликацији да ажурира статусе верификације кључева за шифровање контаката с краја на крај (E2EE) у власништву других апликација"</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"Подешавање правила за лозинку"</string>
-    <string name="policydesc_limitPassword" msgid="4105491021115793793">"Контролише дужину и знакове дозвољене у лозинкама и PIN-овима за закључавање екрана."</string>
+    <string name="policydesc_limitPassword" msgid="4105491021115793793">"Контролише дужину и знакове дозвољене у лозинкама и PIN-овима за откључавање екрана."</string>
     <string name="policylab_watchLogin" msgid="7599669460083719504">"Надзор покушаја откључавања екрана"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"Прати број нетачно унетих лозинки приликом откључавања екрана и закључава таблет или брише податке са таблета ако је нетачна лозинка унета превише пута."</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава Android TV уређај или брише све податке са Android TV уређаја ако се унесе превише нетачних лозинки."</string>
@@ -839,7 +838,7 @@
     <string name="policydesc_watchLogin_secondaryUser" product="automotive" msgid="7180857406058327941">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава систем за инфо-забаву или брише све податке овог профила ако се унесе превише нетачних лозинки."</string>
     <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="9177645136475155924">"Надгледа број нетачних лозинки унетих при откључавању екрана и закључава телефон или брише све податке овог корисника ако се унесе превише нетачних лозинки."</string>
     <string name="policylab_resetPassword" msgid="214556238645096520">"Промена закључавања екрана"</string>
-    <string name="policydesc_resetPassword" msgid="4626419138439341851">"Мења закључавање екрана."</string>
+    <string name="policydesc_resetPassword" msgid="4626419138439341851">"Мења откључавање екрана."</string>
     <string name="policylab_forceLock" msgid="7360335502968476434">"Закључавање екрана"</string>
     <string name="policydesc_forceLock" msgid="1008844760853899693">"Контрола начина и времена закључавања екрана."</string>
     <string name="policylab_wipeData" msgid="1359485247727537311">"Брисање свих података"</string>
@@ -856,7 +855,7 @@
     <string name="policylab_setGlobalProxy" msgid="215332221188670221">"Подесите глобални прокси сервер уређаја"</string>
     <string name="policydesc_setGlobalProxy" msgid="7149665222705519604">"Подешава глобални прокси уређаја који ће се користити док су смернице омогућене. Само власник уређаја може да подеси глобални прокси."</string>
     <string name="policylab_expirePassword" msgid="6015404400532459169">"Подеси истек. лозин. за закљ. екр."</string>
-    <string name="policydesc_expirePassword" msgid="9136524319325960675">"Мења колико често лозинка, PIN или шаблон за закључавање екрана мора да се мења."</string>
+    <string name="policydesc_expirePassword" msgid="9136524319325960675">"Мења колико често лозинка, PIN или шаблон за откључавање екрана мора да се мења."</string>
     <string name="policylab_encryptedStorage" msgid="9012936958126670110">"Подешавање шифровања складишта"</string>
     <string name="policydesc_encryptedStorage" msgid="1102516950740375617">"Захтева да сачувани подаци апликације буду шифровани."</string>
     <string name="policylab_disableCamera" msgid="5749486347810162018">"Онемогућавање камера"</string>
@@ -1185,10 +1184,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Избриши"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Метод уноса"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Радње у вези са текстом"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Писање руком није подржано у овом пољу"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Писање руком није подржано у пољима за лозинке"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Назад"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Промените метод уноса"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Меморијски простор је на измаку"</string>
@@ -1933,6 +1930,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Управља: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Укључено"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Искључено"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Било који календар"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> искључује неке звуке"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Дошло је до интерног проблема у вези са уређајем и можда ће бити нестабилан док не обавите ресетовање на фабричка подешавања."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Дошло је до интерног проблема у вези са уређајем. Потражите детаље од произвођача."</string>
@@ -1992,9 +1992,9 @@
     <string name="work_mode_off_title" msgid="6367463960165135829">"Укључити пословне апликације?"</string>
     <string name="work_mode_turn_on" msgid="5316648862401307800">"Поново активирај"</string>
     <string name="work_mode_emergency_call_button" msgid="6818855962881612322">"Хитан случај"</string>
-    <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Подесите закључавање екрана"</string>
-    <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Подеси закључавање екрана"</string>
-    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Да бисте користили приватни простор, подесите закључавање екрана на овом уређају"</string>
+    <string name="set_up_screen_lock_title" msgid="8346083801616474030">"Подесите откључавање екрана"</string>
+    <string name="set_up_screen_lock_action_label" msgid="2687634803649209367">"Подеси откључавање екрана"</string>
+    <string name="private_space_set_up_screen_lock_message" msgid="1109956797005149814">"Да бисте користили приватни простор, подесите откључавање екрана на овом уређају"</string>
     <string name="app_blocked_title" msgid="7353262160455028160">"Апликација није доступна"</string>
     <string name="app_blocked_message" msgid="542972921087873023">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> тренутно није доступна."</string>
     <string name="app_streaming_blocked_title" msgid="6090945835898766139">"<xliff:g id="ACTIVITY">%1$s</xliff:g> – није доступно"</string>
@@ -2395,6 +2395,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Тест"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Заједничко"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Аутоматски повезано са сателитом"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Можете да шаљете и примате поруке без мобилне или WiFi мреже"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Отвори Messages"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 4abc6f6..2dde3a8 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Det går inte att nå mobilnätverket"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Testa att byta föredraget nätverk. Tryck om du vill ändra."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Det går inte att ringa nödsamtal"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Mobilnätverk krävs för att ringa nödsamtal"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Aviseringar"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Vidarekoppla samtal"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Läget Återuppringning vid nödsamtal"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Ta bort"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Indatametod"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Textåtgärder"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Handskrift stöds inte i det här fältet"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Handskrift stöds inte i lösenordsfält"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Tillbaka"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Byt inmatningsmetod"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Lagringsutrymmet börjar ta slut"</string>
@@ -1530,10 +1527,10 @@
     <string name="vpn_title_long" msgid="6834144390504619998">"VPN aktiveras av <xliff:g id="APP">%s</xliff:g>"</string>
     <string name="vpn_text" msgid="2275388920267251078">"Knacka lätt för att hantera nätverket."</string>
     <string name="vpn_text_long" msgid="278540576806169831">"Ansluten till <xliff:g id="SESSION">%s</xliff:g>. Knacka lätt för att hantera nätverket."</string>
-    <string name="vpn_lockdown_connecting" msgid="6096725311950342607">"Ansluter till Always-on VPN ..."</string>
-    <string name="vpn_lockdown_connected" msgid="2853127976590658469">"Ansluten till Always-on VPN"</string>
-    <string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"Frånkopplad från Always-on VPN"</string>
-    <string name="vpn_lockdown_error" msgid="4453048646854247947">"Det gick inte att ansluta till Always-on VPN"</string>
+    <string name="vpn_lockdown_connecting" msgid="6096725311950342607">"Ansluter till Alltid på-VPN ..."</string>
+    <string name="vpn_lockdown_connected" msgid="2853127976590658469">"Ansluten till Alltid på-VPN"</string>
+    <string name="vpn_lockdown_disconnected" msgid="5573611651300764955">"Frånkopplad från Alltid på-VPN"</string>
+    <string name="vpn_lockdown_error" msgid="4453048646854247947">"Det gick inte att ansluta till Alltid på-VPN"</string>
     <string name="vpn_lockdown_config" msgid="8331697329868252169">"Ändra inställningarna för nätverk eller VPN"</string>
     <string name="upload_file" msgid="8651942222301634271">"Välj fil"</string>
     <string name="no_file_chosen" msgid="4146295695162318057">"Ingen fil har valts"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Hanteras av <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"På"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Av"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>–<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Alla kalendrar"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> stänger av vissa ljud"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Ett internt problem har uppstått i enheten, och det kan hända att problemet kvarstår tills du återställer standardinställningarna."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Ett internt problem har uppstått i enheten. Kontakta tillverkaren om du vill veta mer."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Allmän"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Automatiskt ansluten till satellit"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Du kan skicka och ta emot meddelanden utan mobil- eller wifi-nätverk"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Öppna Messages"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 95a9b73..2936716 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Imeshindwa kufikia mtandao wa simu"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Jaribu kutumia mtandao unaopendelea. Gusa ili ubadilishe."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Huduma ya kupiga simu za dharura haipatikani"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Huduma ya kupiga simu za dharura inahitaji mtandao wa simu"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Arifa"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Kupeleka simu kwenye namba nyingine"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Hali ya kupiga simu za dharura"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Futa"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Mbinu ya uingizaji"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Vitendo vya maandishi"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Huwezi kuandika kwa mkono kwenye sehemu hii"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Huwezi kuandika kwa mkono kwenye sehemu za kuweka nenosiri"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Rudi nyuma"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Badilisha mbinu ya kuingiza data"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Nafasi ya kuhifadhi inakaribia kujaa"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Inadhibitiwa na <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Imewashwa"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Imezimwa"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Kalenda yoyote"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> inazima baadhi ya sauti"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Kuna hitilafu ya ndani ya kifaa chako, na huenda kisiwe thabiti mpaka urejeshe mipangilio ya kiwandani."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Kuna hitilafu ya ndani ya kifaa chako. Wasiliana na mtengenezaji wa kifaa chako kwa maelezo."</string>
@@ -1976,7 +1976,7 @@
     <string name="supervised_user_creation_label" msgid="6884904353827427515">"Weka mtumiaji anayesimamiwa"</string>
     <string name="language_selection_title" msgid="52674936078683285">"Ongeza lugha"</string>
     <string name="country_selection_title" msgid="5221495687299014379">"Mapendeleo ya eneo"</string>
-    <string name="search_language_hint" msgid="7004225294308793583">"Weka jina la lugha"</string>
+    <string name="search_language_hint" msgid="7004225294308793583">"Andika jina la lugha"</string>
     <string name="language_picker_section_suggested" msgid="6556199184638990447">"Zinazopendekezwa"</string>
     <string name="language_picker_regions_section_suggested" msgid="6080131515268225316">"Yanayopendekezwa"</string>
     <string name="language_picker_section_suggested_bilingual" msgid="5932198319583556613">"Lugha zinazopendekezwa"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Jaribio"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Unaoshirikiwa"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Imeunganishwa kiotomatiki na satelaiti"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Unaweza kutuma na kupokea ujumbe bila mtandao wa simu au Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Fungua Programu ya Messages"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 85640a6..28ee91d 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"மொபைல் நெட்வொர்க் கிடைக்கவில்லை"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"விருப்ப நெட்வொர்க்கை மாற்றவும். மாற்ற, தட்டவும்."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"அவசர அழைப்பைச் செய்ய முடியாது"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"அவசர அழைப்புகளுக்கு மொபைல் நெட்வொர்க் தேவை"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"விழிப்பூட்டல்கள்"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"அழைப்பு திருப்பிவிடுதல்"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"அவசரகாலத் திரும்ப அழைக்கும் பயன்முறை"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"நீக்கு"</string>
     <string name="inputMethod" msgid="1784759500516314751">"உள்ளீட்டு முறை"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"உரை நடவடிக்கைகள்"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"இந்தப் புலத்தில் கையெழுத்து ஆதரிக்கப்படவில்லை"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"கடவுச்சொல் புலங்களில் கையெழுத்து ஆதரிக்கப்படவில்லை"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"பின்செல்லும்"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"உள்ளீட்டு முறையை மாற்றும்"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"சேமிப்பிடம் குறைகிறது"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"நிர்வகிப்பது: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ஆன்"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ஆஃப்"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ஏதேனும் கேலெண்டர்"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> சில ஒலிகளை முடக்குகிறது"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"சாதனத்தில் அகச் சிக்கல் இருக்கிறது, அதனை ஆரம்பநிலைக்கு மீட்டமைக்கும் வரை நிலையற்று இயங்கலாம்."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"சாதனத்தில் அகச் சிக்கல் இருக்கிறது. விவரங்களுக்கு சாதன தயாரிப்பாளரைத் தொடர்புகொள்ளவும்."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"பரிசோதனை"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"பொது"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"சாட்டிலைட்டுடன் தானாக இணைக்கப்பட்டது"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"மொபைல்/வைஃபை நெட்வொர்க் இல்லாமல் நீங்கள் மெசேஜ்களை அனுப்பலாம் பெறலாம்"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messages ஆப்ஸைத் திறக்கவும்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index c0c7806e0..c64c9b6d 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"మొబైల్ నెట్‌వర్క్ అందుబాటులో లేదు"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ప్రాధాన్య నెట్‌వర్క్‌ను మార్చుకోవడానికి ప్రయత్నించండి. మార్చడానికి నొక్కండి."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"అత్యవసర కాలింగ్ అందుబాటులో లేదు"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ఎమర్జెన్సీ కాల్స్‌కు మొబైల్ నెట్‌వర్క్ అవసరమవుతుంది"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"అలర్ట్‌లు"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"కాల్ ఫార్వార్డింగ్"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"అత్యవసర కాల్‌బ్యాక్ మోడ్"</string>
@@ -828,7 +827,7 @@
     <string name="permdesc_writeVerificationStateE2eeContactKeys" msgid="8453156829747427041">"మీకు సంబంధించిన ఇతర యాప్‌లలోని E2EE కాంటాక్ట్ కీల వెరిఫికేషన్ స్టేట్‌లను అప్‌డేట్ చేయడానికి యాప్‌ను అనుమతిస్తుంది"</string>
     <string name="policylab_limitPassword" msgid="4851829918814422199">"పాస్‌వర్డ్ నియమాలను సెట్ చేయండి"</string>
     <string name="policydesc_limitPassword" msgid="4105491021115793793">"స్క్రీన్ లాక్ పాస్‌వర్డ్‌లు మరియు PINల్లో అనుమతించబడిన పొడవు మరియు అక్షరాలను నియంత్రిస్తుంది."</string>
-    <string name="policylab_watchLogin" msgid="7599669460083719504">"స్క్రీన్ అన్‌లాక్ ప్రయత్నాలను పర్యవేక్షించండి"</string>
+    <string name="policylab_watchLogin" msgid="7599669460083719504">"స్క్రీన్‌ను అన్‌లాక్ చేయడానికి చేస్తున్న ప్రయత్నాలను మానిటర్ చేయడానికి"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="2388436408621909298">"టైప్ చేసిన చెల్లని పాస్‌వర్డ్‌ల సంఖ్యను పర్యవేక్షిస్తుంది. స్క్రీన్‌ను అన్‌లాక్ చేస్తున్నప్పుడు, అనేక సార్లు చెల్లని పాస్‌వర్డ్‌లను టైప్ చేస్తే టాబ్లెట్ లాక్ చేయబడుతుంది లేదా టాబ్లెట్‌లోని మొత్తం డేటా ఎరేజ్ చేయబడుతుంది."</string>
     <string name="policydesc_watchLogin" product="tv" msgid="2140588224468517507">"స్క్రీన్‌ను అన్‌లాక్ చేస్తున్నప్పుడు పాస్‌వర్డ్‌లను ఎన్నిసార్లు తప్పుగా టైప్ చేశారో పర్యవేక్షిస్తుంది, అలాగే చాలా ఎక్కువసార్లు పాస్‌వర్డ్‌లను తప్పుగా టైప్ చేసి ఉంటే మీ Android TV పరికరాన్ని లాక్ చేస్తుంది లేదా మీ Android TV డేటా మొత్తాన్ని తొలగిస్తుంది."</string>
     <string name="policydesc_watchLogin" product="automotive" msgid="7011438994051251521">"స్క్రీన్‌ను అన్‌లాక్ చేస్తున్నప్పుడు, పాస్‌వర్డ్‌ను ఎన్నిసార్లు తప్పుగా టైప్ చేశారో పర్యవేక్షిస్తుంది. ఒకవేళ చాలా ఎక్కువ సార్లు పాస్‌వర్డ్‌ను తప్పుగా టైప్ చేసి ఉంటే, సమాచారంతో కూడిన వినోదం సిస్టమ్‌ను లాక్ చేస్తుంది లేదా సమాచారంతో కూడిన వినోదం సిస్టమ్ డేటాను తొలగించి ఫ్యాక్టరీ రీసెట్ చేస్తుంది."</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"తొలగించండి"</string>
     <string name="inputMethod" msgid="1784759500516314751">"ఇన్‌పుట్ పద్ధతి"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"వచనానికి సంబంధించిన చర్యలు"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"ఈ ఫీల్డ్‌లో చేతిరాతకు సపోర్ట్ లేదు"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"పాస్‌వర్డ్ ఫీల్డ్‌లలో చేతిరాతకు సపోర్ట్ లేదు"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"వెనుకకు"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"ఇన్‌పుట్ విధానాన్ని మార్చండి"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"స్టోరేజ్‌ ఖాళీ అయిపోతోంది"</string>
@@ -1247,10 +1244,10 @@
     <string name="aerr_process_repeated" msgid="1153152413537954974">"<xliff:g id="PROCESS">%1$s</xliff:g> పునరావృతంగా ఆపివేయబడుతోంది"</string>
     <string name="aerr_restart" msgid="2789618625210505419">"యాప్‌ను మళ్లీ తెరువు"</string>
     <string name="aerr_report" msgid="3095644466849299308">"ఫీడ్‌బ్యాక్‌ను పంపు"</string>
-    <string name="aerr_close" msgid="3398336821267021852">"మూసివేయి"</string>
+    <string name="aerr_close" msgid="3398336821267021852">"మూసివేయండి"</string>
     <string name="aerr_mute" msgid="2304972923480211376">"పరికరం పునఃప్రారంభమయ్యే వరకు మ్యూట్ చేయి"</string>
     <string name="aerr_wait" msgid="3198677780474548217">"వేచి ఉండండి"</string>
-    <string name="aerr_close_app" msgid="8318883106083050970">"యాప్‌ను మూసివేయి"</string>
+    <string name="aerr_close_app" msgid="8318883106083050970">"యాప్‌ను మూసివేయండి"</string>
     <string name="anr_title" msgid="7290329487067300120"></string>
     <string name="anr_activity_application" msgid="8121716632960340680">"<xliff:g id="APPLICATION">%2$s</xliff:g> ప్రతిస్పందించడం లేదు"</string>
     <string name="anr_activity_process" msgid="3477362583767128667">"<xliff:g id="ACTIVITY">%1$s</xliff:g> ప్రతిస్పందించడం లేదు"</string>
@@ -1928,10 +1925,13 @@
     <string name="zen_mode_default_weeknights_name" msgid="7902108149994062847">"వారపు రోజుల్లో రాత్రి"</string>
     <string name="zen_mode_default_weekends_name" msgid="4707200272709377930">"వారాంతం"</string>
     <string name="zen_mode_default_events_name" msgid="2280682960128512257">"ఈవెంట్"</string>
-    <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"నిద్రావస్థ"</string>
+    <string name="zen_mode_default_every_night_name" msgid="1467765312174275823">"నిద్ర"</string>
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> ద్వారా మేనేజ్ చేయబడుతోంది"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"ఆన్‌లో ఉంది"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ఆఫ్‌లో ఉంది"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ఏదైనా క్యాలెండర్"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> కొన్ని ధ్వనులను మ్యూట్ చేస్తోంది"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"మీ పరికరంతో అంతర్గత సమస్య ఏర్పడింది మరియు మీరు ఫ్యాక్టరీ డేటా రీసెట్ చేసే వరకు అస్థిరంగా ఉంటుంది."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"మీ పరికరంతో అంతర్గత సమస్య ఏర్పడింది. వివరాల కోసం మీ తయారీదారుని సంప్రదించండి."</string>
@@ -1958,7 +1958,7 @@
     <string name="floating_toolbar_open_overflow_description" msgid="2260297653578167367">"మరిన్ని ఆప్షన్‌లు"</string>
     <string name="floating_toolbar_close_overflow_description" msgid="3949818077708138098">"అతివ్యాప్తిని మూసివేస్తుంది"</string>
     <string name="maximize_button_text" msgid="4258922519914732645">"గరిష్టీకరించు"</string>
-    <string name="close_button_text" msgid="10603510034455258">"మూసివేయి"</string>
+    <string name="close_button_text" msgid="10603510034455258">"మూసివేయండి"</string>
     <string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
     <string name="call_notification_answer_action" msgid="5999246836247132937">"పికప్ చేయండి"</string>
     <string name="call_notification_answer_video_action" msgid="2086030940195382249">"వీడియో కాల్"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"పరీక్ష"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"కమ్యూనల్"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"శాటిలైట్‌కు ఆటోమేటిక్‌గా కనెక్ట్ చేయబడింది"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"మీరు మొబైల్ లేదా Wi-Fi నెట్‌వర్క్ లేకుండా మెసేజ్‌లను పంపవచ్చు, స్వీకరించవచ్చు"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Messagesను తెరవండి"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index c3a3c6d..7555f26 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"เชื่อมต่อเครือข่ายมือถือไม่ได้"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ลองเปลี่ยนเครือข่ายที่ต้องการ แตะเพื่อเปลี่ยน"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"โทรหาหมายเลขฉุกเฉินไม่ได้"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"การโทรหาหมายเลขฉุกเฉินต้องใช้เครือข่ายมือถือ"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"การแจ้งเตือน"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"การโอนสาย"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"โหมดติดต่อกลับฉุกเฉิน"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"ลบ"</string>
     <string name="inputMethod" msgid="1784759500516314751">"วิธีป้อนข้อมูล"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"การทำงานของข้อความ"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"ช่องนี้ไม่รองรับการเขียนด้วยลายมือ"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"ช่องรหัสผ่านไม่รองรับการเขียนด้วยลายมือ"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"กลับ"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"สลับวิธีการป้อนข้อมูล"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"พื้นที่จัดเก็บเหลือน้อย"</string>
@@ -1300,12 +1297,12 @@
     <string name="new_app_action" msgid="547772182913269801">"เปิด <xliff:g id="NEW_APP">%1$s</xliff:g>"</string>
     <string name="new_app_description" msgid="1958903080400806644">"<xliff:g id="OLD_APP">%1$s</xliff:g> จะปิดโดยไม่บันทึก"</string>
     <string name="dump_heap_notification" msgid="5316644945404825032">"<xliff:g id="PROC">%1$s</xliff:g> เกินขีดจำกัดของหน่วยความจำ"</string>
-    <string name="dump_heap_ready_notification" msgid="2302452262927390268">"ฮีพดัมพ์ <xliff:g id="PROC">%1$s</xliff:g> พร้อมแล้ว"</string>
-    <string name="dump_heap_notification_detail" msgid="8431586843001054050">"รวบรวมฮีพดัมพ์แล้ว แตะเพื่อแชร์"</string>
-    <string name="dump_heap_title" msgid="4367128917229233901">"แชร์ฮีพดัมพ์ไหม"</string>
-    <string name="dump_heap_text" msgid="1692649033835719336">"กระบวนการ <xliff:g id="PROC">%1$s</xliff:g> ใช้หน่วยความจำเกินขีดจำกัดขนาด <xliff:g id="SIZE">%2$s</xliff:g> มีฮีพดัมพ์พร้อมให้แชร์กับนักพัฒนาซอฟต์แวร์ โปรดระวัง: ฮีพดัมพ์นี้อาจมีข้อมูลส่วนบุคคลที่มีความละเอียดอ่อนซึ่งแอปพลิเคชันเข้าถึงได้"</string>
-    <string name="dump_heap_system_text" msgid="6805155514925350849">"กระบวนการ <xliff:g id="PROC">%1$s</xliff:g> ใช้หน่วยความจำเกินขีดจำกัดขนาด <xliff:g id="SIZE">%2$s</xliff:g> มีฮีพดัมพ์พร้อมให้แชร์ โปรดระวัง: ฮีพดัมพ์นี้อาจมีข้อมูลส่วนบุคคลที่มีความละเอียดอ่อนซึ่งกระบวนการดังกล่าวเข้าถึงได้ ซึ่งอาจรวมถึงข้อมูลต่างๆ ที่คุณพิมพ์ไว้"</string>
-    <string name="dump_heap_ready_text" msgid="5849618132123045516">"มีฮีพดัมพ์ของกระบวนการ <xliff:g id="PROC">%1$s</xliff:g> พร้อมให้แชร์ โปรดระวัง: ฮีพดัมพ์นี้อาจมีข้อมูลส่วนบุคคลที่มีความละเอียดอ่อนซึ่งกระบวนการดังกล่าวเข้าถึงได้ ซึ่งอาจรวมถึงข้อมูลต่างๆ ที่คุณพิมพ์ไว้"</string>
+    <string name="dump_heap_ready_notification" msgid="2302452262927390268">"ฮีปดัมป์ <xliff:g id="PROC">%1$s</xliff:g> พร้อมแล้ว"</string>
+    <string name="dump_heap_notification_detail" msgid="8431586843001054050">"รวบรวมฮีปดัมป์แล้ว แตะเพื่อแชร์"</string>
+    <string name="dump_heap_title" msgid="4367128917229233901">"แชร์ฮีปดัมป์ไหม"</string>
+    <string name="dump_heap_text" msgid="1692649033835719336">"กระบวนการ <xliff:g id="PROC">%1$s</xliff:g> ใช้หน่วยความจำเกินขีดจำกัดขนาด <xliff:g id="SIZE">%2$s</xliff:g> มีฮีปดัมป์พร้อมให้แชร์กับนักพัฒนาซอฟต์แวร์ โปรดระวัง: ฮีปดัมป์นี้อาจมีข้อมูลส่วนบุคคลที่มีความละเอียดอ่อนซึ่งแอปพลิเคชันเข้าถึงได้"</string>
+    <string name="dump_heap_system_text" msgid="6805155514925350849">"กระบวนการ <xliff:g id="PROC">%1$s</xliff:g> ใช้หน่วยความจำเกินขีดจำกัดขนาด <xliff:g id="SIZE">%2$s</xliff:g> มีฮีปดัมป์พร้อมให้แชร์ โปรดระวัง: ฮีปดัมป์นี้อาจมีข้อมูลส่วนบุคคลที่มีความละเอียดอ่อนซึ่งกระบวนการดังกล่าวเข้าถึงได้ ซึ่งอาจรวมถึงข้อมูลต่างๆ ที่คุณพิมพ์ไว้"</string>
+    <string name="dump_heap_ready_text" msgid="5849618132123045516">"มีฮีปดัมป์ของกระบวนการ <xliff:g id="PROC">%1$s</xliff:g> พร้อมให้แชร์ โปรดระวัง: ฮีปดัมป์นี้อาจมีข้อมูลส่วนบุคคลที่มีความละเอียดอ่อนซึ่งกระบวนการดังกล่าวเข้าถึงได้ ซึ่งอาจรวมถึงข้อมูลต่างๆ ที่คุณพิมพ์ไว้"</string>
     <string name="sendText" msgid="493003724401350724">"เลือกการทำงานกับข้อความ"</string>
     <string name="volume_ringtone" msgid="134784084629229029">"ระดับความดังเสียงเรียกเข้า"</string>
     <string name="volume_music" msgid="7727274216734955095">"ระดับเสียงของสื่อ"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"จัดการโดย <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"เปิด"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"ปิด"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"ปฏิทินทั้งหมด"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> กำลังปิดเสียงบางรายการ"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"อุปกรณ์ของคุณเกิดปัญหาภายในเครื่อง อุปกรณ์อาจทำงานไม่เสถียรจนกว่าคุณจะรีเซ็ตข้อมูลเป็นค่าเริ่มต้น"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"อุปกรณ์ของคุณเกิดปัญหาภายในเครื่อง โปรดติดต่อผู้ผลิตเพื่อขอรายละเอียดเพิ่มเติม"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"ทดสอบ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"ส่วนกลาง"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"เชื่อมต่อกับดาวเทียมโดยอัตโนมัติ"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"คุณรับส่งข้อความผ่านดาวเทียมได้โดยไม่ต้องใช้เครือข่ายมือถือหรือ Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"เปิด Messages"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 717b9e0..112da5c 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Hindi makakonekta sa mobile network"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Subukang baguhin ang gustong network. I-tap para baguhin."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Hindi available ang pang-emergency na pagtawag"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Kailangan ng mobile network para sa mga emergency na tawag"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Mga Alerto"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Pagpasa ng tawag"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Emergency callback mode"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"I-delete"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Pamamaraan ng pag-input"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Pagkilos ng teksto"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Hindi sinusuportahan ang sulat-kamay sa field na ito"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Hindi sinusuportahan ang sulat-kamay sa mga field ng password"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Bumalik"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Magpalit ng pamamaraan ng pag-input"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Nauubusan na ang puwang ng storage"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Pinapamahalaan ng <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Naka-on"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Naka-off"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>, <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Anumang kalendaryo"</string>
     <string name="muted_by" msgid="91464083490094950">"Minu-mute ng <xliff:g id="THIRD_PARTY">%1$s</xliff:g> ang ilang tunog"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"May internal na problema sa iyong device, at maaaring hindi ito maging stable hanggang sa i-reset mo ang factory data."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"May internal na problema sa iyong device. Makipag-ugnayan sa iyong manufacturer upang malaman ang mga detalye."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Awtomatikong nakakonekta sa satellite"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Puwede kang magpadala at tumanggap ng mga mensahe nang walang mobile o Wi-Fi network"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Buksan ang Messages"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 03a6577..2ca545b 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobil ağa erişilemiyor"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tercih edilen ağı değiştirmeyi deneyin. Değiştirmek için dokunun."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Acil durum çağrısı kullanılamaz"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Acil durum aramaları için mobil ağ gereklidir"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Uyarılar"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Çağrı yönlendirme"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Acil geri arama modu"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Sil"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Giriş yöntemi"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Metin eylemleri"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"El yazısı bu alanda desteklenmiyor"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"El yazısı, şifre alanlarında desteklenmiyor"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Geri"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Giriş yöntemini değiştir"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Depolama alanı bitiyor"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> tarafından yönetiliyor"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Açık"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Kapalı"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>-<xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Tüm takvimler"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> bazı sesleri kapatıyor"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Cihazınızla ilgili dahili bir sorun oluştu ve fabrika verilerine sıfırlama işlemi gerçekleştirilene kadar kararsız çalışabilir."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Cihazınızla ilgili dahili bir sorun oluştu. Ayrıntılı bilgi için üreticinizle iletişim kurun."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Paylaşılan"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Uyduya otomatik olarak bağlandı"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil veya kablosuz ağa bağlı olmadan mesaj alıp gönderebilirsiniz"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mesajlar\'ı aç"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index a8c86d4..df2c715 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -86,8 +86,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Не вдається під’єднатися до мобільної мережі"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Спробуйте змінити вибрану мережу. Торкніться, щоб це зробити."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Екстрені виклики недоступні"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Щоб здійснювати екстрені виклики, потрібне з’єднання з мобільною мережею"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Сповіщення"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Переадресація виклику"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Режим екстреного зворотного виклику"</string>
@@ -1186,10 +1185,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Видалити"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Метод введення"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Дії з текстом"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Рукописне введення не підтримується в цьому полі"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Рукописне введення не підтримується в полях паролів"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Назад"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Змінити метод введення"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Закінчується пам’ять"</string>
@@ -1934,6 +1931,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Керує додаток <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Увімкнено"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Вимкнено"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"З усіх календарів"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> вимикає деякі звуки"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Через внутрішню помилку ваш пристрій може працювати нестабільно. Відновіть заводські налаштування."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"На пристрої сталася внутрішня помилка. Зв’яжіться з виробником пристрою, щоб дізнатися більше."</string>
@@ -2138,7 +2138,7 @@
     <string name="nas_upgrade_notification_enable_action" msgid="3046406808378726874">"OK"</string>
     <string name="nas_upgrade_notification_disable_action" msgid="3794833210043497982">"Вимкнути"</string>
     <string name="nas_upgrade_notification_learn_more_action" msgid="7011130656195423947">"Докладніше"</string>
-    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"В Android 12 адаптивні сповіщення замінено на покращені. Ця функція допомагає впорядковувати сповіщення й показує в них пропоновані дії та відповіді.\n\nПокращені сповіщення надають доступ до вмісту сповіщень, зокрема до такої особистої інформації, як повідомлення й імена контактів. Ця функція може автоматично закривати сповіщення чи реагувати на них, наприклад відповідати на телефонні дзвінки або керувати режимом \"Не турбувати\"."</string>
+    <string name="nas_upgrade_notification_learn_more_content" msgid="3735480566983530650">"В Android 12 адаптивні сповіщення замінено на покращені. Ця функція допомагає впорядковувати сповіщення й показує в них пропоновані дії і відповіді.\n\nПокращені сповіщення надають доступ до вмісту сповіщень, зокрема до такої особистої інформації, як повідомлення й імена контактів. Ця функція може автоматично закривати сповіщення чи реагувати на них, наприклад відповідати на телефонні дзвінки або керувати режимом \"Не турбувати\"."</string>
     <string name="dynamic_mode_notification_channel_name" msgid="2986926422100223328">"Сповіщення про програму"</string>
     <string name="dynamic_mode_notification_title" msgid="1388718452788985481">"Режим енергозбереження ввімкнено"</string>
     <string name="dynamic_mode_notification_summary" msgid="1639031262484979689">"Заряд використовується економно, щоб подовжити час роботи акумулятора"</string>
@@ -2396,6 +2396,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Тестовий профіль"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Спільний профіль"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Автоматично підключено до супутника"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Ви можете надсилати й отримувати повідомлення, не використовуючи Wi-Fi або мобільну мережу"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Відкрийте Повідомлення"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 05184fc..29bd5be 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"موبائل نیٹ ورک تک رسائی نہیں ہو سکتی"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"ترجیحی نیٹ ورک تبدیل کر کے دیکھیں۔ تبدیل کرنے کے لیے تھپتھپائیں۔"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"ایمرجنسی کالنگ دستیاب نہیں ہے"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"ہنگامی کالز کو موبائل نیٹ ورک کی ضرورت ہے"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"الرٹس"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"کال فارورڈنگ"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"ایمرجنسی کال بیک وضع"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"حذف کریں"</string>
     <string name="inputMethod" msgid="1784759500516314751">"اندراج کا طریقہ"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"متن کی کارروائیاں"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"اس فیلڈ میں ہینڈ رائٹنگ تعاون یافتہ نہیں ہے"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"ہینڈ رائٹنگ پاس ورڈ فیلڈز میں تعاون یافتہ نہیں ہے"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"پیچھے"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"اندراج کا طریقہ سوئچ کریں"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"اسٹوریج کی جگہ ختم ہو رہی ہے"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے زیر انتظام ہے"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"آن ہے"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"آف ہے"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"، "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"کوئی بھی کیلنڈر"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> کچھ آوازوں کو خاموش کر رہا ہے"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"آپ کے آلہ میں ایک داخلی مسئلہ ہے اور جب تک آپ فیکٹری ڈیٹا کو دوبارہ ترتیب نہیں دے دیتے ہیں، ہوسکتا ہے کہ یہ غیر مستحکم رہے۔"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"آپ کے آلہ میں ایک داخلی مسئلہ ہے۔ تفصیلات کیلئے اپنے مینوفیکچرر سے رابطہ کریں۔"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"ٹیسٹ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"کمیونل"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"سٹلائٹ سے خودکار طور پر منسلک ہے"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"‏آپ موبائل یا Wi-Fi نیٹ ورک کے بغیر پیغامات بھیج اور موصول کر سکتے ہیں"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"پیغامات ایپ کو کھولیں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index dc31f00..dddc3d6 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Mobil tarmoqqa ulanib bo‘lmadi"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Tarmoq turini almashtiring. Almashtirish uchun bosing."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Favqulodda chaqiruv ishlamayapti"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Favqulodda chaqiruvlar uchun mobil tarmoq zarur"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Ogohlantirishlar"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Chaqiruvlarni uzatish"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Favqulodda qaytarib chaqirish rejimi"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"O‘chirish"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Kiritish uslubi"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Matn yozish"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Bu qatorda qoʻlyozma ishlatish imkonsiz"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Parol qatorlarida qoʻlyozma ishlatish imkonsiz"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Orqaga"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Matn kiritish usulini almashtirish"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Xotirada joy yetarli emas"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"<xliff:g id="APP_NAME">%1$s</xliff:g> tomonidan boshqariladi"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Yoniq"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Oʻchiq"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Har qanday taqvim"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ayrim tovushlarni ovozsiz qilgan"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Qurilmangiz bilan bog‘liq ichki muammo mavjud. U zavod sozlamalari tiklanmaguncha barqaror ishlamasligi mumkin."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Qurilmangiz bilan bog‘liq ichki muammo mavjud. Tafsilotlar uchun qurilmangiz ishlab chiqaruvchisiga murojaat qiling."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Umumiy"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Sputnikka avtomatik ulandi"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Mobil yoki Wi-Fi tarmoqsiz xabarlarni yuborishingiz va qabul qilishingiz mumkin"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Xabarlar ilovasini ochish"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index d82487e..073a1a8 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"Không thể kết nối với mạng di động"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"Hãy thử thay đổi mạng ưu tiên. Nhấn để thay đổi."</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"Không có dịch vụ gọi khẩn cấp"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"Cần có mạng di động để thực hiện các cuộc gọi khẩn cấp"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"Thông báo"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"Chuyển tiếp cuộc gọi"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"Chế độ gọi lại khẩn cấp"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"Xóa"</string>
     <string name="inputMethod" msgid="1784759500516314751">"Phương thức nhập"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"Tác vụ văn bản"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"Trường này không hỗ trợ tính năng Viết tay"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"Các trường mật khẩu không hỗ trợ tính năng Viết tay"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"Quay lại"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"Chuyển phương thức nhập"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"Sắp hết dung lượng lưu trữ"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Do <xliff:g id="APP_NAME">%1$s</xliff:g> quản lý"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Bật"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Tắt"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> – <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Bất kỳ lịch nào"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> đang tắt một số âm thanh"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Đã xảy ra sự cố nội bộ với thiết bị của bạn và thiết bị có thể sẽ không ổn định cho tới khi bạn thiết lập lại dữ liệu ban đầu."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Đã xảy ra sự cố nội bộ với thiết bị. Hãy liên hệ với nhà sản xuất của bạn để biết chi tiết."</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Kiểm thử"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Dùng chung"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Đã tự động kết nối với vệ tinh"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Bạn có thể gửi và nhận tin nhắn mà không cần có mạng di động hoặc mạng Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Mở ứng dụng Tin nhắn"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index d1f7d32..ff2d4fc 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"无法连接到移动网络"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"请尝试更改首选网络。点按即可更改。"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"无法使用紧急呼救服务"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"紧急呼叫需要使用移动网络"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"提醒"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"来电转接"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"紧急回拨模式"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"删除"</string>
     <string name="inputMethod" msgid="1784759500516314751">"输入法"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"文字操作"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"无法在此字段中使用手写功能"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"无法在密码字段中使用手写功能"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"返回"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"切换输入法"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"存储空间不足"</string>
@@ -1286,7 +1283,7 @@
     <string name="android_upgrading_starting_apps" msgid="6206161195076057075">"正在启动应用。"</string>
     <string name="android_upgrading_complete" msgid="409800058018374746">"即将完成启动。"</string>
     <string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"您已按电源按钮,这通常会关闭屏幕。\n\n请尝试在设置指纹时轻轻按一下。"</string>
-    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"若要结束设置,请关闭屏幕"</string>
+    <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"结束设置,请关闭屏幕"</string>
     <string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"关闭"</string>
     <string name="fp_power_button_bp_title" msgid="5585506104526820067">"要继续验证您的指纹吗?"</string>
     <string name="fp_power_button_bp_message" msgid="2983163038168903393">"您已按电源按钮,这通常会关闭屏幕。\n\n请尝试轻轻按一下来验证您的指纹。"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"由<xliff:g id="APP_NAME">%1$s</xliff:g>管理"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"已启用"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"已停用"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"、 "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"所有日历"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>正在将某些音效设为静音"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"您的设备内部出现了问题。如果不将设备恢复出厂设置,设备运行可能会不稳定。"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"您的设备内部出现了问题。请联系您的设备制造商了解详情。"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"测试"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"共用"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"自动连接到卫星"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"您无需使用移动网络或 WLAN 网络便能收发消息"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"打开“信息”应用"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index c914fd1..6f560bb 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"無法連線至流動網絡"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"請嘗試變更偏好的網絡。輕按即可變更。"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"無法撥打緊急電話"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"撥打緊急電話需要使用流動網絡"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"通知"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"來電轉駁"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"緊急回撥模式"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"刪除"</string>
     <string name="inputMethod" msgid="1784759500516314751">"輸入法"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"文字操作"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"此欄位無法使用手寫功能"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"密碼欄位無法使用手寫功能"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"返回"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"切換輸入方法"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"儲存空間即將用盡"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"由<xliff:g id="APP_NAME">%1$s</xliff:g>管理"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"已開啟"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"已關閉"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"、 "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"任何日曆"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>正將某些音效設為靜音"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"你裝置的系統發生問題,回復原廠設定後即可解決該問題。"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"你裝置的系統發生問題,請聯絡你的製造商瞭解詳情。"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"測試"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"共用"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"已自動連線至衛星"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"你可在沒有流動/Wi-Fi 網絡的情況下收發訊息"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 8ac4531..8b2d534 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -84,8 +84,7 @@
     <string name="NetworkPreferenceSwitchTitle" msgid="1008329951315753038">"無法連上行動網路"</string>
     <string name="NetworkPreferenceSwitchSummary" msgid="2086506181486324860">"請嘗試變更偏好的網路。輕觸即可變更。"</string>
     <string name="EmergencyCallWarningTitle" msgid="1615688002899152860">"無法撥打緊急電話"</string>
-    <!-- no translation found for EmergencyCallWarningSummary (9102799172089265268) -->
-    <skip />
+    <string name="EmergencyCallWarningSummary" msgid="9102799172089265268">"撥打緊急電話需要使用行動網路"</string>
     <string name="notification_channel_network_alert" msgid="4788053066033851841">"快訊"</string>
     <string name="notification_channel_call_forward" msgid="8230490317314272406">"來電轉接"</string>
     <string name="notification_channel_emergency_callback" msgid="54074839059123159">"緊急回撥模式"</string>
@@ -1184,10 +1183,8 @@
     <string name="deleteText" msgid="4200807474529938112">"刪除"</string>
     <string name="inputMethod" msgid="1784759500516314751">"輸入法"</string>
     <string name="editTextMenuTitle" msgid="857666911134482176">"文字動作"</string>
-    <!-- no translation found for error_handwriting_unsupported (7809438534946014050) -->
-    <skip />
-    <!-- no translation found for error_handwriting_unsupported_password (5095401146106891087) -->
-    <skip />
+    <string name="error_handwriting_unsupported" msgid="7809438534946014050">"這個欄位無法使用手寫功能"</string>
+    <string name="error_handwriting_unsupported_password" msgid="5095401146106891087">"密碼欄位無法使用手寫功能"</string>
     <string name="input_method_nav_back_button_desc" msgid="3655838793765691787">"返回"</string>
     <string name="input_method_ime_switch_button_desc" msgid="2736542240252198501">"切換輸入法"</string>
     <string name="low_internal_storage_view_title" msgid="9024241779284783414">"儲存空間即將用盡"</string>
@@ -1932,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"由「<xliff:g id="APP_NAME">%1$s</xliff:g>」管理"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"已啟用"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"已停用"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">"、 "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g> - <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"任何日曆"</string>
     <string name="muted_by" msgid="91464083490094950">"「<xliff:g id="THIRD_PARTY">%1$s</xliff:g>」正在關閉部分音效"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"你的裝置發生內部問題,必須將裝置恢復原廠設定才能解除不穩定狀態。"</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"你的裝置發生內部問題,詳情請洽裝置製造商。"</string>
@@ -2394,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"測試"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"通用"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"已自動連上衛星"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"你可以收發訊息,沒有行動/Wi-Fi 網路也無妨"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"開啟「訊息」應用程式"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index eb75d2a..922172c 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1929,6 +1929,9 @@
     <string name="zen_mode_implicit_trigger_description" msgid="5714956693073007111">"Iphethwe yi-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="zen_mode_implicit_activated" msgid="2634285680776672994">"Kuvuliwe"</string>
     <string name="zen_mode_implicit_deactivated" msgid="8688441768371501750">"Kuvaliwe"</string>
+    <string name="zen_mode_trigger_summary_divider_text" msgid="7461583466043698862">", "</string>
+    <string name="zen_mode_trigger_summary_range_symbol_combination" msgid="1804900738798069619">"<xliff:g id="START">%1$s</xliff:g>, <xliff:g id="END">%2$s</xliff:g>"</string>
+    <string name="zen_mode_trigger_event_calendar_any" msgid="2086784607921121803">"Noma iyiphi ikhalenda"</string>
     <string name="muted_by" msgid="91464083490094950">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ithulisa eminye imisindo"</string>
     <string name="system_error_wipe_data" msgid="5910572292172208493">"Kukhona inkinga yangaphakathi ngedivayisi yakho, futhi ingase ibe engazinzile kuze kube yilapho usetha kabusha yonke idatha."</string>
     <string name="system_error_manufacturer" msgid="703545241070116315">"Kukhona inkinga yangaphakathi ngedivayisi yakho. Xhumana nomkhiqizi wakho ukuze uthole imininingwane."</string>
@@ -2391,6 +2394,8 @@
     <string name="profile_label_test" msgid="9168641926186071947">"Hlola"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Okomphakathi"</string>
     <string name="redacted_notification_action_title" msgid="6942924973335920935"></string>
+    <!-- no translation found for screen_not_shared_sensitive_content (7058419185079565001) -->
+    <skip />
     <string name="satellite_notification_title" msgid="4026338973463121526">"Ixhumeke ngokuzenzakalelayo kusathelayithi"</string>
     <string name="satellite_notification_summary" msgid="5207364139430767162">"Ungathumela futhi wamukele imilayezo ngaphandle kwenethiwekhi yeselula noma ye-Wi-Fi"</string>
     <string name="satellite_notification_open_message" msgid="4149234979688273729">"Vula Imilayezo"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 81c79f2..b262ebd 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2400,7 +2400,9 @@
              have been requested to be translucent with
              {@link android.R.attr#windowTranslucentStatus}.
              Corresponds to setting {@link android.view.View#SYSTEM_UI_FLAG_LIGHT_STATUS_BAR} on
-             the decor view. -->
+             the decor view and
+             {@link android.view.WindowInsetsController#APPEARANCE_LIGHT_STATUS_BARS} on the
+             {@link android.view.WindowInsetsController}. -->
         <attr name="windowLightStatusBar" format="boolean" />
 
         <!-- Reference to a drawable to be used as the splash screen content of the window. This
@@ -2422,7 +2424,9 @@
              have been requested to be translucent with
              {@link android.R.attr#windowTranslucentNavigation}.
              Corresponds to setting {@link android.view.View#SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR} on
-             the decor view. -->
+             the decor view and
+             {@link android.view.WindowInsetsController#APPEARANCE_LIGHT_NAVIGATION_BARS} on the
+             {@link android.view.WindowInsetsController}. -->
         <attr name="windowLightNavigationBar" format="boolean" />
 
         <!-- Controls how the window is laid out if there is a {@code DisplayCutout}.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a926a70..d4db244 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2883,6 +2883,13 @@
     -->
     <integer name="config_minimumScreenOffTimeout">10000</integer>
 
+    <!-- User activity timeout: Screen timeout override in milliseconds.
+
+         This value must be greater than 0, otherwise the invalid value will not apply to
+         the screen timeout override policy.
+    -->
+    <integer name="config_screenTimeoutOverride">-1</integer>
+
     <!-- User activity timeout: Maximum screen dim duration in milliseconds.
 
          Sets an upper bound for how long the screen will dim before the device goes
@@ -3344,6 +3351,11 @@
         com.android.systemui/com.android.systemui.tv.hdmi.HdmiCecSetMenuLanguageActivity
     </string>
 
+    <!-- Component name of the activity used to inform user that their device lost Active Source
+      status and will go to standby if there is no interaction. -->
+    <string name="config_hdmiCecActiveSourceLostActivity"
+    >com.android.systemui/com.android.systemui.tv.hdmi.HdmiCecActiveSourceLostActivity</string>
+
     <!-- Name of the dialog that is used to request the user's consent for a Platform VPN -->
     <string name="config_platformVpnConfirmDialogComponent" translatable="false"
             >com.android.vpndialogs/com.android.vpndialogs.PlatformVpnConfirmDialog</string>
@@ -4800,6 +4812,18 @@
      See android.credentials.CredentialManager
     -->
     <string name="config_defaultCredentialManagerHybridService" translatable="false"></string>
+    
+    <!-- The component name, flattened to a string, for the system's credential manager
+      autofill service. This service allows interceding autofill requests and routing
+      them to credential manager.
+
+     This service must be trusted, as it can be activated without explicit consent of the user.
+     If no service with the specified name exists on the device, autofill will still
+     work with the user configured autofill service
+
+     See android.credentials.CredentialManager
+    -->
+    <string name="config_defaultCredentialManagerAutofillService" translatable="false"></string>
 
     <!-- The component name(s), flattened to a string, for the system's credential manager
       provider services. These services allow retrieving and storing credentials.
@@ -6990,4 +7014,8 @@
 
     <!-- Whether desktop mode is supported on the current device  -->
     <bool name="config_isDesktopModeSupported">false</bool>
+
+    <!-- Frame rate compatibility value for Wallpaper
+         FRAME_RATE_COMPATIBILITY_MIN (102) is used by default for lower power consumption -->
+    <integer name="config_wallpaperFrameRateCompatibility">102</integer>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index c6706cb..f3aa27f 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -6443,6 +6443,9 @@
     <!-- Notification action title used instead of a notification's normal title sensitive [CHAR_LIMIT=NOTIF_BODY] -->
     <string name="redacted_notification_action_title"></string>
 
+    <!-- Toast when an app's content is hidden from screen share (user can still see content) due to potential security risks of showing the content (such as a password or OTP) - [CHAR_LIMIT=TOAST] -->
+    <string name="screen_not_shared_sensitive_content">App content hidden from screen share for security</string>
+
     <!-- Satellite related messages -->
     <!-- Notification title when satellite service is connected. -->
     <string name="satellite_notification_title">Auto connected to satellite</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fe4e4f04..f33e277 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -390,6 +390,7 @@
   <java-symbol type="string" name="config_sensorUseStartedActivity_hwToggle" />
   <java-symbol type="string" name="config_sensorStateChangedActivity" />
   <java-symbol type="string" name="config_hdmiCecSetMenuLanguageActivity" />
+  <java-symbol type="string" name="config_hdmiCecActiveSourceLostActivity" />
   <java-symbol type="integer" name="config_minNumVisibleRecentTasks_lowRam" />
   <java-symbol type="integer" name="config_maxNumVisibleRecentTasks_lowRam" />
   <java-symbol type="integer" name="config_minNumVisibleRecentTasks" />
@@ -2285,6 +2286,7 @@
   <java-symbol type="bool" name="config_powerDecoupleAutoSuspendModeFromDisplay" />
   <java-symbol type="bool" name="config_powerDecoupleInteractiveModeFromDisplay" />
   <java-symbol type="integer" name="config_minimumScreenOffTimeout" />
+  <java-symbol type="integer" name="config_screenTimeoutOverride" />
   <java-symbol type="integer" name="config_maximumScreenDimDuration" />
   <java-symbol type="fraction" name="config_maximumScreenDimRatio" />
   <java-symbol type="integer" name="config_attentiveTimeout" />
@@ -3904,6 +3906,7 @@
   <java-symbol type="string" name="config_defaultAppPredictionService" />
   <java-symbol type="string" name="config_defaultContentSuggestionsService" />
   <java-symbol type="string" name="config_defaultCredentialManagerHybridService" />
+  <java-symbol type="string" name="config_defaultCredentialManagerAutofillService" />
   <java-symbol type="array" name="config_enabledCredentialProviderService" />
   <java-symbol type="array" name="config_primaryCredentialProviderService" />
   <java-symbol type="string" name="config_defaultSearchUiService" />
@@ -5206,9 +5209,10 @@
   <java-symbol type="string" name="keyboard_layout_notification_multiple_selected_title"/>
   <java-symbol type="string" name="keyboard_layout_notification_multiple_selected_message"/>
 
-  <!-- For redacted notifications -->
+  <!-- For redacted notifications and screen sharing-->
   <java-symbol type="string" name="redacted_notification_message"/>
   <java-symbol type="string" name="redacted_notification_action_title"/>
+  <java-symbol type="string" name="screen_not_shared_sensitive_content"/>
 
   <java-symbol type="bool" name="config_batteryStatsResetOnUnplugHighBatteryLevel" />
   <java-symbol type="bool" name="config_batteryStatsResetOnUnplugAfterSignificantCharge" />
@@ -5394,4 +5398,7 @@
 
   <!-- Whether desktop mode is supported on the current device  -->
   <java-symbol type="bool" name="config_isDesktopModeSupported" />
+
+  <!-- Frame rate compatibility value for Wallpaper -->
+  <java-symbol type="integer" name="config_wallpaperFrameRateCompatibility" />
 </resources>
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 24031cad..4808204 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -134,6 +134,8 @@
         ":BinderDeathRecipientHelperApp1",
         ":BinderDeathRecipientHelperApp2",
         ":com.android.cts.helpers.aosp",
+        ":BinderProxyCountingTestApp",
+        ":BinderProxyCountingTestService",
     ],
 }
 
diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml
index 05b309b..bf2a5b8 100644
--- a/core/tests/coretests/AndroidTest.xml
+++ b/core/tests/coretests/AndroidTest.xml
@@ -22,6 +22,8 @@
         <option name="test-file-name" value="FrameworksCoreTests.apk" />
         <option name="test-file-name" value="BinderDeathRecipientHelperApp1.apk" />
         <option name="test-file-name" value="BinderDeathRecipientHelperApp2.apk" />
+        <option name="test-file-name" value="BinderProxyCountingTestApp.apk" />
+        <option name="test-file-name" value="BinderProxyCountingTestService.apk" />
     </target_preparer>
 
     <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
diff --git a/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml b/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml
index a971730..c8407b8 100644
--- a/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml
+++ b/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml
@@ -16,6 +16,9 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.frameworks.coretests.binderproxycountingtestapp">
 
+    <queries>
+        <package android:name="com.android.frameworks.coretests.binderproxycountingtestservice" />
+    </queries>
     <application>
         <service android:name=".BpcTestAppCmdService"
                  android:exported="true"/>
diff --git a/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java b/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java
index 5aae1203..a7e97d3 100644
--- a/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java
+++ b/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java
@@ -17,14 +17,15 @@
 package com.android.frameworks.coretests.binderproxycountingtestapp;
 
 import android.app.Service;
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.ServiceConnection;
+import android.database.ContentObserver;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.provider.Settings;
 import android.util.Log;
 
 import com.android.frameworks.coretests.aidl.IBinderProxyCountingService;
@@ -49,24 +50,20 @@
 
     private IBpcTestAppCmdService.Stub mBinder = new IBpcTestAppCmdService.Stub() {
 
-        private ArrayList<BroadcastReceiver> mBrList = new ArrayList();
+        private ArrayList<ContentObserver> mCoList = new ArrayList();
         private ArrayList<ITestRemoteCallback> mTrcList = new ArrayList();
+        private Handler mHandler = new Handler();
 
         @Override
         public void createSystemBinders(int count) {
             int i = 0;
             while (i++ < count) {
-                BroadcastReceiver br = new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-
-                    }
-                };
-                IntentFilter filt = new IntentFilter(Intent.ACTION_POWER_DISCONNECTED);
-                synchronized (mBrList) {
-                    mBrList.add(br);
+                final ContentObserver co = new ContentObserver(mHandler) {};
+                synchronized (mCoList) {
+                    mCoList.add(co);
                 }
-                registerReceiver(br, filt);
+                getContentResolver().registerContentObserver(
+                        Settings.System.CONTENT_URI, false, co);
             }
         }
 
@@ -74,11 +71,11 @@
         public void releaseSystemBinders(int count) {
             int i = 0;
             while (i++ < count) {
-                BroadcastReceiver br;
-                synchronized (mBrList) {
-                    br = mBrList.remove(0);
+                ContentObserver co;
+                synchronized (mCoList) {
+                    co = mCoList.remove(0);
                 }
-                unregisterReceiver(br);
+                getContentResolver().unregisterContentObserver(co);
             }
         }
 
@@ -117,9 +114,9 @@
 
         @Override
         public void releaseAllBinders() {
-            synchronized (mBrList) {
-                while (mBrList.size() > 0) {
-                    unregisterReceiver(mBrList.remove(0));
+            synchronized (mCoList) {
+                while (mCoList.size() > 0) {
+                    getContentResolver().unregisterContentObserver(mCoList.remove(0));
                 }
             }
             synchronized (mTrcList) {
@@ -179,4 +176,4 @@
     public IBinder onBind(Intent intent) {
         return mBinder;
     }
-}
\ No newline at end of file
+}
diff --git a/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java b/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java
index 6bed2a2..0f1accc 100644
--- a/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java
+++ b/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java
@@ -55,8 +55,8 @@
         }
 
         @Override
-        public void setBinderProxyWatermarks(int high, int low) {
-            BinderInternal.nSetBinderProxyCountWatermarks(high, low);
+        public void setBinderProxyWatermarks(int high, int low, int warning) {
+            BinderInternal.nSetBinderProxyCountWatermarks(high, low, warning);
         }
 
         @Override
@@ -68,12 +68,23 @@
         public void setBinderProxyCountCallback(IBpcCallbackObserver observer) {
             if (observer != null) {
                 BinderInternal.setBinderProxyCountCallback(
-                        new BinderInternal.BinderProxyLimitListener() {
+                        new BinderInternal.BinderProxyCountEventListener() {
                             @Override
                             public void onLimitReached(int uid) {
                                 try {
                                     synchronized (observer) {
-                                        observer.onCallback(uid);
+                                        observer.onLimitReached(uid);
+                                    }
+                                } catch (Exception e) {
+                                    Log.e(TAG, e.toString());
+                                }
+                            }
+
+                            @Override
+                            public void onWarningThresholdReached(int uid) {
+                                try {
+                                    synchronized (observer) {
+                                        observer.onWarningThresholdReached(uid);
                                     }
                                 } catch (Exception e) {
                                     Log.e(TAG, e.toString());
@@ -98,4 +109,4 @@
         mHandlerThread.start();
         mHandler = new Handler(mHandlerThread.getLooper());
     }
-}
\ No newline at end of file
+}
diff --git a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl
index c4ebd56..ada7d92 100644
--- a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl
+++ b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl
@@ -17,5 +17,6 @@
 package com.android.frameworks.coretests.aidl;
 
 interface IBpcCallbackObserver {
-    void onCallback(int uid);
-}
\ No newline at end of file
+    void onLimitReached(int uid);
+    void onWarningThresholdReached(int uid);
+}
diff --git a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl
index abdab41..cdcda9d 100644
--- a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl
+++ b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl
@@ -20,7 +20,7 @@
 interface IBpcTestServiceCmdService {
    void forceGc();
    int getBinderProxyCount(int uid);
-   void setBinderProxyWatermarks(int high, int low);
+   void setBinderProxyWatermarks(int high, int low, int warning);
    void enableBinderProxyLimit(boolean enable);
    void setBinderProxyCountCallback(IBpcCallbackObserver observer);
-}
\ No newline at end of file
+}
diff --git a/core/tests/coretests/res/layout/activity_horizontal_scroll_view.xml b/core/tests/coretests/res/layout/activity_horizontal_scroll_view.xml
index 5029212..44dc1f8 100644
--- a/core/tests/coretests/res/layout/activity_horizontal_scroll_view.xml
+++ b/core/tests/coretests/res/layout/activity_horizontal_scroll_view.xml
@@ -22,7 +22,7 @@
 
     <HorizontalScrollView
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
+        android:layout_height="wrap_content"
         android:id="@+id/horizontal_scroll_view">
 
         <LinearLayout
@@ -133,31 +133,31 @@
         <LinearLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:orientation="vertical">
+            android:orientation="horizontal">
             <View
                 android:background="#00F"
-                android:layout_width="90dp"
-                android:layout_height="50dp"/>
+                android:layout_width="100dp"
+                android:layout_height="90dp"/>
             <View
                 android:background="#0FF"
-                android:layout_width="90dp"
-                android:layout_height="50dp"/>
+                android:layout_width="100dp"
+                android:layout_height="90dp"/>
             <View
                 android:background="#0F0"
-                android:layout_width="90dp"
-                android:layout_height="50dp"/>
+                android:layout_width="100dp"
+                android:layout_height="90dp"/>
             <View
                 android:background="#FF0"
-                android:layout_width="90dp"
-                android:layout_height="50dp"/>
+                android:layout_width="100dp"
+                android:layout_height="90dp"/>
             <View
                 android:background="#F00"
-                android:layout_width="90dp"
-                android:layout_height="50dp"/>
+                android:layout_width="100dp"
+                android:layout_height="90dp"/>
             <View
                 android:background="#F0F"
-                android:layout_width="90dp"
-                android:layout_height="50dp"/>
+                android:layout_width="100dp"
+                android:layout_height="90dp"/>
         </LinearLayout>
     </view>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/core/tests/coretests/res/layout/activity_scroll_view.xml b/core/tests/coretests/res/layout/activity_scroll_view.xml
index db8cd02..0d4afd5 100644
--- a/core/tests/coretests/res/layout/activity_scroll_view.xml
+++ b/core/tests/coretests/res/layout/activity_scroll_view.xml
@@ -18,10 +18,10 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="vertical">
+    android:orientation="horizontal">
 
     <ScrollView
-        android:layout_width="match_parent"
+        android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:id="@+id/scroll_view">
 
diff --git a/core/tests/coretests/src/android/app/NotificationChannelTest.java b/core/tests/coretests/src/android/app/NotificationChannelTest.java
index 18209b5..504f98f 100644
--- a/core/tests/coretests/src/android/app/NotificationChannelTest.java
+++ b/core/tests/coretests/src/android/app/NotificationChannelTest.java
@@ -31,6 +31,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.annotation.FlaggedApi;
 import android.content.AttributionSource;
 import android.content.ContentProvider;
 import android.content.ContentResolver;
@@ -46,6 +47,7 @@
 import android.os.RemoteCallback;
 import android.os.RemoteException;
 import android.os.VibrationEffect;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.MediaStore.Audio.AudioColumns;
@@ -577,6 +579,40 @@
         assertNull(channel.getVibrationEffect());
     }
 
+    @Test
+    @EnableFlags({Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_MEDIA,
+            Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_CALL, Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_ALARM})
+    public void testCopy() {
+        NotificationChannel original = new NotificationChannel("id", "name", 2);
+        original.setDescription("desc");
+        original.setBypassDnd(true);
+        original.setLockscreenVisibility(7);
+        original.setSound(Uri.EMPTY, new AudioAttributes.Builder().build());
+        original.setLightColor(5);
+        original.enableLights(false);
+        original.setVibrationPattern(new long[] {1, 9, 3});
+        if (Flags.notificationChannelVibrationEffectApi()) {
+            original.setVibrationEffect(VibrationEffect.createOneShot(100, 5));
+        }
+        original.lockFields(9999);
+        original.setUserVisibleTaskShown(true);
+        original.enableVibration(false);
+        original.setShowBadge(true);
+        original.setDeleted(false);
+        original.setGroup("group");
+        original.setBlockable(false);
+        original.setAllowBubbles(true);
+        original.setOriginalImportance(6);
+        original.setConversationId("parent", "convo");
+        original.setDemoted(false);
+        original.setImportantConversation(true);
+        original.setDeletedTimeMs(100);
+        original.setImportanceLockedByCriticalDeviceFunction(false);
+
+        NotificationChannel parcelCopy = writeToAndReadFromParcel(original);
+        assertThat(original.copy()).isEqualTo(parcelCopy);
+    }
+
     /** Backs up a given channel to an XML, and returns the channel read from the XML. */
     private NotificationChannel backUpAndRestore(NotificationChannel channel) throws Exception {
         TypedXmlSerializer serializer = Xml.newFastSerializer();
diff --git a/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt b/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
index a2a5433..c7d5825 100644
--- a/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
+++ b/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
@@ -175,10 +175,12 @@
         assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(-1f)).isFalse()
         assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(0.85f)).isFalse()
         assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(1.02f)).isFalse()
+        assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(1.05f)).isTrue()
         assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(1.10f)).isTrue()
         assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(1.15f)).isTrue()
         assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(1.1499999f))
                 .isTrue()
+        assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(1.2f)).isTrue()
         assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(1.5f)).isTrue()
         assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(2f)).isTrue()
         assertThat(FontScaleConverterFactory.isNonLinearFontScalingActive(3f)).isTrue()
diff --git a/core/tests/coretests/src/android/hardware/biometrics/BiometricPromptTest.java b/core/tests/coretests/src/android/hardware/biometrics/BiometricPromptTest.java
index 66f3bca..ca91542 100644
--- a/core/tests/coretests/src/android/hardware/biometrics/BiometricPromptTest.java
+++ b/core/tests/coretests/src/android/hardware/biometrics/BiometricPromptTest.java
@@ -16,6 +16,14 @@
 
 package android.hardware.biometrics;
 
+import static android.hardware.biometrics.BiometricPrompt.MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER;
+import static android.hardware.biometrics.PromptContentViewWithMoreOptionsButton.MAX_DESCRIPTION_CHARACTER_NUMBER;
+import static android.hardware.biometrics.PromptVerticalListContentView.MAX_EACH_ITEM_CHARACTER_NUMBER;
+import static android.hardware.biometrics.PromptVerticalListContentView.MAX_ITEM_NUMBER;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
@@ -40,6 +48,7 @@
 import org.mockito.junit.MockitoJUnitRunner;
 import org.mockito.junit.MockitoRule;
 
+import java.util.Random;
 import java.util.concurrent.Executor;
 
 
@@ -83,10 +92,11 @@
                 ArgumentCaptor.forClass(IBiometricServiceReceiver.class);
         BiometricPrompt.AuthenticationCallback callback =
                 new BiometricPrompt.AuthenticationCallback() {
-            @Override
-            public void onAuthenticationError(int errorCode, CharSequence errString) {
-                super.onAuthenticationError(errorCode, errString);
-            }};
+                    @Override
+                    public void onAuthenticationError(int errorCode, CharSequence errString) {
+                        super.onAuthenticationError(errorCode, errString);
+                    }
+                };
         mBiometricPrompt.authenticate(mCancellationSignal, mExecutor, callback);
         mLooper.dispatchAll();
 
@@ -99,4 +109,112 @@
 
         verify(mService).cancelAuthentication(any(), anyString(), anyLong());
     }
+
+    @Test
+    public void testLogoDescription_null() {
+        IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
+                () -> new BiometricPrompt.Builder(mContext).setLogoDescription(null)
+        );
+
+        assertThat(e).hasMessageThat().contains(
+                "Logo description passed in can not be null or exceed");
+    }
+
+    @Test
+    public void testLogoDescription_charLimit() {
+        IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
+                () -> new BiometricPrompt.Builder(mContext).setLogoDescription(
+                        generateRandomString(MAX_LOGO_DESCRIPTION_CHARACTER_NUMBER + 1))
+        );
+
+        assertThat(e).hasMessageThat().contains(
+                "Logo description passed in can not be null or exceed");
+    }
+
+    @Test
+    public void testMoreOptionsButton_descriptionCharLimit() {
+        IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
+                () -> new PromptContentViewWithMoreOptionsButton.Builder().setDescription(
+                        generateRandomString(MAX_DESCRIPTION_CHARACTER_NUMBER + 1))
+        );
+
+        assertThat(e).hasMessageThat().contains(
+                "The character number of description exceeds ");
+    }
+
+    @Test
+    public void testMoreOptionsButton_ExecutorNull() {
+        PromptContentViewWithMoreOptionsButton.Builder builder =
+                new PromptContentViewWithMoreOptionsButton.Builder().setMoreOptionsButtonListener(
+                        null, null);
+        IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
+                builder::build
+        );
+
+        assertThat(e).hasMessageThat().contains(
+                "The executor for the listener of more options button on prompt content must be "
+                        + "set");
+    }
+
+    @Test
+    public void testMoreOptionsButton_ListenerNull() {
+        PromptContentViewWithMoreOptionsButton.Builder builder =
+                new PromptContentViewWithMoreOptionsButton.Builder().setMoreOptionsButtonListener(
+                        mExecutor, null);
+        IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
+                builder::build
+        );
+
+        assertThat(e).hasMessageThat().contains(
+                "The listener of more options button on prompt content must be set");
+    }
+
+    @Test
+    public void testVerticalList_descriptionCharLimit() {
+        IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
+                () -> new PromptVerticalListContentView.Builder().setDescription(
+                        generateRandomString(MAX_DESCRIPTION_CHARACTER_NUMBER + 1))
+        );
+
+        assertThat(e).hasMessageThat().contains(
+                "The character number of description exceeds ");
+    }
+
+    @Test
+    public void testVerticalList_itemCharLimit() {
+        IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
+                () -> new PromptVerticalListContentView.Builder().addListItem(
+                        new PromptContentItemBulletedText(
+                                generateRandomString(MAX_EACH_ITEM_CHARACTER_NUMBER + 1)))
+        );
+
+        assertThat(e).hasMessageThat().contains(
+                "The character number of list item exceeds ");
+    }
+
+    @Test
+    public void testVerticalList_itemNumLimit() {
+        PromptVerticalListContentView.Builder builder = new PromptVerticalListContentView.Builder();
+
+        for (int i = 0; i < MAX_ITEM_NUMBER; i++) {
+            builder.addListItem(new PromptContentItemBulletedText(generateRandomString(10)));
+        }
+
+        IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
+                () -> builder.addListItem(
+                        new PromptContentItemBulletedText(generateRandomString(10)))
+        );
+
+        assertThat(e).hasMessageThat().contains(
+                "The number of list items exceeds ");
+    }
+
+    private String generateRandomString(int charNum) {
+        final Random random = new Random();
+        final StringBuilder longString = new StringBuilder(charNum);
+        for (int j = 0; j < charNum; j++) {
+            longString.append(random.nextInt(10));
+        }
+        return longString.toString();
+    }
 }
diff --git a/core/tests/coretests/src/android/hardware/face/FaceSensorConfigurationsTest.java b/core/tests/coretests/src/android/hardware/face/FaceSensorConfigurationsTest.java
index b61104d..7d7f8ed 100644
--- a/core/tests/coretests/src/android/hardware/face/FaceSensorConfigurationsTest.java
+++ b/core/tests/coretests/src/android/hardware/face/FaceSensorConfigurationsTest.java
@@ -18,13 +18,10 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.res.Resources;
-import android.hardware.biometrics.face.IFace;
-import android.hardware.biometrics.face.SensorProps;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 
@@ -37,8 +34,6 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
-import java.util.function.Function;
-
 @Presubmit
 @SmallTest
 public class FaceSensorConfigurationsTest {
@@ -48,10 +43,6 @@
     private Context mContext;
     @Mock
     private Resources mResources;
-    @Mock
-    private IFace mFace;
-    @Mock
-    private Function<String, IFace> mGetIFace;
 
     private final String[] mAidlInstances = new String[]{"default", "virtual"};
     private String[] mHidlConfigStrings = new String[]{"0:2:15", "0:8:15"};
@@ -59,15 +50,13 @@
 
     @Before
     public void setUp() throws RemoteException {
-        when(mGetIFace.apply(anyString())).thenReturn(mFace);
-        when(mFace.getSensorProps()).thenReturn(new SensorProps[]{});
         when(mContext.getResources()).thenReturn(mResources);
     }
 
     @Test
     public void testAidlInstanceSensorProps() {
         mFaceSensorConfigurations = new FaceSensorConfigurations(false);
-        mFaceSensorConfigurations.addAidlConfigs(mAidlInstances, mGetIFace);
+        mFaceSensorConfigurations.addAidlConfigs(mAidlInstances);
 
         assertThat(mFaceSensorConfigurations.hasSensorConfigurations()).isTrue();
         assertThat(!mFaceSensorConfigurations.isSingleSensorConfigurationPresent()).isTrue();
diff --git a/core/tests/coretests/src/android/hardware/fingerprint/FingerprintSensorConfigurationsTest.java b/core/tests/coretests/src/android/hardware/fingerprint/FingerprintSensorConfigurationsTest.java
index f058c16..b2f8299 100644
--- a/core/tests/coretests/src/android/hardware/fingerprint/FingerprintSensorConfigurationsTest.java
+++ b/core/tests/coretests/src/android/hardware/fingerprint/FingerprintSensorConfigurationsTest.java
@@ -18,13 +18,10 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.res.Resources;
-import android.hardware.biometrics.fingerprint.IFingerprint;
-import android.hardware.biometrics.fingerprint.SensorProps;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 
@@ -37,8 +34,6 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
-import java.util.function.Function;
-
 @Presubmit
 @SmallTest
 public class FingerprintSensorConfigurationsTest {
@@ -48,10 +43,6 @@
     private Context mContext;
     @Mock
     private Resources mResources;
-    @Mock
-    private IFingerprint mFingerprint;
-    @Mock
-    private Function<String, IFingerprint> mGetIFingerprint;
 
     private final String[] mAidlInstances = new String[]{"default", "virtual"};
     private String[] mHidlConfigStrings = new String[]{"0:2:15", "0:8:15"};
@@ -59,8 +50,6 @@
 
     @Before
     public void setUp() throws RemoteException {
-        when(mGetIFingerprint.apply(anyString())).thenReturn(mFingerprint);
-        when(mFingerprint.getSensorProps()).thenReturn(new SensorProps[]{});
         when(mContext.getResources()).thenReturn(mResources);
     }
 
@@ -68,7 +57,7 @@
     public void testAidlInstanceSensorProps() {
         mFingerprintSensorConfigurations = new FingerprintSensorConfigurations(
                 true /* resetLockoutRequiresHardwareAuthToken */);
-        mFingerprintSensorConfigurations.addAidlSensors(mAidlInstances, mGetIFingerprint);
+        mFingerprintSensorConfigurations.addAidlSensors(mAidlInstances);
 
         assertThat(mFingerprintSensorConfigurations.hasSensorConfigurations()).isTrue();
         assertThat(!mFingerprintSensorConfigurations.isSingleSensorConfigurationPresent())
diff --git a/core/tests/coretests/src/android/os/BinderProxyCountingTest.java b/core/tests/coretests/src/android/os/BinderProxyCountingTest.java
index bcd9521..84d2995 100644
--- a/core/tests/coretests/src/android/os/BinderProxyCountingTest.java
+++ b/core/tests/coretests/src/android/os/BinderProxyCountingTest.java
@@ -88,9 +88,10 @@
 
     private static final int BIND_SERVICE_TIMEOUT_SEC = 5;
     private static final int TOO_MANY_BINDERS_TIMEOUT_SEC = 2;
+    private static final int TOO_MANY_BINDERS_WITH_KILL_TIMEOUT_SEC = 30;
 
-    // Keep in sync with sBinderProxyCountLimit in BpBinder.cpp
-    private static final int BINDER_PROXY_LIMIT = 2500;
+    // Keep in sync with BINDER_PROXY_HIGH_WATERMARK in ActivityManagerService.java
+    private static final int BINDER_PROXY_LIMIT = 6000;
 
     private static Context sContext;
     private static UiDevice sUiDevice;
@@ -175,18 +176,26 @@
         }
     }
 
-    private CountDownLatch createBinderLimitLatch() throws RemoteException {
-        final CountDownLatch latch = new CountDownLatch(1);
+    private CountDownLatch[] createBinderLimitLatch() throws RemoteException {
+        final CountDownLatch[] latches = new CountDownLatch[] {
+            new CountDownLatch(1), new CountDownLatch(1)
+        };
         sBpcTestServiceCmdService.setBinderProxyCountCallback(
                 new IBpcCallbackObserver.Stub() {
                     @Override
-                    public void onCallback(int uid) {
+                    public void onLimitReached(int uid) {
                         if (uid == sTestPkgUid) {
-                            latch.countDown();
+                            latches[0].countDown();
+                        }
+                    }
+                    @Override
+                    public void onWarningThresholdReached(int uid) {
+                        if (uid == sTestPkgUid) {
+                            latches[1].countDown();
                         }
                     }
                 });
-        return latch;
+        return latches;
     }
 
     /**
@@ -227,6 +236,7 @@
     @Test
     public void testBinderProxyLimitBoundary() throws Exception {
         final int binderProxyLimit = 2000;
+        final int binderProxyWarning = 1900;
         final int rearmThreshold = 1800;
         try {
             sTestAppConnection = bindService(sTestAppConsumer, sTestAppIntent);
@@ -238,19 +248,33 @@
             // Get the baseline of binders naturally held by the test Package
             int baseBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid);
 
-            final CountDownLatch binderLimitLatch = createBinderLimitLatch();
-            sBpcTestServiceCmdService.setBinderProxyWatermarks(binderProxyLimit, rearmThreshold);
+            final CountDownLatch[] binderLatches = createBinderLimitLatch();
+            sBpcTestServiceCmdService.setBinderProxyWatermarks(binderProxyLimit, rearmThreshold,
+                    binderProxyWarning);
+
+            // Create Binder Proxies up to the warning;
+            sBpcTestAppCmdService.createTestBinders(binderProxyWarning - baseBinderCount);
+            if (binderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+                fail("Received BinderProxyLimitCallback for uid " + sTestPkgUid
+                        + " when proxy warning should not have been triggered");
+            }
+
+            // Create one more Binder to trigger the warning
+            sBpcTestAppCmdService.createTestBinders(1);
+            if (!binderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+                fail("Timed out waiting for uid " + sTestPkgUid + " to trigger the warning");
+            }
 
             // Create Binder Proxies up to the limit
-            sBpcTestAppCmdService.createTestBinders(binderProxyLimit - baseBinderCount);
-            if (binderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+            sBpcTestAppCmdService.createTestBinders(binderProxyLimit - binderProxyWarning - 1);
+            if (binderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
                 fail("Received BinderProxyLimitCallback for uid " + sTestPkgUid
                         + " when proxy limit should not have been reached");
             }
 
             // Create one more Binder to cross the limit
             sBpcTestAppCmdService.createTestBinders(1);
-            if (!binderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+            if (!binderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
                 fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit");
             }
 
@@ -274,12 +298,20 @@
             sBpcTestServiceCmdService.forceGc();
             int baseBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid);
             for (int testLimit : testLimits) {
-                final CountDownLatch binderLimitLatch = createBinderLimitLatch();
+                final CountDownLatch[] binderLatches = createBinderLimitLatch();
                 // Change the BinderProxyLimit
-                sBpcTestServiceCmdService.setBinderProxyWatermarks(testLimit, baseBinderCount + 10);
+                sBpcTestServiceCmdService.setBinderProxyWatermarks(testLimit, baseBinderCount + 10,
+                        testLimit - 10);
+
+                // Trigger the new Binder Proxy warning
+                sBpcTestAppCmdService.createTestBinders(testLimit - 9 - baseBinderCount);
+                if (!binderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+                    fail("Timed out waiting for uid " + sTestPkgUid + " to trigger the warning");
+                }
+
                 // Exceed the new Binder Proxy Limit
-                sBpcTestAppCmdService.createTestBinders(testLimit + 1);
-                if (!binderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+                sBpcTestAppCmdService.createTestBinders(10);
+                if (!binderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
                     fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit");
                 }
 
@@ -297,6 +329,7 @@
     public void testRearmCallbackThreshold() throws Exception {
         final int binderProxyLimit = 2000;
         final int exceedBinderProxyLimit = binderProxyLimit + 10;
+        final int binderProxyWarning = 1900;
         final int rearmThreshold = 1800;
         try {
             sTestAppConnection = bindService(sTestAppConsumer, sTestAppIntent);
@@ -305,11 +338,19 @@
             sBpcTestServiceCmdService.enableBinderProxyLimit(true);
 
             sBpcTestServiceCmdService.forceGc();
-            final CountDownLatch firstBinderLimitLatch = createBinderLimitLatch();
-            sBpcTestServiceCmdService.setBinderProxyWatermarks(binderProxyLimit, rearmThreshold);
+            int baseBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid);
+            final CountDownLatch[] firstBinderLatches = createBinderLimitLatch();
+            sBpcTestServiceCmdService.setBinderProxyWatermarks(binderProxyLimit, rearmThreshold,
+                    binderProxyWarning);
+            // Trigger the Binder Proxy Waring
+            sBpcTestAppCmdService.createTestBinders(binderProxyWarning - baseBinderCount + 1);
+            if (!firstBinderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+                fail("Timed out waiting for uid " + sTestPkgUid + " to trigger warning");
+            }
+
             // Exceed the Binder Proxy Limit
-            sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit);
-            if (!firstBinderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+            sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit - binderProxyWarning);
+            if (!firstBinderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
                 fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit");
             }
 
@@ -321,11 +362,20 @@
             sBpcTestServiceCmdService.forceGc();
             currentBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid);
 
-            final CountDownLatch secondBinderLimitLatch = createBinderLimitLatch();
+            final CountDownLatch[] secondBinderLatches = createBinderLimitLatch();
+
+            // Exceed the Binder Proxy warning which should not cause a callback since there has
+            // been no rearm
+            sBpcTestAppCmdService.createTestBinders(binderProxyWarning - currentBinderCount + 1);
+            if (secondBinderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+                fail("Received BinderProxyLimitCallback for uid " + sTestPkgUid
+                        + " when the callback has not been rearmed yet");
+            }
+
             // Exceed the Binder Proxy limit which should not cause a callback since there has
             // been no rearm
-            sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit - currentBinderCount);
-            if (secondBinderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+            sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit - binderProxyWarning);
+            if (secondBinderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
                 fail("Received BinderProxyLimitCallback for uid " + sTestPkgUid
                         + " when the callback has not been rearmed yet");
             }
@@ -337,10 +387,16 @@
 
             sBpcTestServiceCmdService.forceGc();
             currentBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid);
+            // Trigger the Binder Proxy Waring
+            sBpcTestAppCmdService.createTestBinders(binderProxyWarning - currentBinderCount + 1);
+            if (!secondBinderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+                fail("Timed out waiting for uid " + sTestPkgUid + " to trigger warning");
+            }
+
             // Exceed the Binder Proxy limit for the last time
             sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit - currentBinderCount);
 
-            if (!secondBinderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+            if (!secondBinderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
                 fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit");
             }
             sBpcTestAppCmdService.releaseTestBinders(currentBinderCount);
@@ -373,7 +429,7 @@
                 // is not unexpected
             }
 
-            if (!binderDeathLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+            if (!binderDeathLatch.await(TOO_MANY_BINDERS_WITH_KILL_TIMEOUT_SEC, TimeUnit.SECONDS)) {
                 sBpcTestAppCmdService.releaseSystemBinders(exceedBinderProxyLimit);
                 fail("Timed out waiting for uid " + sTestPkgUid + " to die.");
             }
diff --git a/core/tests/coretests/src/android/view/MotionEventTest.java b/core/tests/coretests/src/android/view/MotionEventTest.java
index c4c983d..6a6e652 100644
--- a/core/tests/coretests/src/android/view/MotionEventTest.java
+++ b/core/tests/coretests/src/android/view/MotionEventTest.java
@@ -47,21 +47,25 @@
 public class MotionEventTest {
     private static final int ID_SOURCE_MASK = 0x3 << 30;
 
+    private PointerCoords pointerCoords(float x, float y) {
+        final var coords = new PointerCoords();
+        coords.x = x;
+        coords.y = y;
+        return coords;
+    }
+
+    private PointerProperties fingerProperties(int id) {
+        final var props = new PointerProperties();
+        props.id = id;
+        props.toolType = TOOL_TYPE_FINGER;
+        return props;
+    }
+
     @Test
     public void testObtainWithDisplayId() {
         final int pointerCount = 1;
-        PointerProperties[] properties = new PointerProperties[pointerCount];
-        final PointerCoords[] coords = new PointerCoords[pointerCount];
-        for (int i = 0; i < pointerCount; i++) {
-            final PointerCoords c = new PointerCoords();
-            c.x = i * 10;
-            c.y = i * 20;
-            coords[i] = c;
-            final PointerProperties p = new PointerProperties();
-            p.id = i;
-            p.toolType = TOOL_TYPE_FINGER;
-            properties[i] = p;
-        }
+        final var properties = new PointerProperties[]{fingerProperties(0)};
+        final var coords = new PointerCoords[]{pointerCoords(10, 20)};
 
         int displayId = 2;
         MotionEvent motionEvent = MotionEvent.obtain(0, 0, ACTION_DOWN,
@@ -125,18 +129,8 @@
     @Test
     public void testCalculatesCursorPositionForMultiTouchMouseEvents() {
         final int pointerCount = 2;
-        final PointerProperties[] properties = new PointerProperties[pointerCount];
-        final PointerCoords[] coords = new PointerCoords[pointerCount];
-
-        for (int i = 0; i < pointerCount; ++i) {
-            properties[i] = new PointerProperties();
-            properties[i].id = i;
-            properties[i].toolType = MotionEvent.TOOL_TYPE_FINGER;
-
-            coords[i] = new PointerCoords();
-            coords[i].x = 20 + i * 20;
-            coords[i].y = 60 - i * 20;
-        }
+        final var properties = new PointerProperties[]{fingerProperties(0), fingerProperties(1)};
+        final var coords = new PointerCoords[]{pointerCoords(20, 60), pointerCoords(40, 40)};
 
         final MotionEvent event = MotionEvent.obtain(0 /* downTime */,
                 0 /* eventTime */, ACTION_POINTER_DOWN, pointerCount, properties, coords,
diff --git a/core/tests/coretests/src/android/view/PendingInsetsControllerTest.java b/core/tests/coretests/src/android/view/PendingInsetsControllerTest.java
index 690b3587..b5b2d0c 100644
--- a/core/tests/coretests/src/android/view/PendingInsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/PendingInsetsControllerTest.java
@@ -18,6 +18,7 @@
 
 import static android.view.WindowInsets.Type.navigationBars;
 import static android.view.WindowInsets.Type.systemBars;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
 import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 
@@ -154,8 +155,8 @@
         mPendingInsetsController.replayAndAttach(mReplayedController);
         mPendingInsetsController.setSystemBarsAppearance(
                 APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS);
-        verify(mReplayedController).setSystemBarsAppearance(eq(APPEARANCE_LIGHT_STATUS_BARS),
-                eq(APPEARANCE_LIGHT_STATUS_BARS));
+        verify(mReplayedController).setSystemBarsAppearance(
+                eq(APPEARANCE_LIGHT_STATUS_BARS), eq(APPEARANCE_LIGHT_STATUS_BARS));
     }
 
     @Test
@@ -168,6 +169,24 @@
     }
 
     @Test
+    public void testAppearanceFromResource() {
+        mPendingInsetsController.setSystemBarsAppearanceFromResource(
+                APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS);
+        mPendingInsetsController.replayAndAttach(mReplayedController);
+        verify(mReplayedController).setSystemBarsAppearanceFromResource(
+                eq(APPEARANCE_LIGHT_STATUS_BARS), eq(APPEARANCE_LIGHT_STATUS_BARS));
+    }
+
+    @Test
+    public void testAppearanceFromResource_direct() {
+        mPendingInsetsController.replayAndAttach(mReplayedController);
+        mPendingInsetsController.setSystemBarsAppearanceFromResource(
+                APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS);
+        verify(mReplayedController).setSystemBarsAppearanceFromResource(
+                eq(APPEARANCE_LIGHT_STATUS_BARS), eq(APPEARANCE_LIGHT_STATUS_BARS));
+    }
+
+    @Test
     public void testAddOnControllableInsetsChangedListener() {
         OnControllableInsetsChangedListener listener =
                 mock(OnControllableInsetsChangedListener.class);
@@ -201,8 +220,10 @@
     public void testReplayTwice() {
         mPendingInsetsController.show(systemBars());
         mPendingInsetsController.setSystemBarsBehavior(BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
-        mPendingInsetsController.setSystemBarsAppearance(APPEARANCE_LIGHT_STATUS_BARS,
-                APPEARANCE_LIGHT_STATUS_BARS);
+        mPendingInsetsController.setSystemBarsAppearance(
+                APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS);
+        mPendingInsetsController.setSystemBarsAppearanceFromResource(
+                APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS);
         mPendingInsetsController.addOnControllableInsetsChangedListener(
                 (controller, typeMask) -> {});
         mPendingInsetsController.replayAndAttach(mReplayedController);
@@ -235,15 +256,29 @@
     public void testDetachReattach() {
         mPendingInsetsController.show(systemBars());
         mPendingInsetsController.setSystemBarsBehavior(BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
-        mPendingInsetsController.setSystemBarsAppearance(APPEARANCE_LIGHT_STATUS_BARS,
-                APPEARANCE_LIGHT_STATUS_BARS);
+        mPendingInsetsController.setSystemBarsAppearance(
+                APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS);
+        mPendingInsetsController.setSystemBarsAppearanceFromResource(
+                APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS);
         mPendingInsetsController.replayAndAttach(mReplayedController);
         mPendingInsetsController.detach();
         mPendingInsetsController.show(navigationBars());
+        mPendingInsetsController.setSystemBarsAppearance(
+                APPEARANCE_LIGHT_NAVIGATION_BARS, APPEARANCE_LIGHT_NAVIGATION_BARS);
+        mPendingInsetsController.setSystemBarsAppearanceFromResource(
+                APPEARANCE_LIGHT_NAVIGATION_BARS, APPEARANCE_LIGHT_NAVIGATION_BARS);
         InsetsController secondController = mock(InsetsController.class);
         mPendingInsetsController.replayAndAttach(secondController);
 
         verify(mReplayedController).show(eq(systemBars()));
+        verify(mReplayedController).setSystemBarsAppearance(
+                eq(APPEARANCE_LIGHT_STATUS_BARS), eq(APPEARANCE_LIGHT_STATUS_BARS));
+        verify(mReplayedController).setSystemBarsAppearanceFromResource(
+                eq(APPEARANCE_LIGHT_STATUS_BARS), eq(APPEARANCE_LIGHT_STATUS_BARS));
         verify(secondController).show(eq(navigationBars()));
+        verify(secondController).setSystemBarsAppearance(
+                eq(APPEARANCE_LIGHT_NAVIGATION_BARS), eq(APPEARANCE_LIGHT_NAVIGATION_BARS));
+        verify(secondController).setSystemBarsAppearanceFromResource(
+                eq(APPEARANCE_LIGHT_NAVIGATION_BARS), eq(APPEARANCE_LIGHT_NAVIGATION_BARS));
     }
 }
diff --git a/core/tests/coretests/src/android/view/ViewFrameRateTest.java b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
index dcdb8b0..dcfbf64 100644
--- a/core/tests/coretests/src/android/view/ViewFrameRateTest.java
+++ b/core/tests/coretests/src/android/view/ViewFrameRateTest.java
@@ -19,10 +19,14 @@
 import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
 import static android.view.Surface.FRAME_RATE_CATEGORY_LOW;
 import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL;
+import static android.view.Surface.FRAME_RATE_COMPATIBILITY_GTE;
+import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY;
+import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY;
 import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
 import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
 import static android.view.flags.Flags.toolkitFrameRateBySizeReadOnly;
 import static android.view.flags.Flags.toolkitFrameRateDefaultNormalReadOnly;
+import static android.view.flags.Flags.toolkitFrameRateSmallUsesPercentReadOnly;
 
 import static junit.framework.Assert.assertEquals;
 
@@ -32,6 +36,9 @@
 import android.app.Activity;
 import android.os.SystemClock;
 import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.util.DisplayMetrics;
 
 import androidx.test.annotation.UiThreadTest;
 import androidx.test.filters.SmallTest;
@@ -56,6 +63,9 @@
     public ActivityTestRule<ViewCaptureTestActivity> mActivityRule = new ActivityTestRule<>(
             ViewCaptureTestActivity.class);
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
     private Activity mActivity;
     private View mMovingView;
     private ViewRootImpl mViewRoot;
@@ -76,7 +86,8 @@
 
     @UiThreadTest
     @Test
-    @RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
+    @RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void frameRateChangesWhenContentMoves() {
         mMovingView.offsetLeftAndRight(100);
         float frameRate = mViewRoot.getPreferredFrameRate();
@@ -115,6 +126,46 @@
         });
     }
 
+    @Test
+    @RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API,
+            FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
+    public void lowVelocity60() throws Throwable {
+        mActivityRule.runOnUiThread(() -> {
+            ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
+            layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
+            layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
+            mMovingView.setLayoutParams(layoutParams);
+        });
+        waitForFrameRateCategoryToSettle();
+        mActivityRule.runOnUiThread(() -> {
+            mMovingView.setFrameContentVelocity(1f);
+            mMovingView.invalidate();
+            assertEquals(60f, mViewRoot.getPreferredFrameRate(), 0f);
+            assertEquals(FRAME_RATE_COMPATIBILITY_GTE, mViewRoot.getFrameRateCompatibility());
+        });
+    }
+
+    @Test
+    @RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API,
+            FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
+    public void highVelocity140() throws Throwable {
+        mActivityRule.runOnUiThread(() -> {
+            ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
+            layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
+            layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
+            mMovingView.setLayoutParams(layoutParams);
+        });
+        waitForFrameRateCategoryToSettle();
+        mActivityRule.runOnUiThread(() -> {
+            mMovingView.setFrameContentVelocity(1_000_000_000f);
+            mMovingView.invalidate();
+            assertEquals(140f, mViewRoot.getPreferredFrameRate(), 0f);
+            assertEquals(FRAME_RATE_COMPATIBILITY_GTE, mViewRoot.getFrameRateCompatibility());
+        });
+    }
+
     private void waitForFrameRateCategoryToSettle() throws Throwable {
         for (int i = 0; i < 5; i++) {
             final CountDownLatch drawLatch = new CountDownLatch(1);
@@ -130,14 +181,24 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void noVelocityUsesCategorySmall() throws Throwable {
         final CountDownLatch drawLatch1 = new CountDownLatch(1);
         mActivityRule.runOnUiThread(() -> {
-            float density = mActivity.getResources().getDisplayMetrics().density;
+            DisplayMetrics displayMetrics = mActivity.getResources().getDisplayMetrics();
             ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
-            layoutParams.height = 4 * ((int) (10 * density));
-            layoutParams.width = 4 * ((int) (10 * density));
+            if (toolkitFrameRateSmallUsesPercentReadOnly()) {
+                float pixels = displayMetrics.widthPixels * displayMetrics.heightPixels * 0.07f;
+                double smallSize = Math.sqrt(pixels);
+                layoutParams.width = (int) smallSize;
+                layoutParams.height = (int) smallSize;
+            } else {
+                float density = displayMetrics.density;
+                layoutParams.height = ((int) (40 * density));
+                layoutParams.width = ((int) (40 * density));
+            }
+
             mMovingView.setLayoutParams(layoutParams);
             mMovingView.getViewTreeObserver().addOnDrawListener(drawLatch1::countDown);
         });
@@ -155,14 +216,23 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void noVelocityUsesCategoryNarrowWidth() throws Throwable {
         final CountDownLatch drawLatch1 = new CountDownLatch(1);
         mActivityRule.runOnUiThread(() -> {
-            float density = mActivity.getResources().getDisplayMetrics().density;
+            DisplayMetrics displayMetrics = mActivity.getResources().getDisplayMetrics();
             ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
-            layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
-            layoutParams.width = (int) (10 * density);
+            if (toolkitFrameRateSmallUsesPercentReadOnly()) {
+                float pixels = displayMetrics.widthPixels * displayMetrics.heightPixels * 0.07f;
+                int parentWidth = ((View) mMovingView.getParent()).getWidth();
+                layoutParams.width = parentWidth;
+                layoutParams.height = (int) (pixels / parentWidth);
+            } else {
+                float density = displayMetrics.density;
+                layoutParams.width = (int) (10 * density);
+                layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
+            }
             mMovingView.setLayoutParams(layoutParams);
             mMovingView.getViewTreeObserver().addOnDrawListener(drawLatch1::countDown);
         });
@@ -180,14 +250,23 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void noVelocityUsesCategoryNarrowHeight() throws Throwable {
         final CountDownLatch drawLatch1 = new CountDownLatch(1);
         mActivityRule.runOnUiThread(() -> {
-            float density = mActivity.getResources().getDisplayMetrics().density;
+            DisplayMetrics displayMetrics = mActivity.getResources().getDisplayMetrics();
             ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
-            layoutParams.height = (int) (10 * density);
-            layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
+            if (toolkitFrameRateSmallUsesPercentReadOnly()) {
+                float pixels = displayMetrics.widthPixels * displayMetrics.heightPixels * 0.07f;
+                int parentHeight = ((View) mMovingView.getParent()).getHeight();
+                layoutParams.width = (int) (pixels / parentHeight);
+                layoutParams.height = parentHeight;
+            } else {
+                float density = displayMetrics.density;
+                layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
+                layoutParams.height = (int) (10 * density);
+            }
             mMovingView.setLayoutParams(layoutParams);
             mMovingView.getViewTreeObserver().addOnDrawListener(drawLatch1::countDown);
         });
@@ -205,14 +284,23 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void noVelocityUsesCategoryLargeWidth() throws Throwable {
         final CountDownLatch drawLatch1 = new CountDownLatch(1);
         mActivityRule.runOnUiThread(() -> {
-            float density = mActivity.getResources().getDisplayMetrics().density;
+            DisplayMetrics displayMetrics = mActivity.getResources().getDisplayMetrics();
             ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
-            layoutParams.height = 4 * ((int) (10 * density));
-            layoutParams.width = 4 * ((int) Math.ceil(10 * density)) + 1;
+            if (toolkitFrameRateSmallUsesPercentReadOnly()) {
+                float pixels = displayMetrics.widthPixels * displayMetrics.heightPixels * 0.07f;
+                double smallSize = Math.sqrt(pixels);
+                layoutParams.width = 1 + (int) Math.ceil(pixels / smallSize);
+                layoutParams.height = (int) smallSize;
+            } else {
+                float density = displayMetrics.density;
+                layoutParams.width = ((int) Math.ceil(40 * density)) + 1;
+                layoutParams.height = ((int) (40 * density));
+            }
             mMovingView.setLayoutParams(layoutParams);
             mMovingView.getViewTreeObserver().addOnDrawListener(drawLatch1::countDown);
         });
@@ -230,14 +318,23 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void noVelocityUsesCategoryLargeHeight() throws Throwable {
         final CountDownLatch drawLatch1 = new CountDownLatch(1);
         mActivityRule.runOnUiThread(() -> {
-            float density = mActivity.getResources().getDisplayMetrics().density;
+            DisplayMetrics displayMetrics = mActivity.getResources().getDisplayMetrics();
             ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
-            layoutParams.height = 4 * ((int) Math.ceil(10 * density)) + 1;
-            layoutParams.width = 4 * ((int) (10 * density));
+            if (toolkitFrameRateSmallUsesPercentReadOnly()) {
+                float pixels = displayMetrics.widthPixels * displayMetrics.heightPixels * 0.07f;
+                double smallSize = Math.sqrt(pixels);
+                layoutParams.width = (int) smallSize;
+                layoutParams.height = 1 + (int) Math.ceil(pixels / smallSize);
+            } else {
+                float density = displayMetrics.density;
+                layoutParams.width = ((int) (40 * density));
+                layoutParams.height = ((int) Math.ceil(40 * density)) + 1;
+            }
             mMovingView.setLayoutParams(layoutParams);
             mMovingView.getViewTreeObserver().addOnDrawListener(drawLatch1::countDown);
         });
@@ -255,8 +352,16 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void defaultNormal() throws Throwable {
+        mActivityRule.runOnUiThread(() -> {
+            View parent = (View) mMovingView.getParent();
+            ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams();
+            layoutParams.width = parent.getWidth() / 2;
+            layoutParams.height = parent.getHeight() / 2;
+            mMovingView.setLayoutParams(layoutParams);
+        });
         waitForFrameRateCategoryToSettle();
         mActivityRule.runOnUiThread(() -> {
             mMovingView.invalidate();
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
index a034f3b..90ee36e 100644
--- a/core/tests/coretests/src/android/view/ViewRootImplTest.java
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -19,6 +19,8 @@
 import static android.view.accessibility.Flags.FLAG_FORCE_INVERT_COLOR;
 import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;
 import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY;
+import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY;
+import static android.view.flags.Flags.FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY;
 import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
 import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH;
 import static android.view.Surface.FRAME_RATE_CATEGORY_HIGH_HINT;
@@ -82,7 +84,6 @@
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -153,7 +154,8 @@
     public void adjustLayoutParamsForCompatibility_layoutFullscreen() {
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
         attrs.systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
-        ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
+        ViewRootImpl.adjustLayoutParamsForCompatibility(
+                attrs, 0 /* appearanceControlled */, false /* behaviorControlled */);
 
         // Type.statusBars() must be removed.
         assertEquals(0, attrs.getFitInsetsTypes() & Type.statusBars());
@@ -163,7 +165,8 @@
     public void adjustLayoutParamsForCompatibility_layoutInScreen() {
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
         attrs.flags = FLAG_LAYOUT_IN_SCREEN;
-        ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
+        ViewRootImpl.adjustLayoutParamsForCompatibility(
+                attrs, 0 /* appearanceControlled */, false /* behaviorControlled */);
 
         // Type.statusBars() must be removed.
         assertEquals(0, attrs.getFitInsetsTypes() & Type.statusBars());
@@ -173,7 +176,8 @@
     public void adjustLayoutParamsForCompatibility_layoutHideNavigation() {
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
         attrs.systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
-        ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
+        ViewRootImpl.adjustLayoutParamsForCompatibility(
+                attrs, 0 /* appearanceControlled */, false /* behaviorControlled */);
 
         // Type.systemBars() must be removed.
         assertEquals(0, attrs.getFitInsetsTypes() & Type.systemBars());
@@ -182,7 +186,8 @@
     @Test
     public void adjustLayoutParamsForCompatibility_toast() {
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_TOAST);
-        ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
+        ViewRootImpl.adjustLayoutParamsForCompatibility(
+                attrs, 0 /* appearanceControlled */, false /* behaviorControlled */);
 
         assertTrue(attrs.isFitInsetsIgnoringVisibility());
     }
@@ -190,7 +195,8 @@
     @Test
     public void adjustLayoutParamsForCompatibility_systemAlert() {
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_SYSTEM_ALERT);
-        ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
+        ViewRootImpl.adjustLayoutParamsForCompatibility(
+                attrs, 0 /* appearanceControlled */, false /* behaviorControlled */);
 
         assertTrue(attrs.isFitInsetsIgnoringVisibility());
     }
@@ -198,7 +204,8 @@
     @Test
     public void adjustLayoutParamsForCompatibility_fitSystemBars() {
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
-        ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
+        ViewRootImpl.adjustLayoutParamsForCompatibility(
+                attrs, 0 /* appearanceControlled */, false /* behaviorControlled */);
 
         assertEquals(Type.systemBars(), attrs.getFitInsetsTypes());
     }
@@ -207,7 +214,8 @@
     public void adjustLayoutParamsForCompatibility_fitSystemBarsAndIme() {
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(TYPE_APPLICATION);
         attrs.softInputMode |= SOFT_INPUT_ADJUST_RESIZE;
-        ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
+        ViewRootImpl.adjustLayoutParamsForCompatibility(
+                attrs, 0 /* appearanceControlled */, false /* behaviorControlled */);
 
         assertEquals(Type.systemBars() | Type.ime(), attrs.getFitInsetsTypes());
     }
@@ -222,7 +230,8 @@
         attrs.setFitInsetsTypes(types);
         attrs.setFitInsetsSides(sides);
         attrs.setFitInsetsIgnoringVisibility(fitMaxInsets);
-        ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
+        ViewRootImpl.adjustLayoutParamsForCompatibility(
+                attrs, 0 /* appearanceControlled */, false /* behaviorControlled */);
 
         // Fit-insets related fields must not be adjusted due to legacy system UI visibility
         // after calling fit-insets related methods.
@@ -233,14 +242,16 @@
 
     @Test
     public void adjustLayoutParamsForCompatibility_noAdjustAppearance() {
-        final WindowInsetsController controller = mViewRootImpl.getInsetsController();
+        final InsetsController controller = mViewRootImpl.getInsetsController();
         final WindowManager.LayoutParams attrs = mViewRootImpl.mWindowAttributes;
         final int appearance = APPEARANCE_OPAQUE_STATUS_BARS;
         controller.setSystemBarsAppearance(appearance, 0xffffffff);
         attrs.systemUiVisibility = SYSTEM_UI_FLAG_LOW_PROFILE
                 | SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
                 | SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
-        ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
+        ViewRootImpl.adjustLayoutParamsForCompatibility(attrs,
+                controller.getAppearanceControlled(),
+                controller.isBehaviorControlled());
 
         // Appearance must not be adjusted due to legacy system UI visibility after calling
         // setSystemBarsAppearance.
@@ -254,12 +265,14 @@
 
     @Test
     public void adjustLayoutParamsForCompatibility_noAdjustBehavior() {
-        final WindowInsetsController controller = mViewRootImpl.getInsetsController();
+        final InsetsController controller = mViewRootImpl.getInsetsController();
         final WindowManager.LayoutParams attrs = mViewRootImpl.mWindowAttributes;
         final int behavior = BEHAVIOR_DEFAULT;
         controller.setSystemBarsBehavior(behavior);
         attrs.systemUiVisibility = SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
-        ViewRootImpl.adjustLayoutParamsForCompatibility(attrs);
+        ViewRootImpl.adjustLayoutParamsForCompatibility(attrs,
+                controller.getAppearanceControlled(),
+                controller.isBehaviorControlled());
 
         // Behavior must not be adjusted due to legacy system UI visibility after calling
         // setSystemBarsBehavior.
@@ -464,8 +477,8 @@
      */
     @UiThreadTest
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_getDefaultValues() {
         ViewRootImpl viewRootImpl = new ViewRootImpl(sContext,
                 sContext.getDisplayNoVerify());
@@ -481,9 +494,9 @@
      * Also, mIsFrameRateBoosting should be true when the visibility becomes visible
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
     @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
-            FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY})
+            FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_voteFrameRateCategory_visibility_bySize() {
         View view = new View(sContext);
         attachViewToWindow(view);
@@ -515,9 +528,9 @@
      * <7%: FRAME_RATE_CATEGORY_LOW
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
     @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
-            FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY})
+            FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_voteFrameRateCategory_smallSize_bySize() {
         View view = new View(sContext);
         WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY);
@@ -544,9 +557,9 @@
      * >=7% : FRAME_RATE_CATEGORY_NORMAL
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
     @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
-            FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY})
+            FLAG_TOOLKIT_FRAME_RATE_BY_SIZE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_voteFrameRateCategory_normalSize_bySize() {
         View view = new View(sContext);
         WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY);
@@ -577,8 +590,9 @@
      * Also, mIsFrameRateBoosting should be true when the visibility becomes visible
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_voteFrameRateCategory_visibility_defaultHigh() {
         View view = new View(sContext);
         attachViewToWindow(view);
@@ -611,8 +625,9 @@
      * <7%: FRAME_RATE_CATEGORY_NORMAL
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_voteFrameRateCategory_smallSize_defaultHigh() {
         View view = new View(sContext);
         WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY);
@@ -639,8 +654,9 @@
      * >=7% : FRAME_RATE_CATEGORY_HIGH
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_voteFrameRateCategory_normalSize_defaultHigh() {
         View view = new View(sContext);
         WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY);
@@ -671,8 +687,8 @@
      * It should take the max value among all of the voted categories per frame.
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_voteFrameRateCategory_aggregate() {
         View view = new View(sContext);
         attachViewToWindow(view);
@@ -717,8 +733,8 @@
      * prioritize 60Hz..
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_voteFrameRate_aggregate() {
         View view = new View(sContext);
         attachViewToWindow(view);
@@ -776,8 +792,9 @@
      * submit your preferred choice to the ViewRootImpl.
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_voteFrameRate_category() {
         View view = new View(sContext);
         attachViewToWindow(view);
@@ -816,8 +833,10 @@
      * Also, we shouldn't call setFrameRate.
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY, FLAG_VIEW_VELOCITY_API})
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_VIEW_VELOCITY_API,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_voteFrameRateCategory_velocityToHigh() {
         View view = new View(sContext);
         WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY);
@@ -848,8 +867,8 @@
      * We should boost the frame rate if the value of mInsetsAnimationRunning is true.
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_insetsAnimation() {
         View view = new View(sContext);
         WindowManager.LayoutParams wmlp = new WindowManager.LayoutParams(TYPE_APPLICATION_OVERLAY);
@@ -885,8 +904,8 @@
      * Test FrameRateBoostOnTouchEnabled API
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_frameRateBoostOnTouch() {
         View view = new View(sContext);
         attachViewToWindow(view);
@@ -918,8 +937,8 @@
      * mPreferredFrameRate should be set to 0.
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_voteFrameRateTimeOut() throws InterruptedException {
         final long delay = 200L;
 
@@ -956,8 +975,9 @@
      * A View should either vote a frame rate or a frame rate category instead of both.
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_voteFrameRateOnly() {
         View view = new View(sContext);
         float frameRate = 20;
@@ -999,8 +1019,9 @@
      * - otherwise, use the previous category value.
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_infrequentLayer_defaultHigh() throws InterruptedException {
         final long delay = 200L;
 
@@ -1068,8 +1089,8 @@
      * Test the IsFrameRatePowerSavingsBalanced values are properly set
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_isFrameRatePowerSavingsBalanced() {
         View view = new View(sContext);
         attachViewToWindow(view);
@@ -1101,8 +1122,9 @@
      * 2. If FT2-FT1 > 15ms && FT3-FT2 > 15ms -> vote for NORMAL category
      */
     @Test
-    @Ignore("Can be enabled only after b/330596920 is ready")
-    @RequiresFlagsEnabled(FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY)
+    @RequiresFlagsEnabled({FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_FUNCTION_ENABLING_READ_ONLY,
+            FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY})
     public void votePreferredFrameRate_applyTextureViewHeuristic() throws InterruptedException {
         final long delay = 30L;
 
diff --git a/core/tests/coretests/src/android/widget/HorizontalScrollViewFunctionalTest.java b/core/tests/coretests/src/android/widget/HorizontalScrollViewFunctionalTest.java
index cd38bd6..5d62f1c 100644
--- a/core/tests/coretests/src/android/widget/HorizontalScrollViewFunctionalTest.java
+++ b/core/tests/coretests/src/android/widget/HorizontalScrollViewFunctionalTest.java
@@ -99,13 +99,29 @@
             mMyHorizontalScrollView.setFrameContentVelocity(0);
         });
         // set setFrameContentVelocity shouldn't do anything.
-        assertEquals(mMyHorizontalScrollView.isSetVelocityCalled, false);
+        assertTrue(mMyHorizontalScrollView.isSetVelocityCalled);
+        assertEquals(0f, mMyHorizontalScrollView.velocity, 0f);
+        mMyHorizontalScrollView.isSetVelocityCalled = false;
 
         mActivityRule.runOnUiThread(() -> {
             mMyHorizontalScrollView.fling(100);
         });
         // set setFrameContentVelocity should be called when fling.
-        assertEquals(mMyHorizontalScrollView.isSetVelocityCalled, true);
+        assertTrue(mMyHorizontalScrollView.isSetVelocityCalled);
+        assertTrue(mMyHorizontalScrollView.velocity > 0f);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
+    public void hasVelocityInSmoothScrollBy() throws Throwable {
+        int maxScroll = mMyHorizontalScrollView.getChildAt(0).getWidth()
+                - mMyHorizontalScrollView.getWidth();
+        mActivityRule.runOnUiThread(() -> {
+            mMyHorizontalScrollView.smoothScrollTo(maxScroll, 0);
+        });
+        PollingCheck.waitFor(() -> mMyHorizontalScrollView.getScrollX() != 0);
+        assertTrue(mMyHorizontalScrollView.isSetVelocityCalled);
+        assertTrue(mMyHorizontalScrollView.velocity > 0f);
     }
 
     static class WatchedEdgeEffect extends EdgeEffect {
@@ -122,9 +138,10 @@
         }
     }
 
-    public static class MyHorizontalScrollView extends ScrollView {
+    public static class MyHorizontalScrollView extends HorizontalScrollView {
 
         public boolean isSetVelocityCalled;
+        public float velocity;
 
         public MyHorizontalScrollView(Context context) {
             super(context);
@@ -140,9 +157,8 @@
 
         @Override
         public void setFrameContentVelocity(float pixelsPerSecond) {
-            if (pixelsPerSecond != 0) {
-                isSetVelocityCalled = true;
-            }
+            isSetVelocityCalled = true;
+            velocity = pixelsPerSecond;
         }
     }
 }
diff --git a/core/tests/coretests/src/android/widget/ScrollViewFunctionalTest.java b/core/tests/coretests/src/android/widget/ScrollViewFunctionalTest.java
index a60b2a13..6d0bab5 100644
--- a/core/tests/coretests/src/android/widget/ScrollViewFunctionalTest.java
+++ b/core/tests/coretests/src/android/widget/ScrollViewFunctionalTest.java
@@ -19,6 +19,7 @@
 import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
@@ -98,13 +99,28 @@
             mMyScrollView.setFrameContentVelocity(0);
         });
         // set setFrameContentVelocity shouldn't do anything.
-        assertEquals(mMyScrollView.isSetVelocityCalled, false);
+        assertTrue(mMyScrollView.isSetVelocityCalled);
+        assertEquals(0f, mMyScrollView.velocity, 0f);
+        mMyScrollView.isSetVelocityCalled = false;
 
         mActivityRule.runOnUiThread(() -> {
             mMyScrollView.fling(100);
         });
         // set setFrameContentVelocity should be called when fling.
-        assertEquals(mMyScrollView.isSetVelocityCalled, true);
+        assertTrue(mMyScrollView.isSetVelocityCalled);
+        assertNotEquals(0f, mMyScrollView.velocity, 0.01f);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(FLAG_VIEW_VELOCITY_API)
+    public void hasVelocityInSmoothScrollBy() throws Throwable {
+        int maxScroll = mMyScrollView.getChildAt(0).getHeight() - mMyScrollView.getHeight();
+        mActivityRule.runOnUiThread(() -> {
+            mMyScrollView.smoothScrollTo(0, maxScroll);
+        });
+        PollingCheck.waitFor(() -> mMyScrollView.getScrollY() != 0);
+        assertTrue(mMyScrollView.isSetVelocityCalled);
+        assertTrue(mMyScrollView.velocity > 0f);
     }
 
     static class WatchedEdgeEffect extends EdgeEffect {
@@ -125,6 +141,8 @@
 
         public boolean isSetVelocityCalled;
 
+        public float velocity;
+
         public MyScrollView(Context context) {
             super(context);
         }
@@ -139,9 +157,8 @@
 
         @Override
         public void setFrameContentVelocity(float pixelsPerSecond) {
-            if (pixelsPerSecond != 0) {
-                isSetVelocityCalled = true;
-            }
+            isSetVelocityCalled = true;
+            velocity = pixelsPerSecond;
         }
     }
 }
diff --git a/core/tests/coretests/src/android/window/WindowMetricsHelperTest.java b/core/tests/coretests/src/android/window/WindowMetricsHelperTest.java
index 22e8806..7cbb6b4 100644
--- a/core/tests/coretests/src/android/window/WindowMetricsHelperTest.java
+++ b/core/tests/coretests/src/android/window/WindowMetricsHelperTest.java
@@ -16,12 +16,19 @@
 
 package android.window;
 
+import static android.view.WindowInsets.Type.displayCutout;
+import static android.view.WindowInsets.Type.navigationBars;
+
 import static org.junit.Assert.assertEquals;
 
 import android.app.Activity;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.view.WindowInsets;
 import android.view.WindowMetrics;
 
 import androidx.test.filters.SmallTest;
@@ -51,24 +58,44 @@
     @Rule
     public ActivityTestRule<TestActivity> mActivityRule =
             new ActivityTestRule<>(TestActivity.class);
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule =
+            DeviceFlagsValueProvider.createCheckFlagsRule();
 
     @Test
-    public void testGetLegacySizeMatchesDisplayGetSize() throws Throwable {
-        if (Flags.insetsDecoupledConfiguration()) {
-            // TODO (b/151861875): Introduce new test to cover the new behavior.
-            return;
-        }
+    @RequiresFlagsDisabled(Flags.FLAG_INSETS_DECOUPLED_CONFIGURATION)
+    public void testGetBoundsExcludingNavigationBarAndCutoutMatchesDisplayGetSize()
+            throws Throwable {
         mActivityRule.runOnUiThread(() -> {
             Activity activity = mActivityRule.getActivity();
             final WindowMetrics metrics = activity.getWindowManager().getCurrentWindowMetrics();
-            final Rect legacyBounds = WindowMetricsHelper
+            final Rect boundsExcludingNavBarAndCutout = WindowMetricsHelper
                     .getBoundsExcludingNavigationBarAndCutout(metrics);
 
             final Point expectedSize = new Point();
             activity.getDisplay().getSize(expectedSize);
 
-            assertEquals(expectedSize.x, legacyBounds.width());
-            assertEquals(expectedSize.y, legacyBounds.height());
+            assertEquals(expectedSize.x, boundsExcludingNavBarAndCutout.width());
+            assertEquals(expectedSize.y, boundsExcludingNavBarAndCutout.height());
+        });
+    }
+
+    @Test
+    public void testGetBoundsExcludingNavigationBarAndCutout()
+            throws Throwable {
+        mActivityRule.runOnUiThread(() -> {
+            Activity activity = mActivityRule.getActivity();
+            final WindowMetrics metrics = activity.getWindowManager().getCurrentWindowMetrics();
+            final Rect boundsExcludingNavBarAndCutout = WindowMetricsHelper
+                    .getBoundsExcludingNavigationBarAndCutout(metrics);
+
+            final WindowInsets windowInsets = metrics.getWindowInsets();
+            final Rect expectedBounds = new Rect(metrics.getBounds());
+            expectedBounds.inset(windowInsets.getInsetsIgnoringVisibility(
+                    navigationBars() | displayCutout()));
+
+            assertEquals(expectedBounds.width(), boundsExcludingNavBarAndCutout.width());
+            assertEquals(expectedBounds.height(), boundsExcludingNavBarAndCutout.height());
         });
     }
 
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutChooserActivityTest.java
index 745390d..9f5ed29 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutChooserActivityTest.java
@@ -53,7 +53,6 @@
 import android.content.pm.ServiceInfo;
 import android.os.Bundle;
 import android.os.Handler;
-import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.support.test.uiautomator.By;
@@ -63,7 +62,6 @@
 import android.view.View;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.Flags;
 import android.view.accessibility.IAccessibilityManager;
 import android.widget.Button;
 
@@ -298,7 +296,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_ALLOW_SHORTCUT_CHOOSER_ON_LOCKSCREEN)
     public void createDialog_onLockscreen_hasExpectedContent() {
         when(mKeyguardManager.isKeyguardLocked()).thenReturn(true);
         launchActivity();
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
index 75b0d4a..365f348 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
@@ -21,13 +21,13 @@
 import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN;
 import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
 import static android.provider.Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.ONE_HANDED_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.REDUCE_BRIGHT_COLORS_COMPONENT_NAME;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -64,9 +64,6 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.Vibrator;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.provider.Settings;
 import android.speech.tts.TextToSpeech;
 import android.speech.tts.Voice;
@@ -74,7 +71,6 @@
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.Flags;
 import android.view.accessibility.IAccessibilityManager;
 import android.widget.Toast;
 
@@ -87,7 +83,6 @@
 
 import org.junit.AfterClass;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -103,9 +98,6 @@
 
 @RunWith(AndroidJUnit4.class)
 public class AccessibilityShortcutControllerTest {
-    @Rule
-    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
-
     private static final String SERVICE_NAME_STRING = "fake.package/fake.service.name";
     private static final CharSequence PACKAGE_NAME_STRING = "Service name";
     private static final String SERVICE_NAME_SUMMARY = "Summary";
@@ -440,7 +432,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_UPDATE_ALWAYS_ON_A11Y_SERVICE)
     public void turnOffVolumeShortcutForAlwaysOnA11yService_shouldTurnOffA11yService()
             throws Exception {
         configureApplicationTargetSdkVersion(Build.VERSION_CODES.R);
@@ -452,7 +443,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_UPDATE_ALWAYS_ON_A11Y_SERVICE)
     public void turnOffVolumeShortcutForAlwaysOnA11yService_hasOtherTypesShortcut_shouldNotTurnOffA11yService()
             throws Exception {
         configureApplicationTargetSdkVersion(Build.VERSION_CODES.R);
@@ -726,14 +716,14 @@
 
     private void configureNoShortcutService() throws Exception {
         when(mAccessibilityManagerService
-                .getAccessibilityShortcutTargets(ACCESSIBILITY_SHORTCUT_KEY))
+                .getAccessibilityShortcutTargets(HARDWARE))
                 .thenReturn(Collections.emptyList());
         Settings.Secure.putString(mContentResolver, ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "");
     }
 
     private void configureValidShortcutService() throws Exception {
         when(mAccessibilityManagerService
-                .getAccessibilityShortcutTargets(ACCESSIBILITY_SHORTCUT_KEY))
+                .getAccessibilityShortcutTargets(HARDWARE))
                 .thenReturn(Collections.singletonList(SERVICE_NAME_STRING));
         Settings.Secure.putString(
                 mContentResolver, ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, SERVICE_NAME_STRING);
@@ -744,7 +734,7 @@
                 (ComponentName) AccessibilityShortcutController.getFrameworkShortcutFeaturesMap()
                         .keySet().toArray()[0];
         when(mAccessibilityManagerService
-                .getAccessibilityShortcutTargets(ACCESSIBILITY_SHORTCUT_KEY))
+                .getAccessibilityShortcutTargets(HARDWARE))
                 .thenReturn(Collections.singletonList(featureComponentName.flattenToString()));
         Settings.Secure.putString(mContentResolver, ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
                 featureComponentName.flattenToString());
@@ -806,7 +796,7 @@
 
     private void configureDefaultAccessibilityService() throws Exception {
         when(mAccessibilityManagerService
-                .getAccessibilityShortcutTargets(ACCESSIBILITY_SHORTCUT_KEY))
+                .getAccessibilityShortcutTargets(HARDWARE))
                 .thenReturn(Collections.singletonList(SERVICE_NAME_STRING));
 
         when(mResources.getString(R.string.config_defaultAccessibilityService)).thenReturn(
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTargetTest.java b/core/tests/coretests/src/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTargetTest.java
index 69b6a9b7a..2ea044c 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTargetTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/dialog/InvisibleToggleAccessibilityServiceTargetTest.java
@@ -39,6 +39,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.accessibility.TestUtils;
+import com.android.internal.accessibility.common.ShortcutConstants;
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.internal.util.test.FakeSettingsProviderRule;
 
@@ -99,7 +100,7 @@
 
         mSut = new InvisibleToggleAccessibilityServiceTarget(
                 mContextSpy,
-                AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY, accessibilityServiceInfo);
+                ShortcutConstants.UserShortcutType.HARDWARE, accessibilityServiceInfo);
     }
 
     @Test
diff --git a/data/etc/com.android.settings.xml b/data/etc/com.android.settings.xml
index 6bdd291..cd68503 100644
--- a/data/etc/com.android.settings.xml
+++ b/data/etc/com.android.settings.xml
@@ -67,5 +67,6 @@
         <permission name="android.permission.READ_SAFETY_CENTER_STATUS" />
         <permission name="android.permission.SEND_SAFETY_CENTER_UPDATE" />
         <permission name="android.permission.LIST_ENABLED_CREDENTIAL_PROVIDERS" />
+        <permission name="android.permission.SATELLITE_COMMUNICATION" />
     </privapp-permissions>
 </permissions>
diff --git a/data/etc/core.protolog.pb b/data/etc/core.protolog.pb
index e1670be..826adc39 100644
--- a/data/etc/core.protolog.pb
+++ b/data/etc/core.protolog.pb
Binary files differ
diff --git a/graphics/java/Android.bp b/graphics/java/Android.bp
index ece453d..f4abd0a 100644
--- a/graphics/java/Android.bp
+++ b/graphics/java/Android.bp
@@ -11,6 +11,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 1e41b4d..4ab09eb 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"
@@ -14,4 +15,4 @@
      namespace: "core_graphics"
      description: "Feature flag for YUV image compress to Ultra HDR."
      bug: "308978825"
-}
\ No newline at end of file
+}
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 250362b..319f115 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -41,12 +41,15 @@
 import libcore.util.NativeAllocationRegistry;
 
 import java.io.IOException;
+import java.io.ByteArrayOutputStream;
 import java.io.OutputStream;
 import java.lang.ref.WeakReference;
 import java.nio.Buffer;
 import java.nio.ByteBuffer;
 import java.nio.IntBuffer;
 import java.nio.ShortBuffer;
+import java.util.ArrayList;
+import java.util.WeakHashMap;
 
 public final class Bitmap implements Parcelable {
     private static final String TAG = "Bitmap";
@@ -120,6 +123,11 @@
     }
 
     /**
+     * @hide
+     */
+    private static final WeakHashMap<Bitmap, Void> sAllBitmaps = new WeakHashMap<>();
+
+    /**
      * Private constructor that must receive an already allocated native bitmap
      * int (pointer).
      */
@@ -162,6 +170,9 @@
                     Bitmap.class.getClassLoader(), nativeGetNativeFinalizer(), allocationByteCount);
         }
         registry.registerNativeAllocation(this, nativeBitmap);
+        synchronized (Bitmap.class) {
+          sAllBitmaps.put(this, null);
+        }
     }
 
     /**
@@ -1510,6 +1521,86 @@
     }
 
     /**
+     * @hide
+     */
+    private static final class DumpData {
+        private int count;
+        private int format;
+        private long[] natives;
+        private byte[][] buffers;
+        private int max;
+
+        public DumpData(@NonNull CompressFormat format, int max) {
+            this.max = max;
+            this.format = format.nativeInt;
+            this.natives = new long[max];
+            this.buffers = new byte[max][];
+            this.count = 0;
+        }
+
+        public void add(long nativePtr, byte[] buffer) {
+            natives[count] = nativePtr;
+            buffers[count] = buffer;
+            count = (count >= max) ? max : count + 1;
+        }
+
+        public int size() {
+            return count;
+        }
+    }
+
+    /**
+     * @hide
+     */
+    private static DumpData dumpData = null;
+
+
+    /**
+     * @hide
+     *
+     * Dump all the bitmaps with their contents compressed into dumpData
+     *
+     * @param format  format of the compressed image, null to clear dump data
+     */
+    public static void dumpAll(@Nullable String format) {
+        if (format == null) {
+            /* release the dump data */
+            dumpData = null;
+            return;
+        }
+        final CompressFormat fmt;
+        if (format.equals("jpg") || format.equals("jpeg")) {
+            fmt = CompressFormat.JPEG;
+        } else if (format.equals("png")) {
+            fmt = CompressFormat.PNG;
+        } else if (format.equals("webp")) {
+            fmt = CompressFormat.WEBP_LOSSLESS;
+        } else {
+            Log.w(TAG, "No bitmaps dumped: unrecognized format " + format);
+            return;
+        }
+
+        final ArrayList<Bitmap> allBitmaps;
+        synchronized (Bitmap.class) {
+          allBitmaps = new ArrayList<>(sAllBitmaps.size());
+          for (Bitmap bitmap : sAllBitmaps.keySet()) {
+            if (bitmap != null && !bitmap.isRecycled()) {
+              allBitmaps.add(bitmap);
+            }
+          }
+        }
+
+        dumpData = new DumpData(fmt, allBitmaps.size());
+        for (Bitmap bitmap : allBitmaps) {
+            ByteArrayOutputStream bas = new ByteArrayOutputStream();
+            if (bitmap.compress(fmt, 90, bas)) {
+                dumpData.add(bitmap.getNativeInstance(), bas.toByteArray());
+            }
+        }
+        Log.i(TAG, dumpData.size() + "/" + allBitmaps.size() + " bitmaps dumped");
+    }
+
+    /**
      * Number of bytes of temp storage we use for communicating between the
      * native compressor and the java OutputStream.
      */
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 2cac2e1..2f2215f 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -17,7 +17,6 @@
 package android.security;
 
 import android.compat.annotation.UnsupportedAppUsage;
-import android.os.StrictMode;
 
 /**
  * This class provides some constants and helper methods related to Android's Keystore service.
@@ -38,17 +37,4 @@
     public static KeyStore getInstance() {
         return KEY_STORE;
     }
-
-    /**
-     * Add an authentication record to the keystore authorization table.
-     *
-     * @param authToken The packed bytes of a hw_auth_token_t to be provided to keymaster.
-     * @return 0 on success, otherwise an error value corresponding to a
-     * {@code KeymasterDefs.KM_ERROR_} value or {@code KeyStore} ResponseCode.
-     */
-    public int addAuthToken(byte[] authToken) {
-        StrictMode.noteDiskWrite();
-
-        return Authorization.addAuthToken(authToken);
-    }
 }
diff --git a/keystore/java/android/security/Authorization.java b/keystore/java/android/security/KeyStoreAuthorization.java
similarity index 82%
rename from keystore/java/android/security/Authorization.java
rename to keystore/java/android/security/KeyStoreAuthorization.java
index 6404c4b..14d715f 100644
--- a/keystore/java/android/security/Authorization.java
+++ b/keystore/java/android/security/KeyStoreAuthorization.java
@@ -33,15 +33,21 @@
  * @hide This is the client side for IKeystoreAuthorization AIDL.
  * It shall only be used by biometric authentication providers and Gatekeeper.
  */
-public class Authorization {
-    private static final String TAG = "KeystoreAuthorization";
+public class KeyStoreAuthorization {
+    private static final String TAG = "KeyStoreAuthorization";
 
     public static final int SYSTEM_ERROR = ResponseCode.SYSTEM_ERROR;
 
+    private static final KeyStoreAuthorization sInstance = new KeyStoreAuthorization();
+
+    public static KeyStoreAuthorization getInstance() {
+        return sInstance;
+    }
+
     /**
      * @return an instance of IKeystoreAuthorization
      */
-    public static IKeystoreAuthorization getService() {
+    private IKeystoreAuthorization getService() {
         return IKeystoreAuthorization.Stub.asInterface(
                     ServiceManager.checkService("android.security.authorization"));
     }
@@ -52,7 +58,7 @@
      * @param authToken created by Android authenticators.
      * @return 0 if successful or {@code ResponseCode.SYSTEM_ERROR}.
      */
-    public static int addAuthToken(@NonNull HardwareAuthToken authToken) {
+    public int addAuthToken(@NonNull HardwareAuthToken authToken) {
         StrictMode.noteSlowCall("addAuthToken");
         try {
             getService().addAuthToken(authToken);
@@ -70,7 +76,7 @@
      * @param authToken
      * @return 0 if successful or a {@code ResponseCode}.
      */
-    public static int addAuthToken(@NonNull byte[] authToken) {
+    public int addAuthToken(@NonNull byte[] authToken) {
         return addAuthToken(AuthTokenUtils.toHardwareAuthToken(authToken));
     }
 
@@ -82,7 +88,7 @@
      *                   is LSKF (or equivalent) and thus has made the synthetic password available
      * @return 0 if successful or a {@code ResponseCode}.
      */
-    public static int onDeviceUnlocked(int userId, @Nullable byte[] password) {
+    public int onDeviceUnlocked(int userId, @Nullable byte[] password) {
         StrictMode.noteDiskWrite();
         try {
             getService().onDeviceUnlocked(userId, password);
@@ -103,7 +109,7 @@
      * @param weakUnlockEnabled - true if non-strong biometric or trust agent unlock is enabled
      * @return 0 if successful or a {@code ResponseCode}.
      */
-    public static int onDeviceLocked(int userId, @NonNull long[] unlockingSids,
+    public int onDeviceLocked(int userId, @NonNull long[] unlockingSids,
             boolean weakUnlockEnabled) {
         StrictMode.noteDiskWrite();
         try {
@@ -125,14 +131,17 @@
      * @return the last authentication time or
      * {@link BiometricConstants#BIOMETRIC_NO_AUTHENTICATION}.
      */
-    public static long getLastAuthenticationTime(
-            long userId, @HardwareAuthenticatorType int[] authenticatorTypes) {
+    public long getLastAuthTime(long userId, @HardwareAuthenticatorType int[] authenticatorTypes) {
         try {
             return getService().getLastAuthTime(userId, authenticatorTypes);
         } catch (RemoteException | NullPointerException e) {
-            Log.w(TAG, "Can not connect to keystore", e);
+            Log.w(TAG, "Error getting last auth time: " + e);
             return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION;
         } catch (ServiceSpecificException e) {
+            // This is returned when the feature flag test fails in keystore2
+            if (e.errorCode == ResponseCode.PERMISSION_DENIED) {
+                throw new UnsupportedOperationException();
+            }
             return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION;
         }
     }
diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index b749a06..5c978e2 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -210,7 +210,7 @@
         "androidx.recyclerview_recyclerview",
         "kotlinx-coroutines-android",
         "kotlinx-coroutines-core",
-        "iconloader_base",
+        "//frameworks/libs/systemui:iconloader_base",
         "com_android_wm_shell_flags_lib",
         "com.android.window.flags.window-aconfig-java",
         "WindowManager-Shell-proto",
diff --git a/libs/WindowManager/Shell/aconfig/Android.bp b/libs/WindowManager/Shell/aconfig/Android.bp
index 1a98ffc..7f8f57b 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",
     ],
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
index b61dda4..7ff204c 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: "enable_app_pairs"
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarDropTargetControllerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarDropTargetControllerTest.kt
deleted file mode 100644
index 2ac7791..0000000
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarDropTargetControllerTest.kt
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.wm.shell.bubbles.bar
-
-import android.content.Context
-import android.graphics.Insets
-import android.graphics.Rect
-import android.view.View
-import android.view.WindowManager
-import android.widget.FrameLayout
-import androidx.core.animation.AnimatorTestRule
-import androidx.test.core.app.ApplicationProvider
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import androidx.test.platform.app.InstrumentationRegistry
-import com.android.internal.protolog.common.ProtoLog
-import com.android.wm.shell.R
-import com.android.wm.shell.bubbles.BubblePositioner
-import com.android.wm.shell.bubbles.DeviceConfig
-import com.android.wm.shell.bubbles.bar.BubbleBarDropTargetController.Companion.DROP_TARGET_ALPHA_IN_DURATION
-import com.android.wm.shell.bubbles.bar.BubbleBarDropTargetController.Companion.DROP_TARGET_ALPHA_OUT_DURATION
-import com.android.wm.shell.bubbles.bar.BubbleBarDropTargetController.Companion.DROP_TARGET_SCALE
-import com.android.wm.shell.common.bubbles.BubbleBarLocation
-import com.google.common.truth.Truth.assertThat
-import org.junit.Before
-import org.junit.ClassRule
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/** Tests for [BubbleBarDropTargetController] */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class BubbleBarDropTargetControllerTest {
-
-    companion object {
-        @JvmField @ClassRule val animatorTestRule: AnimatorTestRule = AnimatorTestRule()
-    }
-
-    private val context = ApplicationProvider.getApplicationContext<Context>()
-    private lateinit var controller: BubbleBarDropTargetController
-    private lateinit var positioner: BubblePositioner
-    private lateinit var container: FrameLayout
-
-    @Before
-    fun setUp() {
-        ProtoLog.REQUIRE_PROTOLOGTOOL = false
-        container = FrameLayout(context)
-        val windowManager = context.getSystemService(WindowManager::class.java)
-        positioner = BubblePositioner(context, windowManager)
-        positioner.setShowingInBubbleBar(true)
-        val deviceConfig =
-            DeviceConfig(
-                windowBounds = Rect(0, 0, 2000, 2600),
-                isLargeScreen = true,
-                isSmallTablet = false,
-                isLandscape = true,
-                isRtl = false,
-                insets = Insets.of(10, 20, 30, 40)
-            )
-        positioner.update(deviceConfig)
-        positioner.bubbleBarBounds = Rect(1800, 2400, 1970, 2560)
-
-        controller = BubbleBarDropTargetController(context, container, positioner)
-    }
-
-    @Test
-    fun show_moveLeftToRight_isVisibleWithExpectedBounds() {
-        val expectedBoundsOnLeft = getExpectedDropTargetBounds(onLeft = true)
-        val expectedBoundsOnRight = getExpectedDropTargetBounds(onLeft = false)
-
-        runOnMainSync { controller.show(BubbleBarLocation.LEFT) }
-        waitForAnimateIn()
-        val viewOnLeft = getDropTargetView()
-        assertThat(viewOnLeft).isNotNull()
-        assertThat(viewOnLeft!!.alpha).isEqualTo(1f)
-        assertThat(viewOnLeft.layoutParams.width).isEqualTo(expectedBoundsOnLeft.width())
-        assertThat(viewOnLeft.layoutParams.height).isEqualTo(expectedBoundsOnLeft.height())
-        assertThat(viewOnLeft.x).isEqualTo(expectedBoundsOnLeft.left)
-        assertThat(viewOnLeft.y).isEqualTo(expectedBoundsOnLeft.top)
-
-        runOnMainSync { controller.show(BubbleBarLocation.RIGHT) }
-        waitForAnimateOut()
-        waitForAnimateIn()
-        val viewOnRight = getDropTargetView()
-        assertThat(viewOnRight).isNotNull()
-        assertThat(viewOnRight!!.alpha).isEqualTo(1f)
-        assertThat(viewOnRight.layoutParams.width).isEqualTo(expectedBoundsOnRight.width())
-        assertThat(viewOnRight.layoutParams.height).isEqualTo(expectedBoundsOnRight.height())
-        assertThat(viewOnRight.x).isEqualTo(expectedBoundsOnRight.left)
-        assertThat(viewOnRight.y).isEqualTo(expectedBoundsOnRight.top)
-    }
-
-    @Test
-    fun toggleSetHidden_dropTargetShown_updatesAlpha() {
-        runOnMainSync { controller.show(BubbleBarLocation.RIGHT) }
-        waitForAnimateIn()
-        val view = getDropTargetView()
-        assertThat(view).isNotNull()
-        assertThat(view!!.alpha).isEqualTo(1f)
-
-        runOnMainSync { controller.setHidden(true) }
-        waitForAnimateOut()
-        val hiddenView = getDropTargetView()
-        assertThat(hiddenView).isNotNull()
-        assertThat(hiddenView!!.alpha).isEqualTo(0f)
-
-        runOnMainSync { controller.setHidden(false) }
-        waitForAnimateIn()
-        val shownView = getDropTargetView()
-        assertThat(shownView).isNotNull()
-        assertThat(shownView!!.alpha).isEqualTo(1f)
-    }
-
-    @Test
-    fun toggleSetHidden_dropTargetNotShown_viewNotCreated() {
-        runOnMainSync { controller.setHidden(true) }
-        waitForAnimateOut()
-        assertThat(getDropTargetView()).isNull()
-        runOnMainSync { controller.setHidden(false) }
-        waitForAnimateIn()
-        assertThat(getDropTargetView()).isNull()
-    }
-
-    @Test
-    fun dismiss_dropTargetShown_viewRemoved() {
-        runOnMainSync { controller.show(BubbleBarLocation.LEFT) }
-        waitForAnimateIn()
-        assertThat(getDropTargetView()).isNotNull()
-        runOnMainSync { controller.dismiss() }
-        waitForAnimateOut()
-        assertThat(getDropTargetView()).isNull()
-    }
-
-    @Test
-    fun dismiss_dropTargetNotShown_doesNothing() {
-        runOnMainSync { controller.dismiss() }
-        waitForAnimateOut()
-        assertThat(getDropTargetView()).isNull()
-    }
-
-    private fun getDropTargetView(): View? = container.findViewById(R.id.bubble_bar_drop_target)
-
-    private fun getExpectedDropTargetBounds(onLeft: Boolean): Rect {
-        val rect = Rect()
-        positioner.getBubbleBarExpandedViewBounds(onLeft, false /* isOveflowExpanded */, rect)
-        // Scale the rect to expected size, but keep the center point the same
-        val centerX = rect.centerX()
-        val centerY = rect.centerY()
-        rect.scale(DROP_TARGET_SCALE)
-        rect.offset(centerX - rect.centerX(), centerY - rect.centerY())
-        return rect
-    }
-
-    private fun runOnMainSync(runnable: Runnable) {
-        InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable)
-    }
-
-    private fun waitForAnimateIn() {
-        // Advance animator for on-device test
-        runOnMainSync { animatorTestRule.advanceTimeBy(DROP_TARGET_ALPHA_IN_DURATION) }
-    }
-
-    private fun waitForAnimateOut() {
-        // Advance animator for on-device test
-        runOnMainSync { animatorTestRule.advanceTimeBy(DROP_TARGET_ALPHA_OUT_DURATION) }
-    }
-}
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
new file mode 100644
index 0000000..e1bf40c
--- /dev/null
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinControllerTest.kt
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.bubbles.bar
+
+import android.content.Context
+import android.graphics.Insets
+import android.graphics.PointF
+import android.graphics.Rect
+import android.view.View
+import android.view.WindowManager
+import android.widget.FrameLayout
+import androidx.core.animation.AnimatorTestRule
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.internal.protolog.common.ProtoLog
+import com.android.wm.shell.R
+import com.android.wm.shell.bubbles.BubblePositioner
+import com.android.wm.shell.bubbles.DeviceConfig
+import com.android.wm.shell.bubbles.bar.BubbleExpandedViewPinController.Companion.DROP_TARGET_SCALE
+import com.android.wm.shell.common.bubbles.BaseBubblePinController
+import com.android.wm.shell.common.bubbles.BaseBubblePinController.Companion.DROP_TARGET_ALPHA_IN_DURATION
+import com.android.wm.shell.common.bubbles.BaseBubblePinController.Companion.DROP_TARGET_ALPHA_OUT_DURATION
+import com.android.wm.shell.common.bubbles.BubbleBarLocation
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Before
+import org.junit.ClassRule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** Tests for [BubbleExpandedViewPinController] */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BubbleExpandedViewPinControllerTest {
+
+    companion object {
+        @JvmField @ClassRule val animatorTestRule: AnimatorTestRule = AnimatorTestRule()
+
+        const val SCREEN_WIDTH = 2000
+        const val SCREEN_HEIGHT = 1000
+
+        const val BUBBLE_BAR_WIDTH = 100
+        const val BUBBLE_BAR_HEIGHT = 50
+    }
+
+    private val context = ApplicationProvider.getApplicationContext<Context>()
+    private lateinit var positioner: BubblePositioner
+    private lateinit var container: FrameLayout
+
+    private lateinit var controller: BubbleExpandedViewPinController
+    private lateinit var testListener: TestLocationChangeListener
+
+    private val pointOnLeft = PointF(100f, 100f)
+    private val pointOnRight = PointF(1900f, 500f)
+
+    @Before
+    fun setUp() {
+        ProtoLog.REQUIRE_PROTOLOGTOOL = false
+        container = FrameLayout(context)
+        val windowManager = context.getSystemService(WindowManager::class.java)
+        positioner = BubblePositioner(context, windowManager)
+        positioner.setShowingInBubbleBar(true)
+        val deviceConfig =
+            DeviceConfig(
+                windowBounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
+                isLargeScreen = true,
+                isSmallTablet = false,
+                isLandscape = true,
+                isRtl = false,
+                insets = Insets.of(10, 20, 30, 40)
+            )
+        positioner.update(deviceConfig)
+        positioner.bubbleBarBounds =
+            Rect(
+                SCREEN_WIDTH - deviceConfig.insets.right - BUBBLE_BAR_WIDTH,
+                SCREEN_HEIGHT - deviceConfig.insets.bottom - BUBBLE_BAR_HEIGHT,
+                SCREEN_WIDTH - deviceConfig.insets.right,
+                SCREEN_HEIGHT - deviceConfig.insets.bottom
+            )
+
+        controller = BubbleExpandedViewPinController(context, container, positioner)
+        testListener = TestLocationChangeListener()
+        controller.setListener(testListener)
+    }
+
+    @After
+    fun tearDown() {
+        runOnMainSync { controller.onDragEnd() }
+        waitForAnimateOut()
+    }
+
+    @Test
+    fun onDragUpdate_stayOnSameSide() {
+        runOnMainSync {
+            controller.onDragStart(initialLocationOnLeft = false)
+            controller.onDragUpdate(pointOnRight.x, pointOnRight.y)
+        }
+        waitForAnimateIn()
+        assertThat(dropTargetView).isNull()
+        assertThat(testListener.locationChanges).isEmpty()
+    }
+
+    @Test
+    fun onDragUpdate_toLeft() {
+        runOnMainSync {
+            controller.onDragStart(initialLocationOnLeft = false)
+            controller.onDragUpdate(pointOnLeft.x, pointOnLeft.y)
+        }
+        waitForAnimateIn()
+
+        assertThat(dropTargetView).isNotNull()
+        assertThat(dropTargetView!!.alpha).isEqualTo(1f)
+
+        val expectedDropTargetBounds = getExpectedDropTargetBounds(onLeft = true)
+        assertThat(dropTargetView!!.layoutParams.width).isEqualTo(expectedDropTargetBounds.width())
+        assertThat(dropTargetView!!.layoutParams.height)
+            .isEqualTo(expectedDropTargetBounds.height())
+
+        assertThat(testListener.locationChanges).containsExactly(BubbleBarLocation.LEFT)
+    }
+
+    @Test
+    fun onDragUpdate_toLeftAndBackToRight() {
+        runOnMainSync {
+            controller.onDragStart(initialLocationOnLeft = false)
+            controller.onDragUpdate(pointOnLeft.x, pointOnLeft.y)
+        }
+        waitForAnimateIn()
+        assertThat(dropTargetView).isNotNull()
+
+        runOnMainSync { controller.onDragUpdate(pointOnRight.x, pointOnRight.y) }
+        // We have to wait for existing drop target to animate out and new to animate in
+        waitForAnimateOut()
+        waitForAnimateIn()
+
+        assertThat(dropTargetView).isNotNull()
+        assertThat(dropTargetView!!.alpha).isEqualTo(1f)
+
+        val expectedDropTargetBounds = getExpectedDropTargetBounds(onLeft = false)
+        assertThat(dropTargetView!!.layoutParams.width).isEqualTo(expectedDropTargetBounds.width())
+        assertThat(dropTargetView!!.layoutParams.height)
+            .isEqualTo(expectedDropTargetBounds.height())
+
+        assertThat(testListener.locationChanges)
+            .containsExactly(BubbleBarLocation.LEFT, BubbleBarLocation.RIGHT)
+    }
+
+    @Test
+    fun onDragUpdate_toLeftInExclusionRect() {
+        runOnMainSync {
+            controller.onDragStart(initialLocationOnLeft = false)
+            // Exclusion rect is around the bottom center area of the screen
+            controller.onDragUpdate(SCREEN_WIDTH / 2f - 50, SCREEN_HEIGHT - 100f)
+        }
+        waitForAnimateIn()
+        assertThat(dropTargetView).isNull()
+        assertThat(testListener.locationChanges).isEmpty()
+    }
+
+    @Test
+    fun toggleSetDropTargetHidden_dropTargetExists() {
+        runOnMainSync {
+            controller.onDragStart(initialLocationOnLeft = false)
+            controller.onDragUpdate(pointOnLeft.x, pointOnLeft.y)
+        }
+        waitForAnimateIn()
+
+        assertThat(dropTargetView).isNotNull()
+        assertThat(dropTargetView!!.alpha).isEqualTo(1f)
+
+        runOnMainSync { controller.setDropTargetHidden(true) }
+        waitForAnimateOut()
+        assertThat(dropTargetView).isNotNull()
+        assertThat(dropTargetView!!.alpha).isEqualTo(0f)
+
+        runOnMainSync { controller.setDropTargetHidden(false) }
+        waitForAnimateIn()
+        assertThat(dropTargetView).isNotNull()
+        assertThat(dropTargetView!!.alpha).isEqualTo(1f)
+    }
+
+    @Test
+    fun toggleSetDropTargetHidden_noDropTarget() {
+        runOnMainSync { controller.setDropTargetHidden(true) }
+        waitForAnimateOut()
+        assertThat(dropTargetView).isNull()
+
+        runOnMainSync { controller.setDropTargetHidden(false) }
+        waitForAnimateIn()
+        assertThat(dropTargetView).isNull()
+    }
+
+    @Test
+    fun onDragEnd_dropTargetExists() {
+        runOnMainSync {
+            controller.onDragStart(initialLocationOnLeft = false)
+            controller.onDragUpdate(pointOnLeft.x, pointOnLeft.y)
+        }
+        waitForAnimateIn()
+        assertThat(dropTargetView).isNotNull()
+
+        runOnMainSync { controller.onDragEnd() }
+        waitForAnimateOut()
+        assertThat(dropTargetView).isNull()
+    }
+
+    @Test
+    fun onDragEnd_noDropTarget() {
+        runOnMainSync { controller.onDragEnd() }
+        waitForAnimateOut()
+        assertThat(dropTargetView).isNull()
+    }
+
+    private val dropTargetView: View?
+        get() = container.findViewById(R.id.bubble_bar_drop_target)
+
+    private fun getExpectedDropTargetBounds(onLeft: Boolean): Rect {
+        val rect = Rect()
+        positioner.getBubbleBarExpandedViewBounds(onLeft, false /* isOveflowExpanded */, rect)
+        // Scale the rect to expected size, but keep the center point the same
+        val centerX = rect.centerX()
+        val centerY = rect.centerY()
+        rect.scale(DROP_TARGET_SCALE)
+        rect.offset(centerX - rect.centerX(), centerY - rect.centerY())
+        return rect
+    }
+
+    private fun runOnMainSync(runnable: Runnable) {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable)
+    }
+
+    private fun waitForAnimateIn() {
+        // Advance animator for on-device test
+        runOnMainSync { animatorTestRule.advanceTimeBy(DROP_TARGET_ALPHA_IN_DURATION) }
+    }
+
+    private fun waitForAnimateOut() {
+        // Advance animator for on-device test
+        runOnMainSync { animatorTestRule.advanceTimeBy(DROP_TARGET_ALPHA_OUT_DURATION) }
+    }
+
+    internal class TestLocationChangeListener : BaseBubblePinController.LocationChangeListener {
+        val locationChanges = mutableListOf<BubbleBarLocation>()
+        override fun onChange(location: BubbleBarLocation) {
+            locationChanges.add(location)
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_color_selector.xml b/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_color_selector.xml
index 65f5239..640d184 100644
--- a/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_color_selector.xml
+++ b/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_color_selector.xml
@@ -14,15 +14,13 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License
 -->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <item android:state_pressed="true"
-        android:color="@color/desktop_mode_maximize_menu_button_on_hover"/>
-    <item android:state_hovered="true"
-        android:color="@color/desktop_mode_maximize_menu_button_on_hover"/>
+        android:color="?androidprv:attr/colorAccentPrimary"/>
     <item android:state_focused="true"
-        android:color="@color/desktop_mode_maximize_menu_button_on_hover"/>
+        android:color="?androidprv:attr/colorAccentPrimary"/>
     <item android:state_selected="true"
-        android:color="@color/desktop_mode_maximize_menu_button_on_hover"/>
-    <item android:color="@color/desktop_mode_maximize_menu_button"/>
+        android:color="?androidprv:attr/colorAccentPrimary"/>
+    <item android:color="?androidprv:attr/materialColorOutlineVariant"/>
 </selector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_outline_color_selector.xml b/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_outline_color_selector.xml
deleted file mode 100644
index 86679af..0000000
--- a/libs/WindowManager/Shell/res/color/desktop_mode_maximize_menu_button_outline_color_selector.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2023 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true"
-        android:color="@color/desktop_mode_maximize_menu_button_outline_on_hover"/>
-    <item android:state_hovered="true"
-        android:color="@color/desktop_mode_maximize_menu_button_outline_on_hover"/>
-    <item android:state_focused="true"
-        android:color="@color/desktop_mode_maximize_menu_button_outline_on_hover"/>
-    <item android:state_selected="true"
-        android:color="@color/desktop_mode_maximize_menu_button_outline_on_hover"/>
-    <item android:color="@color/desktop_mode_maximize_menu_button_outline"/>
-</selector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_maximize_button_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_button_background.xml
similarity index 86%
rename from libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_maximize_button_background.xml
rename to libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_button_background.xml
index bfb0dd7..ed51498 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_maximize_button_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_button_background.xml
@@ -19,6 +19,5 @@
     android:shape="rectangle">
     <solid android:color="@color/desktop_mode_maximize_menu_button_color_selector"/>
     <corners
-        android:radius="@dimen/desktop_mode_maximize_menu_buttons_large_corner_radius"/>
-    <stroke android:width="1dp" android:color="@color/desktop_mode_maximize_menu_button_outline_color_selector"/>
+        android:radius="@dimen/desktop_mode_maximize_menu_buttons_radius"/>
 </shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_maximize_button_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_layout_background.xml
similarity index 79%
copy from libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_maximize_button_background.xml
copy to libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_layout_background.xml
index bfb0dd7..04ad572 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_maximize_button_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_layout_background.xml
@@ -16,9 +16,9 @@
 -->
 
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:shape="rectangle">
-    <solid android:color="@color/desktop_mode_maximize_menu_button_color_selector"/>
     <corners
-        android:radius="@dimen/desktop_mode_maximize_menu_buttons_large_corner_radius"/>
-    <stroke android:width="1dp" android:color="@color/desktop_mode_maximize_menu_button_outline_color_selector"/>
+        android:radius="@dimen/desktop_mode_maximize_menu_buttons_outline_radius"/>
+    <stroke android:width="1dp" android:color="?androidprv:attr/materialColorOutlineVariant"/>
 </shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_maximize_button_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_layout_background_on_hover.xml
similarity index 78%
copy from libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_maximize_button_background.xml
copy to libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_layout_background_on_hover.xml
index bfb0dd7..86da9fe 100644
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_maximize_button_background.xml
+++ b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_layout_background_on_hover.xml
@@ -16,9 +16,9 @@
 -->
 
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:shape="rectangle">
-    <solid android:color="@color/desktop_mode_maximize_menu_button_color_selector"/>
     <corners
-        android:radius="@dimen/desktop_mode_maximize_menu_buttons_large_corner_radius"/>
-    <stroke android:width="1dp" android:color="@color/desktop_mode_maximize_menu_button_outline_color_selector"/>
+        android:radius="@dimen/desktop_mode_maximize_menu_buttons_outline_radius"/>
+    <stroke android:width="1dp" android:color="?androidprv:attr/colorAccentPrimary"/>
 </shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_snap_left_button_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_snap_left_button_background.xml
deleted file mode 100644
index 6630fca..0000000
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_snap_left_button_background.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-  ~ Copyright (C) 2023 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
--->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <solid android:color="@color/desktop_mode_maximize_menu_button_color_selector"/>
-    <corners
-        android:topLeftRadius="@dimen/desktop_mode_maximize_menu_buttons_large_corner_radius"
-        android:topRightRadius="@dimen/desktop_mode_maximize_menu_buttons_small_corner_radius"
-        android:bottomLeftRadius="@dimen/desktop_mode_maximize_menu_buttons_large_corner_radius"
-        android:bottomRightRadius="@dimen/desktop_mode_maximize_menu_buttons_small_corner_radius"/>
-    <stroke android:width="1dp" android:color="@color/desktop_mode_maximize_menu_button_outline_color_selector"/>
-</shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_snap_right_button_background.xml b/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_snap_right_button_background.xml
deleted file mode 100644
index 7bd6e99..0000000
--- a/libs/WindowManager/Shell/res/drawable/desktop_mode_maximize_menu_snap_right_button_background.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<!--
-  ~ Copyright (C) 2023 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License
--->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <solid android:color="@color/desktop_mode_maximize_menu_button_color_selector"/>
-    <corners
-        android:topLeftRadius="@dimen/desktop_mode_maximize_menu_buttons_small_corner_radius"
-        android:topRightRadius="@dimen/desktop_mode_maximize_menu_buttons_large_corner_radius"
-        android:bottomLeftRadius="@dimen/desktop_mode_maximize_menu_buttons_small_corner_radius"
-        android:bottomRightRadius="@dimen/desktop_mode_maximize_menu_buttons_large_corner_radius"/>
-    <stroke android:width="1dp" android:color="@color/desktop_mode_maximize_menu_button_outline_color_selector"/>
-</shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
index fca2fe4..d5724cc 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
@@ -52,7 +52,7 @@
             android:textStyle="normal"
             android:layout_weight="1"/>
 
-        <ImageButton
+        <com.android.wm.shell.windowdecor.HandleMenuImageButton
             android:id="@+id/collapse_menu_button"
             android:layout_width="32dp"
             android:layout_height="32dp"
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
index dbfd6e5..9f0a425 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_maximize_menu.xml
@@ -15,41 +15,87 @@
   ~ limitations under the License.
   -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:id="@+id/maximize_menu"
     style="?android:attr/buttonBarStyle"
     android:layout_width="@dimen/desktop_mode_maximize_menu_width"
     android:layout_height="@dimen/desktop_mode_maximize_menu_height"
     android:orientation="horizontal"
     android:gravity="center"
+    android:padding="16dp"
     android:background="@drawable/desktop_mode_maximize_menu_background">
 
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
 
-    <Button
-        android:id="@+id/maximize_menu_maximize_button"
-        style="?android:attr/buttonBarButtonStyle"
-        android:layout_width="120dp"
-        android:layout_height="80dp"
-        android:layout_marginRight="15dp"
-        android:color="@color/desktop_mode_maximize_menu_button"
-        android:background="@drawable/desktop_mode_maximize_menu_maximize_button_background"
-        android:stateListAnimator="@null"/>
+        <FrameLayout
+            android:id="@+id/maximize_menu_maximize_button_layout"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:background="@drawable/desktop_mode_maximize_menu_layout_background"
+            android:padding="4dp"
+            android:layout_marginRight="8dp"
+            android:layout_marginBottom="4dp">
+            <Button
+                android:id="@+id/maximize_menu_maximize_button"
+                style="?android:attr/buttonBarButtonStyle"
+                android:layout_width="86dp"
+                android:layout_height="@dimen/desktop_mode_maximize_menu_button_height"
+                android:background="@drawable/desktop_mode_maximize_menu_button_background"
+                android:stateListAnimator="@null"/>
+        </FrameLayout>
 
-    <Button
-        android:id="@+id/maximize_menu_snap_left_button"
-        style="?android:attr/buttonBarButtonStyle"
-        android:layout_width="58dp"
-        android:layout_height="80dp"
-        android:layout_marginRight="6dp"
-        android:color="@color/desktop_mode_maximize_menu_button"
-        android:background="@drawable/desktop_mode_maximize_menu_snap_left_button_background"
-        android:stateListAnimator="@null"/>
+        <TextView
+            android:layout_width="94dp"
+            android:layout_height="18dp"
+            android:textSize="11sp"
+            android:layout_marginBottom="76dp"
+            android:gravity="center"
+            android:fontFamily="google-sans-text"
+            android:text="@string/desktop_mode_maximize_menu_maximize_text"
+            android:textColor="?androidprv:attr/materialColorOnSurface"/>
+    </LinearLayout>
 
-    <Button
-        android:id="@+id/maximize_menu_snap_right_button"
-        style="?android:attr/buttonBarButtonStyle"
-        android:layout_width="58dp"
-        android:layout_height="80dp"
-        android:color="@color/desktop_mode_maximize_menu_button"
-        android:background="@drawable/desktop_mode_maximize_menu_snap_right_button_background"
-        android:stateListAnimator="@null"/>
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+        <LinearLayout
+            android:id="@+id/maximize_menu_snap_menu_layout"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:padding="4dp"
+            android:background="@drawable/desktop_mode_maximize_menu_layout_background"
+            android:layout_marginBottom="4dp">
+            <Button
+                android:id="@+id/maximize_menu_snap_left_button"
+                style="?android:attr/buttonBarButtonStyle"
+                android:layout_width="41dp"
+                android:layout_height="@dimen/desktop_mode_maximize_menu_button_height"
+                android:layout_marginRight="4dp"
+                android:background="@drawable/desktop_mode_maximize_menu_button_background"
+                android:stateListAnimator="@null"/>
+
+            <Button
+                android:id="@+id/maximize_menu_snap_right_button"
+                style="?android:attr/buttonBarButtonStyle"
+                android:layout_width="41dp"
+                android:layout_height="@dimen/desktop_mode_maximize_menu_button_height"
+                android:background="@drawable/desktop_mode_maximize_menu_button_background"
+                android:stateListAnimator="@null"/>
+        </LinearLayout>
+        <TextView
+            android:layout_width="94dp"
+            android:layout_height="18dp"
+            android:textSize="11sp"
+            android:layout_marginBottom="76dp"
+            android:layout_gravity="center"
+            android:gravity="center"
+            android:fontFamily="google-sans-text"
+            android:text="@string/desktop_mode_maximize_menu_snap_text"
+            android:textColor="?androidprv:attr/materialColorOnSurface"/>
+    </LinearLayout>
 </LinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index 49935ad..ba24d7b 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -52,10 +52,10 @@
     <string name="accessibility_split_right" msgid="8441001008181296837">"Dividir para a direita"</string>
     <string name="accessibility_split_top" msgid="2789329702027147146">"Dividir para cima"</string>
     <string name="accessibility_split_bottom" msgid="8694551025220868191">"Dividir para baixo"</string>
-    <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Como usar o modo para uma mão"</string>
+    <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Como usar o modo uma mão"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para sair, deslize de baixo para cima na tela ou toque em qualquer lugar acima do app"</string>
-    <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar o modo para uma mão"</string>
-    <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Sair do modo para uma mão"</string>
+    <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar o modo uma mão"</string>
+    <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Sair do modo uma mão"</string>
     <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Configurações de balões do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Menu flutuante"</string>
     <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Devolver à pilha"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index 49935ad..ba24d7b 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -52,10 +52,10 @@
     <string name="accessibility_split_right" msgid="8441001008181296837">"Dividir para a direita"</string>
     <string name="accessibility_split_top" msgid="2789329702027147146">"Dividir para cima"</string>
     <string name="accessibility_split_bottom" msgid="8694551025220868191">"Dividir para baixo"</string>
-    <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Como usar o modo para uma mão"</string>
+    <string name="one_handed_tutorial_title" msgid="4583241688067426350">"Como usar o modo uma mão"</string>
     <string name="one_handed_tutorial_description" msgid="3486582858591353067">"Para sair, deslize de baixo para cima na tela ou toque em qualquer lugar acima do app"</string>
-    <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar o modo para uma mão"</string>
-    <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Sair do modo para uma mão"</string>
+    <string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Iniciar o modo uma mão"</string>
+    <string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Sair do modo uma mão"</string>
     <string name="bubbles_settings_button_description" msgid="1301286017420516912">"Configurações de balões do <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Menu flutuante"</string>
     <string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Devolver à pilha"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 593c8fc..9be3f33 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -17,7 +17,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="pip_phone_close" msgid="5783752637260411309">"మూసివేయి"</string>
+    <string name="pip_phone_close" msgid="5783752637260411309">"మూసివేయండి"</string>
     <string name="pip_phone_expand" msgid="2579292903468287504">"విస్తరింపజేయి"</string>
     <string name="pip_phone_settings" msgid="5468987116750491918">"సెట్టింగ్‌లు"</string>
     <string name="pip_menu_title" msgid="5393619322111827096">"మెనూ"</string>
diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml
index 758dbfd..cf18da6 100644
--- a/libs/WindowManager/Shell/res/values/colors.xml
+++ b/libs/WindowManager/Shell/res/values/colors.xml
@@ -62,10 +62,6 @@
     <color name="desktop_mode_caption_handle_bar_dark">#1C1C17</color>
     <color name="desktop_mode_resize_veil_light">#EFF1F2</color>
     <color name="desktop_mode_resize_veil_dark">#1C1C17</color>
-    <color name="desktop_mode_maximize_menu_button">#DDDACD</color>
-    <color name="desktop_mode_maximize_menu_button_outline">#797869</color>
-    <color name="desktop_mode_maximize_menu_button_outline_on_hover">#606219</color>
-    <color name="desktop_mode_maximize_menu_button_on_hover">#E7E790</color>
     <color name="desktop_mode_maximize_menu_progress_light">#33000000</color>
     <color name="desktop_mode_maximize_menu_progress_dark">#33FFFFFF</color>
     <color name="desktop_mode_caption_button_on_hover_light">#11000000</color>
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index a541c59..c2ba064 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -45,9 +45,6 @@
     <!-- Allow PIP to resize to a slightly bigger state upon touch/showing the menu -->
     <bool name="config_pipEnableResizeForMenu">true</bool>
 
-    <!-- PiP minimum size, which is a % based off the shorter side of display width and height -->
-    <fraction name="config_pipShortestEdgePercent">40%</fraction>
-
     <!-- Time (duration in milliseconds) that the shell waits for an app to close the PiP by itself
          if a custom action is present before closing it. -->
     <integer name="config_pipForceCloseDelay">1000</integer>
@@ -91,11 +88,45 @@
         16x16
     </string>
 
+    <!-- Default percentages for the PIP size logic.
+         1. Determine max widths
+         Subtract width of system UI and default padding from the shortest edge of the device.
+         This is the max width.
+         2. Calculate Default and Mins
+         Default is config_pipSystemPreferredDefaultSizePercent of max-width/height.
+         Min is config_pipSystemPreferredMinimumSizePercent of it. -->
+    <item name="config_pipSystemPreferredDefaultSizePercent" format="float" type="dimen">0.6</item>
+    <item name="config_pipSystemPreferredMinimumSizePercent" format="float" type="dimen">0.5</item>
+    <!-- Default percentages for the PIP size logic when the Display is close to square.
+         This is used instead when the display is square-ish, like fold-ables when unfolded,
+         to make sure that default PiP does not cover the hinge (halfway of the display).
+         0. Determine if the display is square-ish
+         If min(displayWidth, displayHeight) / max(displayWidth, displayHeight) is greater than
+         config_pipSquareDisplayThresholdForSystemPreferredSize, we use the percent for
+         square display listed below.
+         1. Determine max widths
+         Subtract width of system UI and default padding from the shortest edge of the device.
+         This is the max width.
+         2. Calculate Default and Mins
+         Default is config_pipSystemPreferredDefaultSizePercentForSquareDisplay of max-width/height.
+         Min is config_pipSystemPreferredMinimumSizePercentForSquareDisplay of it. -->
+    <item name="config_pipSquareDisplayThresholdForSystemPreferredSize"
+        format="float" type="dimen">0.95</item>
+    <item name="config_pipSystemPreferredDefaultSizePercentForSquareDisplay"
+        format="float" type="dimen">0.5</item>
+    <item name="config_pipSystemPreferredMinimumSizePercentForSquareDisplay"
+        format="float" type="dimen">0.4</item>
+
     <!-- The percentage of the screen width to use for the default width or height of
          picture-in-picture windows. Regardless of the percent set here, calculated size will never
-         be smaller than @dimen/default_minimal_size_pip_resizable_task. -->
+         be smaller than @dimen/default_minimal_size_pip_resizable_task.
+         This is used in legacy spec, use config_pipSystemPreferredDefaultSizePercent instead. -->
     <item name="config_pictureInPictureDefaultSizePercent" format="float" type="dimen">0.23</item>
 
+    <!-- PiP minimum size, which is a % based off the shorter side of display width and height.
+         This is used in legacy spec, use config_pipSystemPreferredMinimumSizePercent instead. -->
+    <fraction name="config_pipShortestEdgePercent">40%</fraction>
+
     <!-- The default aspect ratio for picture-in-picture windows. -->
     <item name="config_pictureInPictureDefaultAspectRatio" format="float" type="dimen">
         1.777778
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 70371f6..39dd4d3 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -456,16 +456,19 @@
     <dimen name="desktop_mode_customizable_caption_margin_end">152dp</dimen>
 
     <!-- The width of the maximize menu in desktop mode. -->
-    <dimen name="desktop_mode_maximize_menu_width">287dp</dimen>
+    <dimen name="desktop_mode_maximize_menu_width">228dp</dimen>
 
     <!-- The height of the maximize menu in desktop mode. -->
-    <dimen name="desktop_mode_maximize_menu_height">112dp</dimen>
+    <dimen name="desktop_mode_maximize_menu_height">114dp</dimen>
 
-    <!-- The larger of the two corner radii of the maximize menu buttons. -->
-    <dimen name="desktop_mode_maximize_menu_buttons_large_corner_radius">4dp</dimen>
+    <!-- The height of the buttons in the maximize menu. -->
+    <dimen name="desktop_mode_maximize_menu_button_height">52dp</dimen>
 
-    <!-- The smaller of the two corner radii of the maximize menu buttons. -->
-    <dimen name="desktop_mode_maximize_menu_buttons_small_corner_radius">2dp</dimen>
+    <!-- The radius of the maximize menu buttons. -->
+    <dimen name="desktop_mode_maximize_menu_buttons_radius">4dp</dimen>
+
+    <!-- The radius of the layout outline around the maximize menu buttons. -->
+    <dimen name="desktop_mode_maximize_menu_buttons_outline_radius">6dp</dimen>
 
     <!-- The corner radius of the maximize menu. -->
     <dimen name="desktop_mode_maximize_menu_corner_radius">8dp</dimen>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 812a81b..bf654d9 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -280,4 +280,8 @@
     <string name="collapse_menu_text">Close Menu</string>
     <!-- Accessibility text for the handle menu open menu button [CHAR LIMIT=NONE] -->
     <string name="expand_menu_text">Open Menu</string>
+    <!-- Maximize menu maximize button string. -->
+    <string name="desktop_mode_maximize_menu_maximize_text">Maximize Screen</string>
+    <!-- Maximize menu snap buttons string. -->
+    <string name="desktop_mode_maximize_menu_snap_text">Snap Screen</string>
 </resources>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index ad3be3d..97bf8f7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -173,6 +173,8 @@
                         ProtoLog.i(WM_SHELL_BACK_PREVIEW, "Navigation window gone.");
                         setTriggerBack(false);
                         resetTouchTracker();
+                        // Don't wait for animation start
+                        mShellExecutor.removeCallbacks(mAnimationTimeoutRunnable);
                     });
                 }
             });
@@ -686,7 +688,11 @@
         }
     }
 
-    private void dispatchOnBackCancelled(IOnBackInvokedCallback callback) {
+    private void tryDispatchOnBackCancelled(IOnBackInvokedCallback callback) {
+        if (!mOnBackStartDispatched) {
+            Log.e(TAG, "Skipping dispatching onBackCancelled. Start was never dispatched.");
+            return;
+        }
         if (callback == null) {
             return;
         }
@@ -745,7 +751,7 @@
             if (touchTracker.getTriggerBack()) {
                 dispatchOrAnimateOnBackInvoked(callback, touchTracker);
             } else {
-                dispatchOnBackCancelled(callback);
+                tryDispatchOnBackCancelled(callback);
             }
         }
         finishBackNavigation(touchTracker.getTriggerBack());
@@ -824,7 +830,7 @@
         if (mCurrentTracker.getTriggerBack()) {
             dispatchOrAnimateOnBackInvoked(mActiveCallback, mCurrentTracker);
         } else {
-            dispatchOnBackCancelled(mActiveCallback);
+            tryDispatchOnBackCancelled(mActiveCallback);
         }
     }
 
@@ -876,7 +882,7 @@
         if (mCurrentTracker.isInInitialState()) {
             if (mBackGestureStarted) {
                 mBackGestureStarted = false;
-                dispatchOnBackCancelled(mActiveCallback);
+                tryDispatchOnBackCancelled(mActiveCallback);
                 finishBackNavigation(false);
                 ProtoLog.d(WM_SHELL_BACK_PREVIEW,
                         "resetTouchTracker -> reset an unfinished gesture");
@@ -950,7 +956,7 @@
             ProtoLog.e(WM_SHELL_BACK_PREVIEW, "Lack of navigation info to start animation.");
             return;
         }
-        if (mApps == null) {
+        if (!validateAnimationTargets(mApps)) {
             ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Not starting animation due to mApps being null.");
             return;
         }
@@ -981,6 +987,21 @@
         }
     }
 
+    /**
+     * Validate animation targets.
+     */
+    static boolean validateAnimationTargets(RemoteAnimationTarget[] apps) {
+        if (apps == null || apps.length == 0) {
+            return false;
+        }
+        for (int i = apps.length - 1; i >= 0; --i) {
+            if (!apps[i].leash.isValid()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     private void createAdapter() {
         IBackAnimationRunner runner =
                 new IBackAnimationRunner.Stub() {
@@ -993,6 +1014,10 @@
                         mShellExecutor.execute(
                                 () -> {
                                     endLatencyTracking();
+                                    if (!validateAnimationTargets(apps)) {
+                                        Log.e(TAG, "Invalid animation targets!");
+                                        return;
+                                    }
                                     mBackAnimationFinishedCallback = finishedCallback;
                                     mApps = apps;
                                     startSystemAnimation();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
index 3253cac..c6d4620 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
@@ -25,6 +25,7 @@
 import android.graphics.Rect
 import android.graphics.RectF
 import android.os.RemoteException
+import android.view.Choreographer
 import android.view.Display
 import android.view.IRemoteAnimationFinishedCallback
 import android.view.IRemoteAnimationRunner
@@ -65,7 +66,7 @@
     private val targetEnteringRect = RectF()
     private val currentEnteringRect = RectF()
 
-    private val taskBoundsRect = Rect()
+    private val backAnimRect = Rect()
 
     private val cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
 
@@ -109,10 +110,10 @@
         transaction.setAnimationTransaction()
 
         // Offset start rectangle to align task bounds.
-        taskBoundsRect.set(closingTarget!!.windowConfiguration.bounds)
-        taskBoundsRect.offsetTo(0, 0)
+        backAnimRect.set(closingTarget!!.localBounds)
+        backAnimRect.offsetTo(0, 0)
 
-        startClosingRect.set(taskBoundsRect)
+        startClosingRect.set(backAnimRect)
 
         // scale closing target into the middle for rhs and to the right for lhs
         targetClosingRect.set(startClosingRect)
@@ -137,7 +138,7 @@
             enteringTarget!!.taskInfo.taskDescription!!.backgroundColor, transaction
         )
         ensureScrimLayer()
-        transaction.apply()
+        applyTransaction()
     }
 
     private fun onGestureProgress(backEvent: BackEvent) {
@@ -150,11 +151,11 @@
         currentEnteringRect.setInterpolatedRectF(startEnteringRect, targetEnteringRect, progress)
         currentEnteringRect.offset(0f, yOffset)
         applyTransform(enteringTarget?.leash, currentEnteringRect, 1f)
-        transaction.apply()
+        applyTransaction()
     }
 
     private fun getYOffset(centeredRect: RectF, touchY: Float): Float {
-        val screenHeight = taskBoundsRect.height()
+        val screenHeight = backAnimRect.height()
         // Base the window movement in the Y axis on the touch movement in the Y axis.
         val rawYDelta = touchY - initialTouchPos.y
         val yDirection = (if (rawYDelta < 0) -1 else 1)
@@ -181,8 +182,8 @@
         // off the animator
         startClosingRect.set(currentClosingRect)
         startEnteringRect.set(currentEnteringRect)
-        targetEnteringRect.set(taskBoundsRect)
-        targetClosingRect.set(taskBoundsRect)
+        targetEnteringRect.set(backAnimRect)
+        targetClosingRect.set(backAnimRect)
         targetClosingRect.offset(currentClosingRect.left + enteringStartOffset, 0f)
 
         val valueAnimator = ValueAnimator.ofFloat(1f, 0f).setDuration(POST_ANIMATION_DURATION)
@@ -210,7 +211,7 @@
         applyTransform(closingTarget?.leash, currentClosingRect, closingAlpha)
         currentEnteringRect.setInterpolatedRectF(startEnteringRect, targetEnteringRect, progress)
         applyTransform(enteringTarget?.leash, currentEnteringRect, 1f)
-        transaction.apply()
+        applyTransaction()
     }
 
     private fun finishAnimation() {
@@ -226,7 +227,7 @@
         closingTarget = null
 
         background.removeBackground(transaction)
-        transaction.apply()
+        applyTransaction()
         transformMatrix.reset()
         initialTouchPos.set(0f, 0f)
         try {
@@ -240,16 +241,21 @@
 
     private fun applyTransform(leash: SurfaceControl?, rect: RectF, alpha: Float) {
         if (leash == null || !leash.isValid) return
-        val scale = rect.width() / taskBoundsRect.width()
+        val scale = rect.width() / backAnimRect.width()
         transformMatrix.reset()
         transformMatrix.setScale(scale, scale)
         transformMatrix.postTranslate(rect.left, rect.top)
         transaction.setAlpha(leash, alpha)
             .setMatrix(leash, transformMatrix, tmpFloat9)
-            .setCrop(leash, taskBoundsRect)
+            .setCrop(leash, backAnimRect)
             .setCornerRadius(leash, cornerRadius)
     }
 
+    private fun applyTransaction() {
+        transaction.setFrameTimelineVsync(Choreographer.getInstance().vsyncId)
+        transaction.apply()
+    }
+
     private fun ensureScrimLayer() {
         if (scrimLayer != null) return
         val isDarkTheme: Boolean = isDarkMode(context)
@@ -267,6 +273,7 @@
         transaction
             .setColor(scrimLayer, colorComponents)
             .setAlpha(scrimLayer!!, maxScrimAlpha)
+            .setCrop(scrimLayer!!, closingTarget!!.localBounds)
             .setRelativeLayer(scrimLayer!!, closingTarget!!.leash, -1)
             .show(scrimLayer)
     }
@@ -274,7 +281,8 @@
     private fun removeScrimLayer() {
         scrimLayer?.let {
             if (it.isValid) {
-                transaction.remove(it).apply()
+                transaction.remove(it)
+                applyTransaction()
             }
         }
         scrimLayer = null
@@ -286,7 +294,7 @@
             // in case we're still animating an onBackCancelled event, let's remove the finish-
             // callback from the progress animator to prevent calling finishAnimation() before
             // restarting a new animation
-            progressAnimator.removeOnBackCancelledFinishCallback();
+            progressAnimator.removeOnBackCancelledFinishCallback()
 
             startBackAnimation(backMotionEvent)
             progressAnimator.onBackStarted(backMotionEvent) { backEvent: BackEvent ->
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
index cae2e80..987001d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
@@ -34,6 +34,7 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.os.RemoteException;
+import android.view.Choreographer;
 import android.view.IRemoteAnimationFinishedCallback;
 import android.view.IRemoteAnimationRunner;
 import android.view.RemoteAnimationTarget;
@@ -192,7 +193,7 @@
 
         applyTransform(mClosingTarget.leash, mClosingCurrentRect, mCornerRadius);
         applyTransform(mEnteringTarget.leash, mEnteringCurrentRect, mCornerRadius);
-        mTransaction.apply();
+        applyTransaction();
 
         mBackground.onBackProgressed(progress);
     }
@@ -242,6 +243,11 @@
                 .setCornerRadius(leash, cornerRadius);
     }
 
+    private void applyTransaction() {
+        mTransaction.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
+        mTransaction.apply();
+    }
+
     private void finishAnimation() {
         if (mEnteringTarget != null) {
             mEnteringTarget.leash.release();
@@ -255,8 +261,7 @@
         if (mBackground != null) {
             mBackground.removeBackground(mTransaction);
         }
-
-        mTransaction.apply();
+        applyTransaction();
         mBackInProgress = false;
         mTransformMatrix.reset();
         mClosingCurrentRect.setEmpty();
@@ -303,7 +308,7 @@
             if (progress > 1 - UPDATE_SYSUI_FLAGS_THRESHOLD) {
                 mBackground.resetStatusBarCustomization();
             }
-            mTransaction.apply();
+            applyTransaction();
         });
 
         valueAnimator.addListener(new AnimatorListenerAdapter() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index ce8a460..313d0d2 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -2329,6 +2329,17 @@
             mMainExecutor.execute(() ->
                     mController.showUserEducation(new Point(positionX, positionY)));
         }
+
+        @Override
+        public void setBubbleBarLocation(BubbleBarLocation location) {
+            mMainExecutor.execute(() ->
+                    mController.setBubbleBarLocation(location));
+        }
+
+        @Override
+        public void setBubbleBarBounds(Rect bubbleBarBounds) {
+            mMainExecutor.execute(() -> mBubblePositioner.setBubbleBarBounds(bubbleBarBounds));
+        }
     }
 
     private class BubblesImpl implements Bubbles {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
index 7a5afec..c9f0f0d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
@@ -19,6 +19,7 @@
 import android.content.Intent;
 import android.graphics.Rect;
 import com.android.wm.shell.bubbles.IBubblesListener;
+import com.android.wm.shell.common.bubbles.BubbleBarLocation;
 
 /**
  * Interface that is exposed to remote callers (launcher) to manipulate the bubbles feature when
@@ -42,4 +43,7 @@
 
     oneway void showUserEducation(in int positionX, in int positionY) = 8;
 
+    oneway void setBubbleBarLocation(in BubbleBarLocation location) = 9;
+
+    oneway void setBubbleBarBounds(in Rect bubbleBarBounds) = 10;
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
index 8af4c75..45ad631 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarAnimationHelper.java
@@ -166,13 +166,8 @@
         bbev.setTaskViewAlpha(0f);
         bbev.setVisibility(VISIBLE);
 
-        // Set the pivot point for the scale, so the view animates out from the bubble bar.
-        Rect bubbleBarBounds = mPositioner.getBubbleBarBounds();
-        mExpandedViewContainerMatrix.setScale(
-                1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT,
-                1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT,
-                bubbleBarBounds.centerX(),
-                bubbleBarBounds.top);
+        setScaleFromBubbleBar(mExpandedViewContainerMatrix,
+                1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT);
 
         bbev.setAnimationMatrix(mExpandedViewContainerMatrix);
 
@@ -214,8 +209,8 @@
         }
         bbev.setScaleX(1f);
         bbev.setScaleY(1f);
-        mExpandedViewContainerMatrix.setScaleX(1f);
-        mExpandedViewContainerMatrix.setScaleY(1f);
+
+        setScaleFromBubbleBar(mExpandedViewContainerMatrix, 1f);
 
         PhysicsAnimator.getInstance(mExpandedViewContainerMatrix).cancel();
         PhysicsAnimator.getInstance(mExpandedViewContainerMatrix)
@@ -240,6 +235,16 @@
         mExpandedViewAlphaAnimator.reverse();
     }
 
+    private void setScaleFromBubbleBar(AnimatableScaleMatrix matrix, float scale) {
+        // Set the pivot point for the scale, so the view animates out from the bubble bar.
+        Rect bubbleBarBounds = mPositioner.getBubbleBarBounds();
+        matrix.setScale(
+                scale,
+                scale,
+                bubbleBarBounds.centerX(),
+                bubbleBarBounds.top);
+    }
+
     /**
      * Animate the expanded bubble when it is being dragged
      */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarDropTargetController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarDropTargetController.kt
deleted file mode 100644
index f6b4653..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarDropTargetController.kt
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.wm.shell.bubbles.bar
-
-import android.content.Context
-import android.graphics.Rect
-import android.view.LayoutInflater
-import android.view.View
-import android.widget.FrameLayout
-import android.widget.FrameLayout.LayoutParams
-import androidx.annotation.VisibleForTesting
-import androidx.core.animation.Animator
-import androidx.core.animation.AnimatorListenerAdapter
-import androidx.core.animation.ObjectAnimator
-import com.android.wm.shell.R
-import com.android.wm.shell.bubbles.BubblePositioner
-import com.android.wm.shell.common.bubbles.BubbleBarLocation
-
-/** Controller to show/hide drop target when bubble bar expanded view is being dragged */
-class BubbleBarDropTargetController(
-    val context: Context,
-    val container: FrameLayout,
-    val positioner: BubblePositioner
-) {
-
-    private var dropTargetView: View? = null
-    private var animator: ObjectAnimator? = null
-    private val tempRect: Rect by lazy(LazyThreadSafetyMode.NONE) { Rect() }
-
-    /**
-     * Show drop target at [location] with animation.
-     *
-     * If the drop target is currently visible, animates it out first, before showing it at the
-     * supplied location.
-     */
-    fun show(location: BubbleBarLocation) {
-        val targetView = dropTargetView ?: createView().also { dropTargetView = it }
-        if (targetView.alpha > 0) {
-            targetView.animateOut {
-                targetView.updateBounds(location)
-                targetView.animateIn()
-            }
-        } else {
-            targetView.updateBounds(location)
-            targetView.animateIn()
-        }
-    }
-
-    /**
-     * Set the view hidden or not
-     *
-     * Requires the drop target to be first shown by calling [animateIn]. Otherwise does not do
-     * anything.
-     */
-    fun setHidden(hidden: Boolean) {
-        val targetView = dropTargetView ?: return
-        if (hidden) {
-            targetView.animateOut()
-        } else {
-            targetView.animateIn()
-        }
-    }
-
-    /** Remove the drop target if it is was shown. */
-    fun dismiss() {
-        dropTargetView?.animateOut {
-            dropTargetView?.let { container.removeView(it) }
-            dropTargetView = null
-        }
-    }
-
-    private fun createView(): View {
-        return LayoutInflater.from(context)
-            .inflate(R.layout.bubble_bar_drop_target, container, false /* attachToRoot */)
-            .also { view: View ->
-                view.alpha = 0f
-                // Add at index 0 to ensure it does not cover the bubble
-                container.addView(view, 0)
-            }
-    }
-
-    private fun getBounds(onLeft: Boolean, out: Rect) {
-        positioner.getBubbleBarExpandedViewBounds(onLeft, false /* isOverflowExpanded */, out)
-        val centerX = out.centerX()
-        val centerY = out.centerY()
-        out.scale(DROP_TARGET_SCALE)
-        // Move rect center back to the same position as before scale
-        out.offset(centerX - out.centerX(), centerY - out.centerY())
-    }
-
-    private fun View.updateBounds(location: BubbleBarLocation) {
-        getBounds(location.isOnLeft(isLayoutRtl), tempRect)
-        val lp = layoutParams as LayoutParams
-        lp.width = tempRect.width()
-        lp.height = tempRect.height()
-        layoutParams = lp
-        x = tempRect.left.toFloat()
-        y = tempRect.top.toFloat()
-    }
-
-    private fun View.animateIn() {
-        animator?.cancel()
-        animator =
-            ObjectAnimator.ofFloat(this, View.ALPHA, 1f)
-                .setDuration(DROP_TARGET_ALPHA_IN_DURATION)
-                .addEndAction { animator = null }
-        animator?.start()
-    }
-
-    private fun View.animateOut(endAction: Runnable? = null) {
-        animator?.cancel()
-        animator =
-            ObjectAnimator.ofFloat(this, View.ALPHA, 0f)
-                .setDuration(DROP_TARGET_ALPHA_OUT_DURATION)
-                .addEndAction {
-                    endAction?.run()
-                    animator = null
-                }
-        animator?.start()
-    }
-
-    private fun <T : Animator> T.addEndAction(runnable: Runnable): T {
-        addListener(
-            object : AnimatorListenerAdapter() {
-                override fun onAnimationEnd(animation: Animator) {
-                    runnable.run()
-                }
-            }
-        )
-        return this
-    }
-
-    companion object {
-        @VisibleForTesting const val DROP_TARGET_ALPHA_IN_DURATION = 150L
-        @VisibleForTesting const val DROP_TARGET_ALPHA_OUT_DURATION = 100L
-        @VisibleForTesting const val DROP_TARGET_SCALE = 0.9f
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
index ad97a24..fe9c4d4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
@@ -17,12 +17,9 @@
 package com.android.wm.shell.bubbles.bar
 
 import android.annotation.SuppressLint
-import android.graphics.RectF
 import android.view.MotionEvent
 import android.view.View
-import com.android.wm.shell.R
 import com.android.wm.shell.bubbles.BubblePositioner
-import com.android.wm.shell.common.bubbles.BubbleBarLocation
 import com.android.wm.shell.common.bubbles.DismissView
 import com.android.wm.shell.common.bubbles.RelativeTouchListener
 import com.android.wm.shell.common.magnetictarget.MagnetizedObject
@@ -34,6 +31,7 @@
     private val dismissView: DismissView,
     private val animationHelper: BubbleBarAnimationHelper,
     private val bubblePositioner: BubblePositioner,
+    private val pinController: BubbleExpandedViewPinController,
     private val dragListener: DragListener
 ) {
 
@@ -45,8 +43,6 @@
     private val magnetizedExpandedView: MagnetizedObject<BubbleBarExpandedView> =
         MagnetizedObject.magnetizeView(expandedView)
     private val magnetizedDismissTarget: MagnetizedObject.MagneticTarget
-    private val dismissZoneHeight: Int
-    private val dismissZoneWidth: Int
 
     init {
         magnetizedExpandedView.magnetListener = MagnetListener()
@@ -78,33 +74,11 @@
             }
             return@setOnTouchListener dragMotionEventHandler.onTouch(view, event) || magnetConsumed
         }
-
-        dismissZoneHeight =
-            dismissView.resources.getDimensionPixelSize(R.dimen.bubble_bar_dismiss_zone_height)
-        dismissZoneWidth =
-            dismissView.resources.getDimensionPixelSize(R.dimen.bubble_bar_dismiss_zone_width)
     }
 
-    /** Listener to receive callback about dragging events */
+    /** Listener to get notified about drag events */
     interface DragListener {
         /**
-         * Bubble bar [BubbleBarLocation] has changed as a result of dragging the expanded view.
-         *
-         * Triggered when drag gesture passes the middle of the screen and before touch up. Can be
-         * triggered multiple times per gesture.
-         *
-         * @param location new location of the bubble bar as a result of the ongoing drag operation
-         */
-        fun onLocationChanged(location: BubbleBarLocation)
-
-        /**
-         * Called when bubble bar is moved into or out of the dismiss target
-         *
-         * @param isStuck `true` if view is dragged inside dismiss target
-         */
-        fun onStuckToDismissChanged(isStuck: Boolean)
-
-        /**
          * Bubble bar was released
          *
          * @param inDismiss `true` if view was release in dismiss target
@@ -115,25 +89,11 @@
     private inner class HandleDragListener : RelativeTouchListener() {
 
         private var isMoving = false
-        private var screenCenterX: Int = -1
-        private var isOnLeft = false
-        private val dismissZone = RectF()
 
         override fun onDown(v: View, ev: MotionEvent): Boolean {
             // While animating, don't allow new touch events
             if (expandedView.isAnimating) return false
-            isOnLeft = bubblePositioner.isBubbleBarOnLeft
-
-            val screenRect = bubblePositioner.screenRect
-            screenCenterX = screenRect.centerX()
-            val screenBottom = screenRect.bottom
-
-            dismissZone.set(
-                screenCenterX - dismissZoneWidth / 2f,
-                (screenBottom - dismissZoneHeight).toFloat(),
-                screenCenterX + dismissZoneHeight / 2f,
-                screenBottom.toFloat()
-            )
+            pinController.onDragStart(bubblePositioner.isBubbleBarOnLeft)
             return true
         }
 
@@ -152,19 +112,7 @@
             expandedView.translationX = expandedViewInitialTranslationX + dx
             expandedView.translationY = expandedViewInitialTranslationY + dy
             dismissView.show()
-
-            // Check if we are in the zone around dismiss view where drag can only lead to dismiss
-            if (dismissZone.contains(ev.rawX, ev.rawY)) {
-                return
-            }
-
-            if (isOnLeft && ev.rawX > screenCenterX) {
-                isOnLeft = false
-                dragListener.onLocationChanged(BubbleBarLocation.RIGHT)
-            } else if (!isOnLeft && ev.rawX < screenCenterX) {
-                isOnLeft = true
-                dragListener.onLocationChanged(BubbleBarLocation.LEFT)
-            }
+            pinController.onDragUpdate(ev.rawX, ev.rawY)
         }
 
         override fun onUp(
@@ -188,6 +136,7 @@
         private fun finishDrag() {
             if (!isStuckToDismiss) {
                 animationHelper.animateToRestPosition()
+                pinController.onDragEnd()
                 dragListener.onReleased(inDismiss = false)
                 dismissView.hide()
             }
@@ -201,7 +150,7 @@
             draggedObject: MagnetizedObject<*>
         ) {
             isStuckToDismiss = true
-            dragListener.onStuckToDismissChanged(isStuck = true)
+            pinController.setDropTargetHidden(true)
         }
 
         override fun onUnstuckFromTarget(
@@ -213,7 +162,7 @@
         ) {
             isStuckToDismiss = false
             animationHelper.animateUnstuckFromDismissView(target)
-            dragListener.onStuckToDismissChanged(isStuck = false)
+            pinController.setDropTargetHidden(false)
         }
 
         override fun onReleasedInTarget(
@@ -221,6 +170,7 @@
             draggedObject: MagnetizedObject<*>
         ) {
             dragListener.onReleased(inDismiss = true)
+            pinController.onDragEnd()
             dismissView.hide()
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
index 88ccc92..62cc4da 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
@@ -33,8 +33,6 @@
 import android.view.WindowManager;
 import android.widget.FrameLayout;
 
-import androidx.annotation.NonNull;
-
 import com.android.wm.shell.bubbles.Bubble;
 import com.android.wm.shell.bubbles.BubbleController;
 import com.android.wm.shell.bubbles.BubbleData;
@@ -44,7 +42,6 @@
 import com.android.wm.shell.bubbles.DeviceConfig;
 import com.android.wm.shell.bubbles.DismissViewUtils;
 import com.android.wm.shell.bubbles.bar.BubbleBarExpandedViewDragController.DragListener;
-import com.android.wm.shell.common.bubbles.BubbleBarLocation;
 import com.android.wm.shell.common.bubbles.DismissView;
 
 import kotlin.Unit;
@@ -71,7 +68,7 @@
     private final BubbleBarAnimationHelper mAnimationHelper;
     private final BubbleEducationViewController mEducationViewController;
     private final View mScrimView;
-    private final BubbleBarDropTargetController mDropTargetController;
+    private final BubbleExpandedViewPinController mBubbleExpandedViewPinController;
 
     @Nullable
     private BubbleViewProvider mExpandedBubble;
@@ -116,7 +113,9 @@
 
         setUpDismissView();
 
-        mDropTargetController = new BubbleBarDropTargetController(context, this, mPositioner);
+        mBubbleExpandedViewPinController = new BubbleExpandedViewPinController(
+                context, this, mPositioner);
+        mBubbleExpandedViewPinController.setListener(mBubbleController::setBubbleBarLocation);
 
         setOnClickListener(view -> hideMenuOrCollapse());
     }
@@ -207,12 +206,17 @@
                 }
             });
 
-            DragListener dragListener = createDragListener();
+            DragListener dragListener = inDismiss -> {
+                if (inDismiss && mExpandedBubble != null) {
+                    mBubbleController.dismissBubble(mExpandedBubble.getKey(), DISMISS_USER_GESTURE);
+                }
+            };
             mDragController = new BubbleBarExpandedViewDragController(
                     mExpandedView,
                     mDismissView,
                     mAnimationHelper,
                     mPositioner,
+                    mBubbleExpandedViewPinController,
                     dragListener);
 
             addView(mExpandedView, new LayoutParams(width, height, Gravity.LEFT));
@@ -377,26 +381,4 @@
         }
     }
 
-    private DragListener createDragListener() {
-        return new DragListener() {
-            @Override
-            public void onLocationChanged(@NonNull BubbleBarLocation location) {
-                mBubbleController.setBubbleBarLocation(location);
-                mDropTargetController.show(location);
-            }
-
-            @Override
-            public void onStuckToDismissChanged(boolean isStuck) {
-                mDropTargetController.setHidden(isStuck);
-            }
-
-            @Override
-            public void onReleased(boolean inDismiss) {
-                mDropTargetController.dismiss();
-                if (inDismiss && mExpandedBubble != null) {
-                    mBubbleController.dismissBubble(mExpandedBubble.getKey(), DISMISS_USER_GESTURE);
-                }
-            }
-        };
-    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinController.kt
new file mode 100644
index 0000000..5d391ec
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleExpandedViewPinController.kt
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.bubbles.bar
+
+import android.content.Context
+import android.graphics.Rect
+import android.graphics.RectF
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.FrameLayout
+import androidx.annotation.VisibleForTesting
+import androidx.core.view.updateLayoutParams
+import com.android.wm.shell.R
+import com.android.wm.shell.bubbles.BubblePositioner
+import com.android.wm.shell.common.bubbles.BaseBubblePinController
+import com.android.wm.shell.common.bubbles.BubbleBarLocation
+
+/**
+ * Controller to manage pinning bubble bar to left or right when dragging starts from the bubble bar
+ * expanded view
+ */
+class BubbleExpandedViewPinController(
+    private val context: Context,
+    private val container: FrameLayout,
+    private val positioner: BubblePositioner
+) : BaseBubblePinController() {
+
+    private var dropTargetView: View? = null
+    private val tempRect: Rect by lazy(LazyThreadSafetyMode.NONE) { Rect() }
+
+    override fun getScreenCenterX(): Int {
+        return positioner.screenRect.centerX()
+    }
+
+    override fun getExclusionRect(): RectF {
+        val rect =
+            RectF(
+                0f,
+                0f,
+                context.resources.getDimension(R.dimen.bubble_bar_dismiss_zone_width),
+                context.resources.getDimension(R.dimen.bubble_bar_dismiss_zone_height)
+            )
+
+        val screenRect = positioner.screenRect
+        // Center it around the bottom center of the screen
+        rect.offsetTo(
+            screenRect.exactCenterX() - rect.width() / 2f,
+            screenRect.bottom - rect.height()
+        )
+        return rect
+    }
+
+    override fun createDropTargetView(): View {
+        return LayoutInflater.from(context)
+            .inflate(R.layout.bubble_bar_drop_target, container, false /* attachToRoot */)
+            .also { view: View ->
+                dropTargetView = view
+                // Add at index 0 to ensure it does not cover the bubble
+                container.addView(view, 0)
+            }
+    }
+
+    override fun getDropTargetView(): View? {
+        return dropTargetView
+    }
+
+    override fun removeDropTargetView(view: View) {
+        container.removeView(view)
+        dropTargetView = null
+    }
+
+    override fun updateLocation(location: BubbleBarLocation) {
+        val view = dropTargetView ?: return
+        getBounds(location.isOnLeft(view.isLayoutRtl), tempRect)
+        view.updateLayoutParams<FrameLayout.LayoutParams> {
+            width = tempRect.width()
+            height = tempRect.height()
+        }
+        view.x = tempRect.left.toFloat()
+        view.y = tempRect.top.toFloat()
+    }
+
+    private fun getBounds(onLeft: Boolean, out: Rect) {
+        positioner.getBubbleBarExpandedViewBounds(onLeft, false /* isOverflowExpanded */, out)
+        val centerX = out.centerX()
+        val centerY = out.centerY()
+        out.scale(DROP_TARGET_SCALE)
+        // Move rect center back to the same position as before scale
+        out.offset(centerX - out.centerX(), centerY - out.centerY())
+    }
+
+    companion object {
+        @VisibleForTesting const val DROP_TARGET_SCALE = 0.9f
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BaseBubblePinController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BaseBubblePinController.kt
new file mode 100644
index 0000000..630ad6e
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BaseBubblePinController.kt
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.common.bubbles
+
+import android.graphics.RectF
+import android.view.View
+import androidx.annotation.VisibleForTesting
+import androidx.core.animation.Animator
+import androidx.core.animation.AnimatorListenerAdapter
+import androidx.core.animation.ObjectAnimator
+import com.android.wm.shell.common.bubbles.BaseBubblePinController.LocationChangeListener
+import com.android.wm.shell.common.bubbles.BubbleBarLocation.LEFT
+import com.android.wm.shell.common.bubbles.BubbleBarLocation.RIGHT
+
+/**
+ * Base class for common logic shared between different bubble views to support pinning bubble bar
+ * to left or right edge of screen.
+ *
+ * Handles drag events and allows a [LocationChangeListener] to be registered that is notified when
+ * location of the bubble bar should change.
+ *
+ * Shows a drop target when releasing a view would update the [BubbleBarLocation].
+ */
+abstract class BaseBubblePinController {
+
+    private var onLeft = false
+    private var dismissZone: RectF? = null
+    private var screenCenterX = 0
+    private var listener: LocationChangeListener? = null
+    private var dropTargetAnimator: ObjectAnimator? = null
+
+    /**
+     * Signal the controller that dragging interaction has started.
+     *
+     * @param initialLocationOnLeft side of the screen where bubble bar is pinned to
+     */
+    fun onDragStart(initialLocationOnLeft: Boolean) {
+        onLeft = initialLocationOnLeft
+        dismissZone = getExclusionRect()
+        screenCenterX = getScreenCenterX()
+    }
+
+    /** View has moved to [x] and [y] screen coordinates */
+    fun onDragUpdate(x: Float, y: Float) {
+        if (dismissZone?.contains(x, y) == true) return
+
+        if (onLeft && x > screenCenterX) {
+            onLeft = false
+            onLocationChange(RIGHT)
+        } else if (!onLeft && x < screenCenterX) {
+            onLeft = true
+            onLocationChange(LEFT)
+        }
+    }
+
+    /** Temporarily hide the drop target view */
+    fun setDropTargetHidden(hidden: Boolean) {
+        val targetView = getDropTargetView() ?: return
+        if (hidden) {
+            targetView.animateOut()
+        } else {
+            targetView.animateIn()
+        }
+    }
+
+    /** Signal the controller that dragging interaction has finished. */
+    fun onDragEnd() {
+        getDropTargetView()?.let { view -> view.animateOut { removeDropTargetView(view) } }
+        dismissZone = null
+    }
+
+    /**
+     * [LocationChangeListener] that is notified when dragging interaction has resulted in bubble
+     * bar to be pinned on the other edge
+     */
+    fun setListener(listener: LocationChangeListener?) {
+        this.listener = listener
+    }
+
+    /** Get screen center coordinate on the x axis. */
+    protected abstract fun getScreenCenterX(): Int
+
+    /** Optional exclusion rect where drag interactions are not processed */
+    protected abstract fun getExclusionRect(): RectF?
+
+    /** Create the drop target view and attach it to the parent */
+    protected abstract fun createDropTargetView(): View
+
+    /** Get the drop target view if it exists */
+    protected abstract fun getDropTargetView(): View?
+
+    /** Remove the drop target view */
+    protected abstract fun removeDropTargetView(view: View)
+
+    /** Update size and location of the drop target view */
+    protected abstract fun updateLocation(location: BubbleBarLocation)
+
+    private fun onLocationChange(location: BubbleBarLocation) {
+        showDropTarget(location)
+        listener?.onChange(location)
+    }
+
+    private fun showDropTarget(location: BubbleBarLocation) {
+        val targetView = getDropTargetView() ?: createDropTargetView().apply { alpha = 0f }
+        if (targetView.alpha > 0) {
+            targetView.animateOut {
+                updateLocation(location)
+                targetView.animateIn()
+            }
+        } else {
+            updateLocation(location)
+            targetView.animateIn()
+        }
+    }
+
+    private fun View.animateIn() {
+        dropTargetAnimator?.cancel()
+        dropTargetAnimator =
+            ObjectAnimator.ofFloat(this, View.ALPHA, 1f)
+                .setDuration(DROP_TARGET_ALPHA_IN_DURATION)
+                .addEndAction { dropTargetAnimator = null }
+        dropTargetAnimator?.start()
+    }
+
+    private fun View.animateOut(endAction: Runnable? = null) {
+        dropTargetAnimator?.cancel()
+        dropTargetAnimator =
+            ObjectAnimator.ofFloat(this, View.ALPHA, 0f)
+                .setDuration(DROP_TARGET_ALPHA_OUT_DURATION)
+                .addEndAction {
+                    endAction?.run()
+                    dropTargetAnimator = null
+                }
+        dropTargetAnimator?.start()
+    }
+
+    private fun <T : Animator> T.addEndAction(runnable: Runnable): T {
+        addListener(
+            object : AnimatorListenerAdapter() {
+                override fun onAnimationEnd(animation: Animator) {
+                    runnable.run()
+                }
+            }
+        )
+        return this
+    }
+
+    /** Receive updates on location changes */
+    interface LocationChangeListener {
+        /**
+         * Bubble bar [BubbleBarLocation] has changed as a result of dragging
+         *
+         * Triggered when drag gesture passes the middle of the screen and before touch up. Can be
+         * triggered multiple times per gesture.
+         *
+         * @param location new location as a result of the ongoing drag operation
+         */
+        fun onChange(location: BubbleBarLocation)
+    }
+
+    companion object {
+        @VisibleForTesting const val DROP_TARGET_ALPHA_IN_DURATION = 150L
+        @VisibleForTesting const val DROP_TARGET_ALPHA_OUT_DURATION = 100L
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarLocation.aidl
similarity index 73%
copy from packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
copy to libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarLocation.aidl
index 0c92b50..3c5beeb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/bubbles/BubbleBarLocation.aidl
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.notification.stack.shared.model
+package com.android.wm.shell.common.bubbles;
 
-/** Models the clipping rounded rectangle of the notification stack */
-data class StackClipping(val bounds: StackBounds, val rounding: StackRounding)
+parcelable BubbleBarLocation;
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PhoneSizeSpecSource.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PhoneSizeSpecSource.kt
index 18c7bdd..7eb0f26 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PhoneSizeSpecSource.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PhoneSizeSpecSource.kt
@@ -18,7 +18,6 @@
 
 import android.content.Context
 import android.content.res.Resources
-import android.os.SystemProperties
 import android.util.Size
 import com.android.wm.shell.R
 import java.io.PrintWriter
@@ -36,30 +35,81 @@
     private var mOverrideMinSize: Size? = null
 
 
-    /** Default and minimum percentages for the PIP size logic.  */
-    private val mDefaultSizePercent: Float
-    private val mMinimumSizePercent: Float
+    /**
+     * Default percentages for the PIP size logic.
+     * 1. Determine max widths
+     * Subtract width of system UI and default padding from the shortest edge of the device.
+     * This is the max width.
+     * 2. Calculate Default and Mins
+     * Default is mSystemPreferredDefaultSizePercent of max-width/height.
+     * Min is mSystemPreferredMinimumSizePercent of it.
+     *
+     * NOTE: Do not use this directly, use the mPreferredDefaultSizePercent getter instead.
+     */
+    private var mSystemPreferredDefaultSizePercent = 0.6f
+    /** Minimum percentages for the PIP size logic. */
+    private var mSystemPreferredMinimumSizePercent = 0.5f
+
+    /** Threshold to categorize the Display as square, calculated as min(w, h) / max(w, h). */
+    private var mSquareDisplayThresholdForSystemPreferredSize = 0.95f
+    /**
+     * Default percentages for the PIP size logic when the Display is square-ish.
+     * This is used instead when the display is square-ish, like fold-ables when unfolded,
+     * to make sure that default PiP does not cover the hinge (halfway of the display).
+     * 1. Determine max widths
+     * Subtract width of system UI and default padding from the shortest edge of the device.
+     * This is the max width.
+     * 2. Calculate Default and Mins
+     * Default is mSystemPreferredDefaultSizePercent of max-width/height.
+     * Min is mSystemPreferredMinimumSizePercent of it.
+     *
+     * NOTE: Do not use this directly, use the mPreferredDefaultSizePercent getter instead.
+     */
+    private var mSystemPreferredDefaultSizePercentForSquareDisplay = 0.5f
+    /** Minimum percentages for the PIP size logic. */
+    private var mSystemPreferredMinimumSizePercentForSquareDisplay = 0.4f
+
+    private val mIsSquareDisplay
+        get() = minOf(pipDisplayLayoutState.displayLayout.width(),
+                        pipDisplayLayoutState.displayLayout.height()).toFloat() /
+                maxOf(pipDisplayLayoutState.displayLayout.width(),
+                        pipDisplayLayoutState.displayLayout.height()) >
+                mSquareDisplayThresholdForSystemPreferredSize
+    private val mPreferredDefaultSizePercent
+        get() = if (mIsSquareDisplay) mSystemPreferredDefaultSizePercentForSquareDisplay else
+            mSystemPreferredDefaultSizePercent
+
+    private val mPreferredMinimumSizePercent
+        get() = if (mIsSquareDisplay) mSystemPreferredMinimumSizePercentForSquareDisplay else
+            mSystemPreferredMinimumSizePercent
 
     /** Aspect ratio that the PIP size spec logic optimizes for.  */
     private var mOptimizedAspectRatio = 0f
 
     init {
-        mDefaultSizePercent = SystemProperties
-                .get("com.android.wm.shell.pip.phone.def_percentage", "0.6").toFloat()
-        mMinimumSizePercent = SystemProperties
-                .get("com.android.wm.shell.pip.phone.min_percentage", "0.5").toFloat()
-
         reloadResources()
     }
 
     private fun reloadResources() {
-        val res: Resources = context.getResources()
+        val res: Resources = context.resources
 
         mDefaultMinSize = res.getDimensionPixelSize(
                 R.dimen.default_minimal_size_pip_resizable_task)
         mOverridableMinSize = res.getDimensionPixelSize(
                 R.dimen.overridable_minimal_size_pip_resizable_task)
 
+        mSystemPreferredDefaultSizePercent = res.getFloat(
+                R.dimen.config_pipSystemPreferredDefaultSizePercent)
+        mSystemPreferredMinimumSizePercent = res.getFloat(
+                R.dimen.config_pipSystemPreferredMinimumSizePercent)
+
+        mSquareDisplayThresholdForSystemPreferredSize = res.getFloat(
+                R.dimen.config_pipSquareDisplayThresholdForSystemPreferredSize)
+        mSystemPreferredDefaultSizePercentForSquareDisplay = res.getFloat(
+                R.dimen.config_pipSystemPreferredDefaultSizePercentForSquareDisplay)
+        mSystemPreferredMinimumSizePercentForSquareDisplay = res.getFloat(
+                R.dimen.config_pipSystemPreferredMinimumSizePercentForSquareDisplay)
+
         val requestedOptAspRatio = res.getFloat(R.dimen.config_pipLargeScreenOptimizedAspectRatio)
         // make sure the optimized aspect ratio is valid with a default value to fall back to
         mOptimizedAspectRatio = if (requestedOptAspRatio > 1) {
@@ -128,7 +178,7 @@
             return minSize
         }
         val maxSize = getMaxSize(aspectRatio)
-        val defaultWidth = Math.max(Math.round(maxSize.width * mDefaultSizePercent),
+        val defaultWidth = Math.max(Math.round(maxSize.width * mPreferredDefaultSizePercent),
                 minSize.width)
         val defaultHeight = Math.round(defaultWidth / aspectRatio)
         return Size(defaultWidth, defaultHeight)
@@ -146,8 +196,8 @@
             return adjustOverrideMinSizeToAspectRatio(aspectRatio)!!
         }
         val maxSize = getMaxSize(aspectRatio)
-        var minWidth = Math.round(maxSize.width * mMinimumSizePercent)
-        var minHeight = Math.round(maxSize.height * mMinimumSizePercent)
+        var minWidth = Math.round(maxSize.width * mPreferredMinimumSizePercent)
+        var minHeight = Math.round(maxSize.height * mPreferredMinimumSizePercent)
 
         // make sure the calculated min size is not smaller than the allowed default min size
         if (aspectRatio > 1f) {
@@ -244,8 +294,8 @@
         pw.println(innerPrefix + "mOverrideMinSize=" + mOverrideMinSize)
         pw.println(innerPrefix + "mOverridableMinSize=" + mOverridableMinSize)
         pw.println(innerPrefix + "mDefaultMinSize=" + mDefaultMinSize)
-        pw.println(innerPrefix + "mDefaultSizePercent=" + mDefaultSizePercent)
-        pw.println(innerPrefix + "mMinimumSizePercent=" + mMinimumSizePercent)
+        pw.println(innerPrefix + "mDefaultSizePercent=" + mPreferredDefaultSizePercent)
+        pw.println(innerPrefix + "mMinimumSizePercent=" + mPreferredMinimumSizePercent)
         pw.println(innerPrefix + "mOptimizedAspectRatio=" + mOptimizedAspectRatio)
     }
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
index ae07812..4eff3f0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/pip/Pip2Module.java
@@ -23,19 +23,25 @@
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.DisplayController;
 import com.android.wm.shell.common.DisplayInsetsController;
+import com.android.wm.shell.common.FloatingContentCoordinator;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SystemWindows;
 import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
 import com.android.wm.shell.common.pip.PipBoundsState;
 import com.android.wm.shell.common.pip.PipDisplayLayoutState;
 import com.android.wm.shell.common.pip.PipMediaController;
+import com.android.wm.shell.common.pip.PipPerfHintController;
+import com.android.wm.shell.common.pip.PipSnapAlgorithm;
 import com.android.wm.shell.common.pip.PipUiEventLogger;
 import com.android.wm.shell.common.pip.PipUtils;
+import com.android.wm.shell.common.pip.SizeSpecSource;
 import com.android.wm.shell.dagger.WMShellBaseModule;
 import com.android.wm.shell.dagger.WMSingleton;
 import com.android.wm.shell.pip2.phone.PhonePipMenuController;
 import com.android.wm.shell.pip2.phone.PipController;
+import com.android.wm.shell.pip2.phone.PipMotionHelper;
 import com.android.wm.shell.pip2.phone.PipScheduler;
+import com.android.wm.shell.pip2.phone.PipTouchHandler;
 import com.android.wm.shell.pip2.phone.PipTransition;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
 import com.android.wm.shell.sysui.ShellController;
@@ -62,6 +68,7 @@
             PipBoundsState pipBoundsState,
             PipBoundsAlgorithm pipBoundsAlgorithm,
             Optional<PipController> pipController,
+            PipTouchHandler pipTouchHandler,
             @NonNull PipScheduler pipScheduler) {
         return new PipTransition(context, shellInit, shellTaskOrganizer, transitions,
                 pipBoundsState, null, pipBoundsAlgorithm, pipScheduler);
@@ -93,8 +100,9 @@
     @Provides
     static PipScheduler providePipScheduler(Context context,
             PipBoundsState pipBoundsState,
-            @ShellMainThread ShellExecutor mainExecutor) {
-        return new PipScheduler(context, pipBoundsState, mainExecutor);
+            @ShellMainThread ShellExecutor mainExecutor,
+            ShellTaskOrganizer shellTaskOrganizer) {
+        return new PipScheduler(context, pipBoundsState, mainExecutor, shellTaskOrganizer);
     }
 
     @WMSingleton
@@ -108,4 +116,34 @@
         return new PhonePipMenuController(context, pipBoundsState, pipMediaController,
                 systemWindows, pipUiEventLogger, mainExecutor, mainHandler);
     }
+
+
+    @WMSingleton
+    @Provides
+    static PipTouchHandler providePipTouchHandler(Context context,
+            ShellInit shellInit,
+            PhonePipMenuController menuPhoneController,
+            PipBoundsAlgorithm pipBoundsAlgorithm,
+            @NonNull PipBoundsState pipBoundsState,
+            @NonNull SizeSpecSource sizeSpecSource,
+            PipMotionHelper pipMotionHelper,
+            FloatingContentCoordinator floatingContentCoordinator,
+            PipUiEventLogger pipUiEventLogger,
+            @ShellMainThread ShellExecutor mainExecutor,
+            Optional<PipPerfHintController> pipPerfHintControllerOptional) {
+        return new PipTouchHandler(context, shellInit, menuPhoneController, pipBoundsAlgorithm,
+                pipBoundsState, sizeSpecSource, pipMotionHelper, floatingContentCoordinator,
+                pipUiEventLogger, mainExecutor, pipPerfHintControllerOptional);
+    }
+
+    @WMSingleton
+    @Provides
+    static PipMotionHelper providePipMotionHelper(Context context,
+            PipBoundsState pipBoundsState, PhonePipMenuController menuController,
+            PipSnapAlgorithm pipSnapAlgorithm,
+            FloatingContentCoordinator floatingContentCoordinator,
+            Optional<PipPerfHintController> pipPerfHintControllerOptional) {
+        return new PipMotionHelper(context, pipBoundsState, menuController, pipSnapAlgorithm,
+                floatingContentCoordinator, pipPerfHintControllerOptional);
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
index 7c8fcbb..120d681 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepository.kt
@@ -16,10 +16,12 @@
 
 package com.android.wm.shell.desktopmode
 
+import android.graphics.Rect
 import android.graphics.Region
 import android.util.ArrayMap
 import android.util.ArraySet
 import android.util.SparseArray
+import android.view.Display.INVALID_DISPLAY
 import androidx.core.util.forEach
 import androidx.core.util.keyIterator
 import androidx.core.util.valueIterator
@@ -54,6 +56,8 @@
     private val visibleTasksListeners = ArrayMap<VisibleTasksListener, Executor>()
     // Track corner/caption regions of desktop tasks, used to determine gesture exclusion
     private val desktopExclusionRegions = SparseArray<Region>()
+    // Track last bounds of task before toggled to stable bounds
+    private val boundsBeforeMaximizeByTaskId = SparseArray<Rect>()
     private var desktopGestureExclusionListener: Consumer<Region>? = null
     private var desktopGestureExclusionExecutor: Executor? = null
 
@@ -226,6 +230,14 @@
                         displayData[otherDisplayId].visibleTasks.size)
                 }
             }
+        } else if (displayId == INVALID_DISPLAY) {
+            // Task has vanished. Check which display to remove the task from.
+            displayData.forEach { displayId, data ->
+                if (data.visibleTasks.remove(taskId)) {
+                    notifyVisibleTaskListeners(displayId, data.visibleTasks.size)
+                }
+            }
+            return
         }
 
         val prevCount = getVisibleTaskCount(displayId)
@@ -236,6 +248,7 @@
         }
         val newCount = getVisibleTaskCount(displayId)
 
+        // Check if count changed
         if (prevCount != newCount) {
             KtProtoLog.d(
                 WM_SHELL_DESKTOP_MODE,
@@ -244,10 +257,6 @@
                 visible,
                 displayId
             )
-        }
-
-        // Check if count changed
-        if (prevCount != newCount) {
             KtProtoLog.d(
                 WM_SHELL_DESKTOP_MODE,
                 "DesktopTaskRepo: visibleTaskCount has changed from %d to %d",
@@ -301,6 +310,7 @@
             taskId
         )
         freeformTasksInZOrder.remove(taskId)
+        boundsBeforeMaximizeByTaskId.remove(taskId)
         KtProtoLog.d(
             WM_SHELL_DESKTOP_MODE,
             "DesktopTaskRepo: remaining freeform tasks: " + freeformTasksInZOrder.toDumpString()
@@ -352,6 +362,20 @@
     }
 
     /**
+     * Removes and returns the bounds saved before maximizing the given task.
+     */
+    fun removeBoundsBeforeMaximize(taskId: Int): Rect? {
+        return boundsBeforeMaximizeByTaskId.removeReturnOld(taskId)
+    }
+
+    /**
+     * Saves the bounds of the given task before maximizing.
+     */
+    fun saveBoundsBeforeMaximize(taskId: Int, bounds: Rect) {
+        boundsBeforeMaximizeByTaskId.set(taskId, Rect(bounds))
+    }
+
+    /**
      * Check if display with id [displayId] has desktop tasks stashed
      */
     fun isStashed(displayId: Int): Boolean {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index c369061..e210ea7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -120,7 +120,6 @@
     private var visualIndicator: DesktopModeVisualIndicator? = null
     private val desktopModeShellCommandHandler: DesktopModeShellCommandHandler =
         DesktopModeShellCommandHandler(this)
-
     private val mOnAnimationFinishedCallback = Consumer<SurfaceControl.Transaction> {
         t: SurfaceControl.Transaction ->
         visualIndicator?.releaseVisualIndicator(t)
@@ -570,7 +569,10 @@
         }
     }
 
-    /** Quick-resizes a desktop task, toggling between the stable bounds and the default bounds. */
+    /**
+     * Quick-resizes a desktop task, toggling between the stable bounds and the last saved bounds
+     * if available or the default bounds otherwise.
+     */
     fun toggleDesktopTaskSize(taskInfo: RunningTaskInfo) {
         val displayLayout = displayController.getDisplayLayout(taskInfo.displayId) ?: return
 
@@ -578,11 +580,21 @@
         displayLayout.getStableBounds(stableBounds)
         val destinationBounds = Rect()
         if (taskInfo.configuration.windowConfiguration.bounds == stableBounds) {
-            // The desktop task is currently occupying the whole stable bounds, toggle to the
-            // default bounds.
-            getDefaultDesktopTaskBounds(displayLayout, destinationBounds)
+            // The desktop task is currently occupying the whole stable bounds. If the bounds
+            // before the task was toggled to stable bounds were saved, toggle the task to those
+            // bounds. Otherwise, toggle to the default bounds.
+            val taskBoundsBeforeMaximize =
+                    desktopModeTaskRepository.removeBoundsBeforeMaximize(taskInfo.taskId)
+            if (taskBoundsBeforeMaximize != null) {
+                destinationBounds.set(taskBoundsBeforeMaximize)
+            } else {
+                getDefaultDesktopTaskBounds(displayLayout, destinationBounds)
+            }
         } else {
-            // Toggle to the stable bounds.
+            // Save current bounds so that task can be restored back to original bounds if necessary
+            // and toggle to the stable bounds.
+            val taskBounds = taskInfo.configuration.windowConfiguration.bounds
+            desktopModeTaskRepository.saveBoundsBeforeMaximize(taskInfo.taskId, taskBounds)
             destinationBounds.set(stableBounds)
         }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
index b830a41..0061d03 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandler.kt
@@ -369,67 +369,50 @@
             val startBounds = draggedTaskChange.startAbsBounds
             val endBounds = draggedTaskChange.endAbsBounds
 
-            // TODO(b/301106941): Instead of forcing-finishing the animation that scales the
-            //  surface down and then starting another that scales it back up to the final size,
-            //  blend the two animations.
-            state.dragAnimator.endAnimator()
-            // Using [DRAG_FREEFORM_SCALE] to calculate animated width/height is possible because
-            // it is known that the animation scale is finished because the animation was
-            // force-ended above. This won't be true when the two animations are blended.
-            val animStartWidth = (startBounds.width() * DRAG_FREEFORM_SCALE).toInt()
-            val animStartHeight = (startBounds.height() * DRAG_FREEFORM_SCALE).toInt()
-            // Using end bounds here to find the left/top also assumes the center animation has
-            // finished and the surface is placed exactly in the center of the screen which matches
-            // the end/default bounds of the now freeform task.
-            val animStartLeft = endBounds.centerX() - (animStartWidth / 2)
-            val animStartTop = endBounds.centerY() - (animStartHeight / 2)
-            val animStartBounds = Rect(
-                    animStartLeft,
-                    animStartTop,
-                    animStartLeft + animStartWidth,
-                    animStartTop + animStartHeight
+            // Pause any animation that may be currently playing; we will use the relevant
+            // details of that animation here.
+            state.dragAnimator.cancelAnimator()
+            // We still apply scale to task bounds; as we animate the bounds to their
+            // end value, animate scale to 1.
+            val startScale = state.dragAnimator.scale
+            val startPosition = state.dragAnimator.position
+            val unscaledStartWidth = startBounds.width()
+            val unscaledStartHeight = startBounds.height()
+            val unscaledStartBounds = Rect(
+                startPosition.x.toInt(),
+                startPosition.y.toInt(),
+                startPosition.x.toInt() + unscaledStartWidth,
+                startPosition.y.toInt() + unscaledStartHeight
             )
 
-
             dragToDesktopStateListener?.onCommitToDesktopAnimationStart(t)
-            t.apply {
-                setScale(draggedTaskLeash, 1f, 1f)
-                setPosition(
-                        draggedTaskLeash,
-                        animStartBounds.left.toFloat(),
-                        animStartBounds.top.toFloat()
-                )
-                setWindowCrop(
-                        draggedTaskLeash,
-                        animStartBounds.width(),
-                        animStartBounds.height()
-                )
-            }
             // Accept the merge by applying the merging transaction (applied by #showResizeVeil)
             // and finish callback. Show the veil and position the task at the first frame before
             // starting the final animation.
-            onTaskResizeAnimationListener.onAnimationStart(state.draggedTaskId, t, animStartBounds)
+            onTaskResizeAnimationListener.onAnimationStart(state.draggedTaskId, t,
+                unscaledStartBounds)
             finishCallback.onTransitionFinished(null /* wct */)
 
-            // Because the task surface was scaled down during the drag, we must use the animated
-            // bounds instead of the [startAbsBounds].
             val tx: SurfaceControl.Transaction = transactionSupplier.get()
-            ValueAnimator.ofObject(rectEvaluator, animStartBounds, endBounds)
+            ValueAnimator.ofObject(rectEvaluator, unscaledStartBounds, endBounds)
                     .setDuration(DRAG_TO_DESKTOP_FINISH_ANIM_DURATION_MS)
                     .apply {
                         addUpdateListener { animator ->
                             val animBounds = animator.animatedValue as Rect
+                            val animFraction = animator.animatedFraction
+                            // Progress scale from starting value to 1 as animation plays.
+                            val animScale = startScale + animFraction * (1 - startScale)
                             tx.apply {
-                                setScale(draggedTaskLeash, 1f, 1f)
-                                 setPosition(
-                                         draggedTaskLeash,
-                                         animBounds.left.toFloat(),
-                                         animBounds.top.toFloat()
-                                 )
+                                setScale(draggedTaskLeash, animScale, animScale)
+                                setPosition(
+                                     draggedTaskLeash,
+                                     animBounds.left.toFloat(),
+                                     animBounds.top.toFloat()
+                                )
                                 setWindowCrop(
-                                        draggedTaskLeash,
-                                        animBounds.width(),
-                                        animBounds.height()
+                                    draggedTaskLeash,
+                                    animBounds.width(),
+                                    animBounds.height()
                                 )
                             }
                             onTaskResizeAnimationListener.onBoundsChange(
@@ -493,10 +476,8 @@
         val draggedTaskChange = state.draggedTaskChange
                 ?: throw IllegalStateException("Expected non-null task change")
         val sc = draggedTaskChange.leash
-        // TODO(b/301106941): Don't end the animation and start one to scale it back, merge them
-        //  instead.
-        // End the animation that shrinks the window when task is first dragged from fullscreen
-        dragToDesktopAnimator.endAnimator()
+        // Pause the animation that shrinks the window when task is first dragged from fullscreen
+        dragToDesktopAnimator.cancelAnimator()
         // Then animate the scaled window back to its original bounds.
         val x: Float = dragToDesktopAnimator.position.x
         val y: Float = dragToDesktopAnimator.position.y
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index cdeb00b..c16eac8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -1957,6 +1957,8 @@
         }
         if (mPipTransitionState.getTransitionState() == PipTransitionState.UNDEFINED) {
             // Avoid double removal, which is fatal.
+            ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: trying to remove overlay (%s) while in UNDEFINED state", TAG, surface);
             return;
         }
         if (surface == null || !surface.isValid()) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
index 4c69cc3..1e18b8c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
@@ -245,9 +245,9 @@
             Rect destinationBounds, SurfaceControl overlay, Rect appBounds) {
         ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                 "onSwipePipToHomeAnimationStart: %s", componentName);
-        mPipScheduler.setInSwipePipToHomeTransition(true);
+        mPipScheduler.onSwipePipToHomeAnimationStart(taskId, componentName, destinationBounds,
+                overlay, appBounds);
         mPipRecentsAnimationListener.onPipAnimationStarted();
-        // TODO: cache the overlay if provided for reparenting later.
     }
 
     //
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDismissTargetHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDismissTargetHandler.java
new file mode 100644
index 0000000..e7e7970
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipDismissTargetHandler.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.pip2.phone;
+
+import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.view.MotionEvent;
+import android.view.SurfaceControl;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.WindowInsets;
+import android.view.WindowManager;
+
+import androidx.annotation.NonNull;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.bubbles.DismissViewUtils;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.bubbles.DismissCircleView;
+import com.android.wm.shell.common.bubbles.DismissView;
+import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
+
+import kotlin.Unit;
+
+/**
+ * Handler of all Magnetized Object related code for PiP.
+ */
+public class PipDismissTargetHandler implements ViewTreeObserver.OnPreDrawListener {
+
+    /* The multiplier to apply scale the target size by when applying the magnetic field radius */
+    private static final float MAGNETIC_FIELD_RADIUS_MULTIPLIER = 1.25f;
+
+    /**
+     * MagnetizedObject wrapper for PIP. This allows the magnetic target library to locate and move
+     * PIP.
+     */
+    private MagnetizedObject<Rect> mMagnetizedPip;
+
+    /**
+     * Container for the dismiss circle, so that it can be animated within the container via
+     * translation rather than within the WindowManager via slow layout animations.
+     */
+    private DismissView mTargetViewContainer;
+
+    /** Circle view used to render the dismiss target. */
+    private DismissCircleView mTargetView;
+
+    /**
+     * MagneticTarget instance wrapping the target view and allowing us to set its magnetic radius.
+     */
+    private MagnetizedObject.MagneticTarget mMagneticTarget;
+
+    // Allow dragging the PIP to a location to close it
+    private boolean mEnableDismissDragToEdge;
+
+    private int mTargetSize;
+    private int mDismissAreaHeight;
+    private float mMagneticFieldRadiusPercent = 1f;
+    private WindowInsets mWindowInsets;
+
+    private SurfaceControl mTaskLeash;
+    private boolean mHasDismissTargetSurface;
+
+    private final Context mContext;
+    private final PipMotionHelper mMotionHelper;
+    private final PipUiEventLogger mPipUiEventLogger;
+    private final WindowManager mWindowManager;
+    private final ShellExecutor mMainExecutor;
+
+    public PipDismissTargetHandler(Context context, PipUiEventLogger pipUiEventLogger,
+            PipMotionHelper motionHelper, ShellExecutor mainExecutor) {
+        mContext = context;
+        mPipUiEventLogger = pipUiEventLogger;
+        mMotionHelper = motionHelper;
+        mMainExecutor = mainExecutor;
+        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+    }
+
+    void init() {
+        Resources res = mContext.getResources();
+        mEnableDismissDragToEdge = res.getBoolean(R.bool.config_pipEnableDismissDragToEdge);
+        mDismissAreaHeight = res.getDimensionPixelSize(R.dimen.floating_dismiss_gradient_height);
+
+        if (mTargetViewContainer != null) {
+            // init can be called multiple times, remove the old one from view hierarchy first.
+            cleanUpDismissTarget();
+        }
+
+        mTargetViewContainer = new DismissView(mContext);
+        DismissViewUtils.setup(mTargetViewContainer);
+        mTargetView = mTargetViewContainer.getCircle();
+        mTargetViewContainer.setOnApplyWindowInsetsListener((view, windowInsets) -> {
+            if (!windowInsets.equals(mWindowInsets)) {
+                mWindowInsets = windowInsets;
+                updateMagneticTargetSize();
+            }
+            return windowInsets;
+        });
+
+        mMagnetizedPip = mMotionHelper.getMagnetizedPip();
+        mMagnetizedPip.clearAllTargets();
+        mMagneticTarget = mMagnetizedPip.addTarget(mTargetView, 0);
+        updateMagneticTargetSize();
+
+        mMagnetizedPip.setAnimateStuckToTarget(
+                (target, velX, velY, flung, after) -> {
+                    if (mEnableDismissDragToEdge) {
+                        mMotionHelper.animateIntoDismissTarget(target, velX, velY, flung, after);
+                    }
+                    return Unit.INSTANCE;
+                });
+        mMagnetizedPip.setMagnetListener(new MagnetizedObject.MagnetListener() {
+            @Override
+            public void onStuckToTarget(@NonNull MagnetizedObject.MagneticTarget target,
+                    @NonNull MagnetizedObject<?> draggedObject) {
+                // Show the dismiss target, in case the initial touch event occurred within
+                // the magnetic field radius.
+                if (mEnableDismissDragToEdge) {
+                    showDismissTargetMaybe();
+                }
+            }
+
+            @Override
+            public void onUnstuckFromTarget(@NonNull MagnetizedObject.MagneticTarget target,
+                    @NonNull MagnetizedObject<?> draggedObject,
+                    float velX, float velY, boolean wasFlungOut) {
+                if (wasFlungOut) {
+                    mMotionHelper.flingToSnapTarget(velX, velY, null /* endAction */);
+                    hideDismissTargetMaybe();
+                } else {
+                    mMotionHelper.setSpringingToTouch(true);
+                }
+            }
+
+            @Override
+            public void onReleasedInTarget(@NonNull MagnetizedObject.MagneticTarget target,
+                    @NonNull MagnetizedObject<?> draggedObject) {
+                if (mEnableDismissDragToEdge) {
+                    mMainExecutor.executeDelayed(() -> {
+                        mMotionHelper.notifyDismissalPending();
+                        mMotionHelper.animateDismiss();
+                        hideDismissTargetMaybe();
+
+                        mPipUiEventLogger.log(
+                                PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_DRAG_TO_REMOVE);
+                    }, 0);
+                }
+            }
+        });
+
+    }
+
+    @Override
+    public boolean onPreDraw() {
+        mTargetViewContainer.getViewTreeObserver().removeOnPreDrawListener(this);
+        mHasDismissTargetSurface = true;
+        updateDismissTargetLayer();
+        return true;
+    }
+
+    /**
+     * Potentially start consuming future motion events if PiP is currently near the magnetized
+     * object.
+     */
+    public boolean maybeConsumeMotionEvent(MotionEvent ev) {
+        return mMagnetizedPip.maybeConsumeMotionEvent(ev);
+    }
+
+    /**
+     * Update the magnet size.
+     */
+    public void updateMagneticTargetSize() {
+        if (mTargetView == null) {
+            return;
+        }
+        if (mTargetViewContainer != null) {
+            mTargetViewContainer.updateResources();
+        }
+
+        final Resources res = mContext.getResources();
+        mTargetSize = res.getDimensionPixelSize(R.dimen.dismiss_circle_size);
+        mDismissAreaHeight = res.getDimensionPixelSize(R.dimen.floating_dismiss_gradient_height);
+
+        // Set the magnetic field radius equal to the target size from the center of the target
+        setMagneticFieldRadiusPercent(mMagneticFieldRadiusPercent);
+    }
+
+    /**
+     * Increase or decrease the field radius of the magnet object, e.g. with larger percent,
+     * PiP will magnetize to the field sooner.
+     */
+    public void setMagneticFieldRadiusPercent(float percent) {
+        mMagneticFieldRadiusPercent = percent;
+        mMagneticTarget.setMagneticFieldRadiusPx((int) (mMagneticFieldRadiusPercent * mTargetSize
+                        * MAGNETIC_FIELD_RADIUS_MULTIPLIER));
+    }
+
+    public void setTaskLeash(SurfaceControl taskLeash) {
+        mTaskLeash = taskLeash;
+    }
+
+    private void updateDismissTargetLayer() {
+        if (!mHasDismissTargetSurface || mTaskLeash == null) {
+            // No dismiss target surface, can just return
+            return;
+        }
+
+        final SurfaceControl targetViewLeash =
+                mTargetViewContainer.getViewRootImpl().getSurfaceControl();
+        if (!targetViewLeash.isValid()) {
+            // The surface of mTargetViewContainer is somehow not ready, bail early
+            return;
+        }
+
+        // Put the dismiss target behind the task
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        t.setRelativeLayer(targetViewLeash, mTaskLeash, -1);
+        t.apply();
+    }
+
+    /** Adds the magnetic target view to the WindowManager so it's ready to be animated in. */
+    public void createOrUpdateDismissTarget() {
+        if (mTargetViewContainer.getParent() == null) {
+            mTargetViewContainer.cancelAnimators();
+
+            mTargetViewContainer.setVisibility(View.INVISIBLE);
+            mTargetViewContainer.getViewTreeObserver().removeOnPreDrawListener(this);
+            mHasDismissTargetSurface = false;
+
+            mWindowManager.addView(mTargetViewContainer, getDismissTargetLayoutParams());
+        } else {
+            mWindowManager.updateViewLayout(mTargetViewContainer, getDismissTargetLayoutParams());
+        }
+    }
+
+    /** Returns layout params for the dismiss target, using the latest display metrics. */
+    private WindowManager.LayoutParams getDismissTargetLayoutParams() {
+        final Point windowSize = new Point();
+        mWindowManager.getDefaultDisplay().getRealSize(windowSize);
+        int height = Math.min(windowSize.y, mDismissAreaHeight);
+        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                WindowManager.LayoutParams.MATCH_PARENT,
+                height,
+                0, windowSize.y - height,
+                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+                PixelFormat.TRANSLUCENT);
+
+        lp.setTitle("pip-dismiss-overlay");
+        lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
+        lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+        lp.setFitInsetsTypes(0 /* types */);
+
+        return lp;
+    }
+
+    /** Makes the dismiss target visible and animates it in, if it isn't already visible. */
+    public void showDismissTargetMaybe() {
+        if (!mEnableDismissDragToEdge) {
+            return;
+        }
+
+        createOrUpdateDismissTarget();
+
+        if (mTargetViewContainer.getVisibility() != View.VISIBLE) {
+            mTargetViewContainer.getViewTreeObserver().addOnPreDrawListener(this);
+        }
+        // always invoke show, since the target might still be VISIBLE while playing hide animation,
+        // so we want to ensure it will show back again
+        mTargetViewContainer.show();
+    }
+
+    /** Animates the magnetic dismiss target out and then sets it to GONE. */
+    public void hideDismissTargetMaybe() {
+        if (!mEnableDismissDragToEdge) {
+            return;
+        }
+        mTargetViewContainer.hide();
+    }
+
+    /**
+     * Removes the dismiss target and cancels any pending callbacks to show it.
+     */
+    public void cleanUpDismissTarget() {
+        if (mTargetViewContainer.getParent() != null) {
+            mWindowManager.removeViewImmediate(mTargetViewContainer);
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java
new file mode 100644
index 0000000..03547a5
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipInputConsumer.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.pip2.phone;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.view.BatchedInputEventReceiver;
+import android.view.Choreographer;
+import android.view.IWindowManager;
+import android.view.InputChannel;
+import android.view.InputEvent;
+
+import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
+
+import java.io.PrintWriter;
+
+/**
+ * Manages the input consumer that allows the Shell to directly receive input.
+ */
+public class PipInputConsumer {
+
+    private static final String TAG = PipInputConsumer.class.getSimpleName();
+
+    /**
+     * Listener interface for callers to subscribe to input events.
+     */
+    public interface InputListener {
+        /** Handles any input event. */
+        boolean onInputEvent(InputEvent ev);
+    }
+
+    /**
+     * Listener interface for callers to learn when this class is registered or unregistered with
+     * window manager
+     */
+    private interface RegistrationListener {
+        void onRegistrationChanged(boolean isRegistered);
+    }
+
+    /**
+     * Input handler used for the input consumer. Input events are batched and consumed with the
+     * SurfaceFlinger vsync.
+     */
+    private final class InputEventReceiver extends BatchedInputEventReceiver {
+
+        InputEventReceiver(InputChannel inputChannel, Looper looper,
+                Choreographer choreographer) {
+            super(inputChannel, looper, choreographer);
+        }
+
+        @Override
+        public void onInputEvent(InputEvent event) {
+            boolean handled = true;
+            try {
+                if (mListener != null) {
+                    handled = mListener.onInputEvent(event);
+                }
+            } finally {
+                finishInputEvent(event, handled);
+            }
+        }
+    }
+
+    private final IWindowManager mWindowManager;
+    private final IBinder mToken;
+    private final String mName;
+    private final ShellExecutor mMainExecutor;
+
+    private InputEventReceiver mInputEventReceiver;
+    private InputListener mListener;
+    private RegistrationListener mRegistrationListener;
+
+    /**
+     * @param name the name corresponding to the input consumer that is defined in the system.
+     */
+    public PipInputConsumer(IWindowManager windowManager, String name,
+            ShellExecutor mainExecutor) {
+        mWindowManager = windowManager;
+        mToken = new Binder();
+        mName = name;
+        mMainExecutor = mainExecutor;
+    }
+
+    /**
+     * Sets the input listener.
+     */
+    public void setInputListener(InputListener listener) {
+        mListener = listener;
+    }
+
+    /**
+     * Sets the registration listener.
+     */
+    public void setRegistrationListener(RegistrationListener listener) {
+        mRegistrationListener = listener;
+        mMainExecutor.execute(() -> {
+            if (mRegistrationListener != null) {
+                mRegistrationListener.onRegistrationChanged(mInputEventReceiver != null);
+            }
+        });
+    }
+
+    /**
+     * Check if the InputConsumer is currently registered with WindowManager
+     *
+     * @return {@code true} if registered, {@code false} if not.
+     */
+    public boolean isRegistered() {
+        return mInputEventReceiver != null;
+    }
+
+    /**
+     * Registers the input consumer.
+     */
+    public void registerInputConsumer() {
+        if (mInputEventReceiver != null) {
+            return;
+        }
+        final InputChannel inputChannel = new InputChannel();
+        try {
+            // TODO(b/113087003): Support Picture-in-picture in multi-display.
+            mWindowManager.destroyInputConsumer(mToken, DEFAULT_DISPLAY);
+            mWindowManager.createInputConsumer(mToken, mName, DEFAULT_DISPLAY, inputChannel);
+        } catch (RemoteException e) {
+            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Failed to create input consumer, %s", TAG, e);
+        }
+        mMainExecutor.execute(() -> {
+            mInputEventReceiver = new InputEventReceiver(inputChannel,
+                Looper.myLooper(), Choreographer.getInstance());
+            if (mRegistrationListener != null) {
+                mRegistrationListener.onRegistrationChanged(true /* isRegistered */);
+            }
+        });
+    }
+
+    /**
+     * Unregisters the input consumer.
+     */
+    public void unregisterInputConsumer() {
+        if (mInputEventReceiver == null) {
+            return;
+        }
+        try {
+            // TODO(b/113087003): Support Picture-in-picture in multi-display.
+            mWindowManager.destroyInputConsumer(mToken, DEFAULT_DISPLAY);
+        } catch (RemoteException e) {
+            ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Failed to destroy input consumer, %s", TAG, e);
+        }
+        mInputEventReceiver.dispose();
+        mInputEventReceiver = null;
+        mMainExecutor.execute(() -> {
+            if (mRegistrationListener != null) {
+                mRegistrationListener.onRegistrationChanged(false /* isRegistered */);
+            }
+        });
+    }
+
+    /**
+     * Dumps the {@link PipInputConsumer} state.
+     */
+    public void dump(PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "registered=" + (mInputEventReceiver != null));
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
new file mode 100644
index 0000000..619bed4
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipMotionHelper.java
@@ -0,0 +1,719 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.pip2.phone;
+
+import static androidx.dynamicanimation.animation.SpringForce.DAMPING_RATIO_NO_BOUNCY;
+import static androidx.dynamicanimation.animation.SpringForce.STIFFNESS_LOW;
+import static androidx.dynamicanimation.animation.SpringForce.STIFFNESS_MEDIUM;
+
+import static com.android.wm.shell.common.pip.PipBoundsState.STASH_TYPE_LEFT;
+import static com.android.wm.shell.common.pip.PipBoundsState.STASH_TYPE_NONE;
+import static com.android.wm.shell.common.pip.PipBoundsState.STASH_TYPE_RIGHT;
+import static com.android.wm.shell.pip2.phone.PipMenuView.ANIM_TYPE_DISMISS;
+import static com.android.wm.shell.pip2.phone.PipMenuView.ANIM_TYPE_NONE;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.os.Debug;
+
+import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.R;
+import com.android.wm.shell.animation.FloatProperties;
+import com.android.wm.shell.common.FloatingContentCoordinator;
+import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
+import com.android.wm.shell.common.pip.PipAppOpsListener;
+import com.android.wm.shell.common.pip.PipBoundsState;
+import com.android.wm.shell.common.pip.PipPerfHintController;
+import com.android.wm.shell.common.pip.PipSnapAlgorithm;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
+import com.android.wm.shell.shared.animation.PhysicsAnimator;
+
+import kotlin.Unit;
+import kotlin.jvm.functions.Function0;
+
+import java.util.Optional;
+import java.util.function.Consumer;
+
+/**
+ * A helper to animate and manipulate the PiP.
+ */
+public class PipMotionHelper implements PipAppOpsListener.Callback,
+        FloatingContentCoordinator.FloatingContent {
+    private static final String TAG = "PipMotionHelper";
+    private static final boolean DEBUG = false;
+
+    private static final int SHRINK_STACK_FROM_MENU_DURATION = 250;
+    private static final int EXPAND_STACK_TO_MENU_DURATION = 250;
+    private static final int UNSTASH_DURATION = 250;
+    private static final int LEAVE_PIP_DURATION = 300;
+    private static final int SHIFT_DURATION = 300;
+
+    /** Friction to use for PIP when it moves via physics fling animations. */
+    private static final float DEFAULT_FRICTION = 1.9f;
+    /** How much of the dismiss circle size to use when scaling down PIP. **/
+    private static final float DISMISS_CIRCLE_PERCENT = 0.85f;
+
+    private final Context mContext;
+    private @NonNull PipBoundsState mPipBoundsState;
+
+    private PhonePipMenuController mMenuController;
+    private PipSnapAlgorithm mSnapAlgorithm;
+
+    /** The region that all of PIP must stay within. */
+    private final Rect mFloatingAllowedArea = new Rect();
+
+    /** Coordinator instance for resolving conflicts with other floating content. */
+    private FloatingContentCoordinator mFloatingContentCoordinator;
+
+    @Nullable private final PipPerfHintController mPipPerfHintController;
+    @Nullable private PipPerfHintController.PipHighPerfSession mPipHighPerfSession;
+
+    /**
+     * PhysicsAnimator instance for animating {@link PipBoundsState#getMotionBoundsState()}
+     * using physics animations.
+     */
+    private PhysicsAnimator<Rect> mTemporaryBoundsPhysicsAnimator;
+
+    private MagnetizedObject<Rect> mMagnetizedPip;
+
+    /**
+     * Update listener that resizes the PIP to {@link PipBoundsState#getMotionBoundsState()}.
+     */
+    private final PhysicsAnimator.UpdateListener<Rect> mResizePipUpdateListener;
+
+    /** FlingConfig instances provided to PhysicsAnimator for fling gestures. */
+    private PhysicsAnimator.FlingConfig mFlingConfigX;
+    private PhysicsAnimator.FlingConfig mFlingConfigY;
+    /** FlingConfig instances provided to PhysicsAnimator for stashing. */
+    private PhysicsAnimator.FlingConfig mStashConfigX;
+
+    /** SpringConfig to use for fling-then-spring animations. */
+    private final PhysicsAnimator.SpringConfig mSpringConfig =
+            new PhysicsAnimator.SpringConfig(700f, DAMPING_RATIO_NO_BOUNCY);
+
+    /** SpringConfig used for animating into the dismiss region, matches the one in
+     * {@link MagnetizedObject}. */
+    private final PhysicsAnimator.SpringConfig mAnimateToDismissSpringConfig =
+            new PhysicsAnimator.SpringConfig(STIFFNESS_MEDIUM, DAMPING_RATIO_NO_BOUNCY);
+
+    /** SpringConfig used for animating the pip to catch up to the finger once it leaves the dismiss
+     * drag region. */
+    private final PhysicsAnimator.SpringConfig mCatchUpSpringConfig =
+            new PhysicsAnimator.SpringConfig(5000f, DAMPING_RATIO_NO_BOUNCY);
+
+    /** SpringConfig to use for springing PIP away from conflicting floating content. */
+    private final PhysicsAnimator.SpringConfig mConflictResolutionSpringConfig =
+            new PhysicsAnimator.SpringConfig(STIFFNESS_LOW, DAMPING_RATIO_NO_BOUNCY);
+
+    private final Consumer<Rect> mUpdateBoundsCallback = (Rect newBounds) -> {
+        if (mPipBoundsState.getBounds().equals(newBounds)) {
+            return;
+        }
+
+        mMenuController.updateMenuLayout(newBounds);
+        mPipBoundsState.setBounds(newBounds);
+    };
+
+    /**
+     * Whether we're springing to the touch event location (vs. moving it to that position
+     * instantly). We spring-to-touch after PIP is dragged out of the magnetic target, since it was
+     * 'stuck' in the target and needs to catch up to the touch location.
+     */
+    private boolean mSpringingToTouch = false;
+
+    /**
+     * Whether PIP was released in the dismiss target, and will be animated out and dismissed
+     * shortly.
+     */
+    private boolean mDismissalPending = false;
+
+    /**
+     * Gets set in {@link #animateToExpandedState(Rect, Rect, Rect, Runnable)}, this callback is
+     * used to show menu activity when the expand animation is completed.
+     */
+    private Runnable mPostPipTransitionCallback;
+
+    public PipMotionHelper(Context context, @NonNull PipBoundsState pipBoundsState,
+            PhonePipMenuController menuController, PipSnapAlgorithm snapAlgorithm,
+            FloatingContentCoordinator floatingContentCoordinator,
+            Optional<PipPerfHintController> pipPerfHintControllerOptional) {
+        mContext = context;
+        mPipBoundsState = pipBoundsState;
+        mMenuController = menuController;
+        mSnapAlgorithm = snapAlgorithm;
+        mFloatingContentCoordinator = floatingContentCoordinator;
+        mPipPerfHintController = pipPerfHintControllerOptional.orElse(null);
+        mResizePipUpdateListener = (target, values) -> {
+            if (mPipBoundsState.getMotionBoundsState().isInMotion()) {
+                /*
+                mPipTaskOrganizer.scheduleUserResizePip(getBounds(),
+                        mPipBoundsState.getMotionBoundsState().getBoundsInMotion(), null);
+                 */
+            }
+        };
+    }
+
+    void init() {
+        mTemporaryBoundsPhysicsAnimator = PhysicsAnimator.getInstance(
+                mPipBoundsState.getMotionBoundsState().getBoundsInMotion());
+    }
+
+    @NonNull
+    @Override
+    public Rect getFloatingBoundsOnScreen() {
+        return !mPipBoundsState.getMotionBoundsState().getAnimatingToBounds().isEmpty()
+                ? mPipBoundsState.getMotionBoundsState().getAnimatingToBounds() : getBounds();
+    }
+
+    @NonNull
+    @Override
+    public Rect getAllowedFloatingBoundsRegion() {
+        return mFloatingAllowedArea;
+    }
+
+    @Override
+    public void moveToBounds(@NonNull Rect bounds) {
+        animateToBounds(bounds, mConflictResolutionSpringConfig);
+    }
+
+    /**
+     * Synchronizes the current bounds with the pinned stack, cancelling any ongoing animations.
+     */
+    void synchronizePinnedStackBounds() {
+        cancelPhysicsAnimation();
+        mPipBoundsState.getMotionBoundsState().onAllAnimationsEnded();
+
+        /*
+        if (mPipTaskOrganizer.isInPip()) {
+            mFloatingContentCoordinator.onContentMoved(this);
+        }
+         */
+    }
+
+    /**
+     * Tries to move the pinned stack to the given {@param bounds}.
+     */
+    void movePip(Rect toBounds) {
+        movePip(toBounds, false /* isDragging */);
+    }
+
+    /**
+     * Tries to move the pinned stack to the given {@param bounds}.
+     *
+     * @param isDragging Whether this movement is the result of a drag touch gesture. If so, we
+     *                   won't notify the floating content coordinator of this move, since that will
+     *                   happen when the gesture ends.
+     */
+    void movePip(Rect toBounds, boolean isDragging) {
+        if (!isDragging) {
+            mFloatingContentCoordinator.onContentMoved(this);
+        }
+
+        if (!mSpringingToTouch) {
+            // If we are moving PIP directly to the touch event locations, cancel any animations and
+            // move PIP to the given bounds.
+            cancelPhysicsAnimation();
+
+            if (!isDragging) {
+                resizePipUnchecked(toBounds);
+                mPipBoundsState.setBounds(toBounds);
+            } else {
+                mPipBoundsState.getMotionBoundsState().setBoundsInMotion(toBounds);
+                /*
+                mPipTaskOrganizer.scheduleUserResizePip(getBounds(), toBounds,
+                        (Rect newBounds) -> {
+                                mMenuController.updateMenuLayout(newBounds);
+                        });
+                 */
+            }
+        } else {
+            // If PIP is 'catching up' after being stuck in the dismiss target, update the animation
+            // to spring towards the new touch location.
+            mTemporaryBoundsPhysicsAnimator
+                    .spring(FloatProperties.RECT_WIDTH, getBounds().width(), mCatchUpSpringConfig)
+                    .spring(FloatProperties.RECT_HEIGHT, getBounds().height(), mCatchUpSpringConfig)
+                    .spring(FloatProperties.RECT_X, toBounds.left, mCatchUpSpringConfig)
+                    .spring(FloatProperties.RECT_Y, toBounds.top, mCatchUpSpringConfig);
+
+            startBoundsAnimator(toBounds.left /* toX */, toBounds.top /* toY */);
+        }
+    }
+
+    /** Animates the PIP into the dismiss target, scaling it down. */
+    void animateIntoDismissTarget(
+            MagnetizedObject.MagneticTarget target,
+            float velX, float velY,
+            boolean flung, Function0<Unit> after) {
+        final PointF targetCenter = target.getCenterOnScreen();
+
+        // PIP should fit in the circle
+        final float dismissCircleSize = mContext.getResources().getDimensionPixelSize(
+                R.dimen.dismiss_circle_size);
+
+        final float width = getBounds().width();
+        final float height = getBounds().height();
+        final float ratio = width / height;
+
+        // Width should be a little smaller than the circle size.
+        final float desiredWidth = dismissCircleSize * DISMISS_CIRCLE_PERCENT;
+        final float desiredHeight = desiredWidth / ratio;
+        final float destinationX = targetCenter.x - (desiredWidth / 2f);
+        final float destinationY = targetCenter.y - (desiredHeight / 2f);
+
+        // If we're already in the dismiss target area, then there won't be a move to set the
+        // temporary bounds, so just initialize it to the current bounds.
+        if (!mPipBoundsState.getMotionBoundsState().isInMotion()) {
+            mPipBoundsState.getMotionBoundsState().setBoundsInMotion(getBounds());
+        }
+        mTemporaryBoundsPhysicsAnimator
+                .spring(FloatProperties.RECT_X, destinationX, velX, mAnimateToDismissSpringConfig)
+                .spring(FloatProperties.RECT_Y, destinationY, velY, mAnimateToDismissSpringConfig)
+                .spring(FloatProperties.RECT_WIDTH, desiredWidth, mAnimateToDismissSpringConfig)
+                .spring(FloatProperties.RECT_HEIGHT, desiredHeight, mAnimateToDismissSpringConfig)
+                .withEndActions(after);
+
+        startBoundsAnimator(destinationX, destinationY);
+    }
+
+    /** Set whether we're springing-to-touch to catch up after being stuck in the dismiss target. */
+    void setSpringingToTouch(boolean springingToTouch) {
+        mSpringingToTouch = springingToTouch;
+    }
+
+    /**
+     * Resizes the pinned stack back to unknown windowing mode, which could be freeform or
+     *      * fullscreen depending on the display area's windowing mode.
+     */
+    void expandLeavePip(boolean skipAnimation) {
+        expandLeavePip(skipAnimation, false /* enterSplit */);
+    }
+
+    /**
+     * Resizes the pinned task to split-screen mode.
+     */
+    void expandIntoSplit() {
+        expandLeavePip(false, true /* enterSplit */);
+    }
+
+    /**
+     * Resizes the pinned stack back to unknown windowing mode, which could be freeform or
+     * fullscreen depending on the display area's windowing mode.
+     */
+    private void expandLeavePip(boolean skipAnimation, boolean enterSplit) {
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: exitPip: skipAnimation=%s"
+                            + " callers=\n%s", TAG, skipAnimation, Debug.getCallers(5, "    "));
+        }
+        cancelPhysicsAnimation();
+        mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */);
+        // mPipTaskOrganizer.exitPip(skipAnimation ? 0 : LEAVE_PIP_DURATION, enterSplit);
+    }
+
+    /**
+     * Dismisses the pinned stack.
+     */
+    @Override
+    public void dismissPip() {
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: removePip: callers=\n%s", TAG, Debug.getCallers(5, "    "));
+        }
+        cancelPhysicsAnimation();
+        mMenuController.hideMenu(ANIM_TYPE_DISMISS, false /* resize */);
+        // mPipTaskOrganizer.removePip();
+    }
+
+    /** Sets the movement bounds to use to constrain PIP position animations. */
+    void onMovementBoundsChanged() {
+        rebuildFlingConfigs();
+
+        // The movement bounds represent the area within which we can move PIP's top-left position.
+        // The allowed area for all of PIP is those bounds plus PIP's width and height.
+        mFloatingAllowedArea.set(mPipBoundsState.getMovementBounds());
+        mFloatingAllowedArea.right += getBounds().width();
+        mFloatingAllowedArea.bottom += getBounds().height();
+    }
+
+    /**
+     * @return the PiP bounds.
+     */
+    private Rect getBounds() {
+        return mPipBoundsState.getBounds();
+    }
+
+    /**
+     * Flings the PiP to the closest snap target.
+     */
+    void flingToSnapTarget(
+            float velocityX, float velocityY, @Nullable Runnable postBoundsUpdateCallback) {
+        movetoTarget(velocityX, velocityY, postBoundsUpdateCallback, false /* isStash */);
+    }
+
+    /**
+     * Stash PiP to the closest edge. We set velocityY to 0 to limit pure horizontal motion.
+     */
+    void stashToEdge(float velX, float velY, @Nullable Runnable postBoundsUpdateCallback) {
+        velY = mPipBoundsState.getStashedState() == STASH_TYPE_NONE ? 0 : velY;
+        movetoTarget(velX, velY, postBoundsUpdateCallback, true /* isStash */);
+    }
+
+    private void onHighPerfSessionTimeout(PipPerfHintController.PipHighPerfSession session) {}
+
+    private void cleanUpHighPerfSessionMaybe() {
+        if (mPipHighPerfSession != null) {
+            // Close the high perf session once pointer interactions are over;
+            mPipHighPerfSession.close();
+            mPipHighPerfSession = null;
+        }
+    }
+
+    private void movetoTarget(
+            float velocityX,
+            float velocityY,
+            @Nullable Runnable postBoundsUpdateCallback,
+            boolean isStash) {
+        // If we're flinging to a snap target now, we're not springing to catch up to the touch
+        // location now.
+        mSpringingToTouch = false;
+
+        mTemporaryBoundsPhysicsAnimator
+                .spring(FloatProperties.RECT_WIDTH, getBounds().width(), mSpringConfig)
+                .spring(FloatProperties.RECT_HEIGHT, getBounds().height(), mSpringConfig)
+                .flingThenSpring(
+                        FloatProperties.RECT_X, velocityX,
+                        isStash ? mStashConfigX : mFlingConfigX,
+                        mSpringConfig, true /* flingMustReachMinOrMax */)
+                .flingThenSpring(
+                        FloatProperties.RECT_Y, velocityY, mFlingConfigY, mSpringConfig);
+
+        final Rect insetBounds = mPipBoundsState.getDisplayLayout().stableInsets();
+        final float leftEdge = isStash
+                ? mPipBoundsState.getStashOffset() - mPipBoundsState.getBounds().width()
+                + insetBounds.left
+                : mPipBoundsState.getMovementBounds().left;
+        final float rightEdge = isStash
+                ?  mPipBoundsState.getDisplayBounds().right - mPipBoundsState.getStashOffset()
+                - insetBounds.right
+                : mPipBoundsState.getMovementBounds().right;
+
+        final float xEndValue = velocityX < 0 ? leftEdge : rightEdge;
+
+        final int startValueY = mPipBoundsState.getMotionBoundsState().getBoundsInMotion().top;
+        final float estimatedFlingYEndValue =
+                PhysicsAnimator.estimateFlingEndValue(startValueY, velocityY, mFlingConfigY);
+
+        startBoundsAnimator(xEndValue /* toX */, estimatedFlingYEndValue /* toY */,
+                postBoundsUpdateCallback);
+    }
+
+    /**
+     * Animates PIP to the provided bounds, using physics animations and the given spring
+     * configuration
+     */
+    void animateToBounds(Rect bounds, PhysicsAnimator.SpringConfig springConfig) {
+        if (!mTemporaryBoundsPhysicsAnimator.isRunning()) {
+            // Animate from the current bounds if we're not already animating.
+            mPipBoundsState.getMotionBoundsState().setBoundsInMotion(getBounds());
+        }
+
+        mTemporaryBoundsPhysicsAnimator
+                .spring(FloatProperties.RECT_X, bounds.left, springConfig)
+                .spring(FloatProperties.RECT_Y, bounds.top, springConfig);
+        startBoundsAnimator(bounds.left /* toX */, bounds.top /* toY */);
+    }
+
+    /**
+     * Animates the dismissal of the PiP off the edge of the screen.
+     */
+    void animateDismiss() {
+        // Animate off the bottom of the screen, then dismiss PIP.
+        mTemporaryBoundsPhysicsAnimator
+                .spring(FloatProperties.RECT_Y,
+                        mPipBoundsState.getMovementBounds().bottom + getBounds().height() * 2,
+                        0,
+                        mSpringConfig)
+                .withEndActions(this::dismissPip);
+
+        startBoundsAnimator(
+                getBounds().left /* toX */, getBounds().bottom + getBounds().height() /* toY */);
+
+        mDismissalPending = false;
+    }
+
+    /**
+     * Animates the PiP to the expanded state to show the menu.
+     */
+    float animateToExpandedState(Rect expandedBounds, Rect movementBounds,
+            Rect expandedMovementBounds, Runnable callback) {
+        float savedSnapFraction = mSnapAlgorithm.getSnapFraction(new Rect(getBounds()),
+                movementBounds);
+        mSnapAlgorithm.applySnapFraction(expandedBounds, expandedMovementBounds, savedSnapFraction);
+        mPostPipTransitionCallback = callback;
+        resizeAndAnimatePipUnchecked(expandedBounds, EXPAND_STACK_TO_MENU_DURATION);
+        return savedSnapFraction;
+    }
+
+    /**
+     * Animates the PiP from the expanded state to the normal state after the menu is hidden.
+     */
+    void animateToUnexpandedState(Rect normalBounds, float savedSnapFraction,
+            Rect normalMovementBounds, Rect currentMovementBounds, boolean immediate) {
+        if (savedSnapFraction < 0f) {
+            // If there are no saved snap fractions, then just use the current bounds
+            savedSnapFraction = mSnapAlgorithm.getSnapFraction(new Rect(getBounds()),
+                    currentMovementBounds, mPipBoundsState.getStashedState());
+        }
+
+        mSnapAlgorithm.applySnapFraction(normalBounds, normalMovementBounds, savedSnapFraction,
+                mPipBoundsState.getStashedState(), mPipBoundsState.getStashOffset(),
+                mPipBoundsState.getDisplayBounds(),
+                mPipBoundsState.getDisplayLayout().stableInsets());
+
+        if (immediate) {
+            movePip(normalBounds);
+        } else {
+            resizeAndAnimatePipUnchecked(normalBounds, SHRINK_STACK_FROM_MENU_DURATION);
+        }
+    }
+
+    /**
+     * Animates the PiP to the stashed state, choosing the closest edge.
+     */
+    void animateToStashedClosestEdge() {
+        Rect tmpBounds = new Rect();
+        final Rect insetBounds = mPipBoundsState.getDisplayLayout().stableInsets();
+        final int stashType =
+                mPipBoundsState.getBounds().left == mPipBoundsState.getMovementBounds().left
+                ? STASH_TYPE_LEFT : STASH_TYPE_RIGHT;
+        final float leftEdge = stashType == STASH_TYPE_LEFT
+                ? mPipBoundsState.getStashOffset()
+                - mPipBoundsState.getBounds().width() + insetBounds.left
+                : mPipBoundsState.getDisplayBounds().right
+                        - mPipBoundsState.getStashOffset() - insetBounds.right;
+        tmpBounds.set((int) leftEdge,
+                mPipBoundsState.getBounds().top,
+                (int) (leftEdge + mPipBoundsState.getBounds().width()),
+                mPipBoundsState.getBounds().bottom);
+        resizeAndAnimatePipUnchecked(tmpBounds, UNSTASH_DURATION);
+        mPipBoundsState.setStashed(stashType);
+    }
+
+    /**
+     * Animates the PiP from stashed state into un-stashed, popping it out from the edge.
+     */
+    void animateToUnStashedBounds(Rect unstashedBounds) {
+        resizeAndAnimatePipUnchecked(unstashedBounds, UNSTASH_DURATION);
+    }
+
+    /**
+     * Animates the PiP to offset it from the IME or shelf.
+     */
+    void animateToOffset(Rect originalBounds, int offset) {
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: animateToOffset: originalBounds=%s offset=%s"
+                            + " callers=\n%s", TAG, originalBounds, offset,
+                    Debug.getCallers(5, "    "));
+        }
+        cancelPhysicsAnimation();
+        /*
+        mPipTaskOrganizer.scheduleOffsetPip(originalBounds, offset, SHIFT_DURATION,
+                mUpdateBoundsCallback);
+         */
+    }
+
+    /**
+     * Cancels all existing animations.
+     */
+    private void cancelPhysicsAnimation() {
+        mTemporaryBoundsPhysicsAnimator.cancel();
+        mPipBoundsState.getMotionBoundsState().onPhysicsAnimationEnded();
+        mSpringingToTouch = false;
+    }
+
+    /** Set new fling configs whose min/max values respect the given movement bounds. */
+    private void rebuildFlingConfigs() {
+        mFlingConfigX = new PhysicsAnimator.FlingConfig(DEFAULT_FRICTION,
+                mPipBoundsState.getMovementBounds().left,
+                mPipBoundsState.getMovementBounds().right);
+        mFlingConfigY = new PhysicsAnimator.FlingConfig(DEFAULT_FRICTION,
+                mPipBoundsState.getMovementBounds().top,
+                mPipBoundsState.getMovementBounds().bottom);
+        final Rect insetBounds = mPipBoundsState.getDisplayLayout().stableInsets();
+        mStashConfigX = new PhysicsAnimator.FlingConfig(
+                DEFAULT_FRICTION,
+                mPipBoundsState.getStashOffset() - mPipBoundsState.getBounds().width()
+                        + insetBounds.left,
+                mPipBoundsState.getDisplayBounds().right - mPipBoundsState.getStashOffset()
+                        - insetBounds.right);
+    }
+
+    private void startBoundsAnimator(float toX, float toY) {
+        startBoundsAnimator(toX, toY, null /* postBoundsUpdateCallback */);
+    }
+
+    /**
+     * Starts the physics animator which will update the animated PIP bounds using physics
+     * animations, as well as the TimeAnimator which will apply those bounds to PIP.
+     *
+     * This will also add end actions to the bounds animator that cancel the TimeAnimator and update
+     * the 'real' bounds to equal the final animated bounds.
+     *
+     * If one wishes to supply a callback after all the 'real' bounds update has happened,
+     * pass @param postBoundsUpdateCallback.
+     */
+    private void startBoundsAnimator(float toX, float toY, Runnable postBoundsUpdateCallback) {
+        if (!mSpringingToTouch) {
+            cancelPhysicsAnimation();
+        }
+
+        setAnimatingToBounds(new Rect(
+                (int) toX,
+                (int) toY,
+                (int) toX + getBounds().width(),
+                (int) toY + getBounds().height()));
+
+        if (!mTemporaryBoundsPhysicsAnimator.isRunning()) {
+            if (mPipPerfHintController != null) {
+                // Start a high perf session with a timeout callback.
+                mPipHighPerfSession = mPipPerfHintController.startSession(
+                        this::onHighPerfSessionTimeout, "startBoundsAnimator");
+            }
+            if (postBoundsUpdateCallback != null) {
+                mTemporaryBoundsPhysicsAnimator
+                        .addUpdateListener(mResizePipUpdateListener)
+                        .withEndActions(this::onBoundsPhysicsAnimationEnd,
+                                postBoundsUpdateCallback);
+            } else {
+                mTemporaryBoundsPhysicsAnimator
+                        .addUpdateListener(mResizePipUpdateListener)
+                        .withEndActions(this::onBoundsPhysicsAnimationEnd);
+            }
+        }
+
+        mTemporaryBoundsPhysicsAnimator.start();
+    }
+
+    /**
+     * Notify that PIP was released in the dismiss target and will be animated out and dismissed
+     * shortly.
+     */
+    void notifyDismissalPending() {
+        mDismissalPending = true;
+    }
+
+    private void onBoundsPhysicsAnimationEnd() {
+        // The physics animation ended, though we may not necessarily be done animating, such as
+        // when we're still dragging after moving out of the magnetic target.
+        if (!mDismissalPending
+                && !mSpringingToTouch
+                && !mMagnetizedPip.getObjectStuckToTarget()) {
+            // All motion operations have actually finished.
+            mPipBoundsState.setBounds(
+                    mPipBoundsState.getMotionBoundsState().getBoundsInMotion());
+            mPipBoundsState.getMotionBoundsState().onAllAnimationsEnded();
+            if (!mDismissalPending) {
+                // do not schedule resize if PiP is dismissing, which may cause app re-open to
+                // mBounds instead of its normal bounds.
+                // mPipTaskOrganizer.scheduleFinishResizePip(getBounds());
+            }
+        }
+        mPipBoundsState.getMotionBoundsState().onPhysicsAnimationEnded();
+        mSpringingToTouch = false;
+        mDismissalPending = false;
+        cleanUpHighPerfSessionMaybe();
+    }
+
+    /**
+     * Notifies the floating coordinator that we're moving, and sets the animating to bounds so
+     * we return these bounds from
+     * {@link FloatingContentCoordinator.FloatingContent#getFloatingBoundsOnScreen()}.
+     */
+    private void setAnimatingToBounds(Rect bounds) {
+        mPipBoundsState.getMotionBoundsState().setAnimatingToBounds(bounds);
+        mFloatingContentCoordinator.onContentMoved(this);
+    }
+
+    /**
+     * Directly resizes the PiP to the given {@param bounds}.
+     */
+    private void resizePipUnchecked(Rect toBounds) {
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: resizePipUnchecked: toBounds=%s"
+                            + " callers=\n%s", TAG, toBounds, Debug.getCallers(5, "    "));
+        }
+        if (!toBounds.equals(getBounds())) {
+            // mPipTaskOrganizer.scheduleResizePip(toBounds, mUpdateBoundsCallback);
+        }
+    }
+
+    /**
+     * Directly resizes the PiP to the given {@param bounds}.
+     */
+    private void resizeAndAnimatePipUnchecked(Rect toBounds, int duration) {
+        if (DEBUG) {
+            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: resizeAndAnimatePipUnchecked: toBounds=%s"
+                            + " duration=%s callers=\n%s", TAG, toBounds, duration,
+                    Debug.getCallers(5, "    "));
+        }
+
+        // Intentionally resize here even if the current bounds match the destination bounds.
+        // This is so all the proper callbacks are performed.
+
+        // mPipTaskOrganizer.scheduleAnimateResizePip(toBounds, duration,
+        //         TRANSITION_DIRECTION_EXPAND_OR_UNEXPAND, null /* updateBoundsCallback */);
+        // setAnimatingToBounds(toBounds);
+    }
+
+    /**
+     * Returns a MagnetizedObject wrapper for PIP's animated bounds. This is provided to the
+     * magnetic dismiss target so it can calculate PIP's size and position.
+     */
+    MagnetizedObject<Rect> getMagnetizedPip() {
+        if (mMagnetizedPip == null) {
+            mMagnetizedPip = new MagnetizedObject<Rect>(
+                    mContext, mPipBoundsState.getMotionBoundsState().getBoundsInMotion(),
+                    FloatProperties.RECT_X, FloatProperties.RECT_Y) {
+                @Override
+                public float getWidth(@NonNull Rect animatedPipBounds) {
+                    return animatedPipBounds.width();
+                }
+
+                @Override
+                public float getHeight(@NonNull Rect animatedPipBounds) {
+                    return animatedPipBounds.height();
+                }
+
+                @Override
+                public void getLocationOnScreen(
+                        @NonNull Rect animatedPipBounds, @NonNull int[] loc) {
+                    loc[0] = animatedPipBounds.left;
+                    loc[1] = animatedPipBounds.top;
+                }
+            };
+            mMagnetizedPip.setFlingToTargetEnabled(false);
+        }
+
+        return mMagnetizedPip;
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java
new file mode 100644
index 0000000..04cf350
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipResizeGestureHandler.java
@@ -0,0 +1,538 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.pip2.phone;
+
+import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_NONE;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.hardware.input.InputManager;
+import android.os.Looper;
+import android.view.BatchedInputEventReceiver;
+import android.view.Choreographer;
+import android.view.InputChannel;
+import android.view.InputEvent;
+import android.view.InputEventReceiver;
+import android.view.InputMonitor;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
+import com.android.wm.shell.common.pip.PipBoundsState;
+import com.android.wm.shell.common.pip.PipPerfHintController;
+import com.android.wm.shell.common.pip.PipPinchResizingAlgorithm;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
+
+import java.io.PrintWriter;
+import java.util.function.Consumer;
+
+/**
+ * Helper on top of PipTouchHandler that handles inputs OUTSIDE of the PIP window, which is used to
+ * trigger dynamic resize.
+ */
+public class PipResizeGestureHandler {
+
+    private static final String TAG = "PipResizeGestureHandler";
+    private static final int PINCH_RESIZE_SNAP_DURATION = 250;
+    private static final float PINCH_RESIZE_AUTO_MAX_RATIO = 0.9f;
+
+    private final Context mContext;
+    private final PipBoundsAlgorithm mPipBoundsAlgorithm;
+    private final PipBoundsState mPipBoundsState;
+    private final PipTouchState mPipTouchState;
+    private final PhonePipMenuController mPhonePipMenuController;
+    private final PipUiEventLogger mPipUiEventLogger;
+    private final PipPinchResizingAlgorithm mPinchResizingAlgorithm;
+    private final int mDisplayId;
+    private final ShellExecutor mMainExecutor;
+
+    private final PointF mDownPoint = new PointF();
+    private final PointF mDownSecondPoint = new PointF();
+    private final PointF mLastPoint = new PointF();
+    private final PointF mLastSecondPoint = new PointF();
+    private final Point mMaxSize = new Point();
+    private final Point mMinSize = new Point();
+    private final Rect mLastResizeBounds = new Rect();
+    private final Rect mUserResizeBounds = new Rect();
+    private final Rect mDownBounds = new Rect();
+    private final Runnable mUpdateMovementBoundsRunnable;
+    private final Consumer<Rect> mUpdateResizeBoundsCallback;
+
+    private float mTouchSlop;
+
+    private boolean mAllowGesture;
+    private boolean mIsAttached;
+    private boolean mIsEnabled;
+    private boolean mEnablePinchResize;
+    private boolean mIsSysUiStateValid;
+    private boolean mThresholdCrossed;
+    private boolean mOngoingPinchToResize = false;
+    private float mAngle = 0;
+    int mFirstIndex = -1;
+    int mSecondIndex = -1;
+
+    private InputMonitor mInputMonitor;
+    private InputEventReceiver mInputEventReceiver;
+
+    @Nullable
+    private final PipPerfHintController mPipPerfHintController;
+
+    @Nullable
+    private PipPerfHintController.PipHighPerfSession mPipHighPerfSession;
+
+    private int mCtrlType;
+    private int mOhmOffset;
+
+    public PipResizeGestureHandler(Context context, PipBoundsAlgorithm pipBoundsAlgorithm,
+            PipBoundsState pipBoundsState, PipTouchState pipTouchState,
+            Runnable updateMovementBoundsRunnable,
+            PipUiEventLogger pipUiEventLogger, PhonePipMenuController menuActivityController,
+            ShellExecutor mainExecutor, @Nullable PipPerfHintController pipPerfHintController) {
+        mContext = context;
+        mDisplayId = context.getDisplayId();
+        mMainExecutor = mainExecutor;
+        mPipPerfHintController = pipPerfHintController;
+        mPipBoundsAlgorithm = pipBoundsAlgorithm;
+        mPipBoundsState = pipBoundsState;
+        mPipTouchState = pipTouchState;
+        mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable;
+        mPhonePipMenuController = menuActivityController;
+        mPipUiEventLogger = pipUiEventLogger;
+        mPinchResizingAlgorithm = new PipPinchResizingAlgorithm();
+
+        mUpdateResizeBoundsCallback = (rect) -> {
+            mUserResizeBounds.set(rect);
+            // mMotionHelper.synchronizePinnedStackBounds();
+            mUpdateMovementBoundsRunnable.run();
+            resetState();
+        };
+    }
+
+    void init() {
+        mContext.getDisplay().getRealSize(mMaxSize);
+        reloadResources();
+
+        final Resources res = mContext.getResources();
+        mEnablePinchResize = res.getBoolean(R.bool.config_pipEnablePinchResize);
+    }
+
+    void onConfigurationChanged() {
+        reloadResources();
+    }
+
+    /**
+     * Called when SysUI state changed.
+     *
+     * @param isSysUiStateValid Is SysUI valid or not.
+     */
+    public void onSystemUiStateChanged(boolean isSysUiStateValid) {
+        mIsSysUiStateValid = isSysUiStateValid;
+    }
+
+    private void reloadResources() {
+        mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
+    }
+
+    private void disposeInputChannel() {
+        if (mInputEventReceiver != null) {
+            mInputEventReceiver.dispose();
+            mInputEventReceiver = null;
+        }
+        if (mInputMonitor != null) {
+            mInputMonitor.dispose();
+            mInputMonitor = null;
+        }
+    }
+
+    void onActivityPinned() {
+        mIsAttached = true;
+        updateIsEnabled();
+    }
+
+    void onActivityUnpinned() {
+        mIsAttached = false;
+        mUserResizeBounds.setEmpty();
+        updateIsEnabled();
+    }
+
+    private void updateIsEnabled() {
+        boolean isEnabled = mIsAttached;
+        if (isEnabled == mIsEnabled) {
+            return;
+        }
+        mIsEnabled = isEnabled;
+        disposeInputChannel();
+
+        if (mIsEnabled) {
+            // Register input event receiver
+            mInputMonitor = mContext.getSystemService(InputManager.class).monitorGestureInput(
+                    "pip-resize", mDisplayId);
+            try {
+                mMainExecutor.executeBlocking(() -> {
+                    mInputEventReceiver = new PipResizeInputEventReceiver(
+                            mInputMonitor.getInputChannel(), Looper.myLooper());
+                });
+            } catch (InterruptedException e) {
+                throw new RuntimeException("Failed to create input event receiver", e);
+            }
+        }
+    }
+
+    @VisibleForTesting
+    void onInputEvent(InputEvent ev) {
+        if (!mEnablePinchResize) {
+            // No need to handle anything if neither form of resizing is enabled.
+            return;
+        }
+
+        if (!mPipTouchState.getAllowInputEvents()) {
+            // No need to handle anything if touches are not enabled
+            return;
+        }
+
+        // Don't allow resize when PiP is stashed.
+        if (mPipBoundsState.isStashed()) {
+            return;
+        }
+
+        if (ev instanceof MotionEvent) {
+            MotionEvent mv = (MotionEvent) ev;
+            int action = mv.getActionMasked();
+            final Rect pipBounds = mPipBoundsState.getBounds();
+            if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+                if (!pipBounds.contains((int) mv.getRawX(), (int) mv.getRawY())
+                        && mPhonePipMenuController.isMenuVisible()) {
+                    mPhonePipMenuController.hideMenu();
+                }
+            }
+
+            if (mEnablePinchResize && mOngoingPinchToResize) {
+                onPinchResize(mv);
+            }
+        }
+    }
+
+    /**
+     * Checks if there is currently an on-going gesture, either drag-resize or pinch-resize.
+     */
+    public boolean hasOngoingGesture() {
+        return mCtrlType != CTRL_NONE || mOngoingPinchToResize;
+    }
+
+    public boolean isUsingPinchToZoom() {
+        return mEnablePinchResize;
+    }
+
+    public boolean isResizing() {
+        return mAllowGesture;
+    }
+
+    boolean willStartResizeGesture(MotionEvent ev) {
+        if (isInValidSysUiState()) {
+            if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
+                if (mEnablePinchResize && ev.getPointerCount() == 2) {
+                    onPinchResize(ev);
+                    mOngoingPinchToResize = mAllowGesture;
+                    return mAllowGesture;
+                }
+            }
+        }
+        return false;
+    }
+
+    private boolean isInValidSysUiState() {
+        return mIsSysUiStateValid;
+    }
+
+    private void onHighPerfSessionTimeout(PipPerfHintController.PipHighPerfSession session) {}
+
+    private void cleanUpHighPerfSessionMaybe() {
+        if (mPipHighPerfSession != null) {
+            // Close the high perf session once pointer interactions are over;
+            mPipHighPerfSession.close();
+            mPipHighPerfSession = null;
+        }
+    }
+
+    @VisibleForTesting
+    void onPinchResize(MotionEvent ev) {
+        int action = ev.getActionMasked();
+
+        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
+            mFirstIndex = -1;
+            mSecondIndex = -1;
+            mAllowGesture = false;
+            finishResize();
+            cleanUpHighPerfSessionMaybe();
+        }
+
+        if (ev.getPointerCount() != 2) {
+            return;
+        }
+
+        final Rect pipBounds = mPipBoundsState.getBounds();
+        if (action == MotionEvent.ACTION_POINTER_DOWN) {
+            if (mFirstIndex == -1 && mSecondIndex == -1
+                    && pipBounds.contains((int) ev.getRawX(0), (int) ev.getRawY(0))
+                    && pipBounds.contains((int) ev.getRawX(1), (int) ev.getRawY(1))) {
+                mAllowGesture = true;
+                mFirstIndex = 0;
+                mSecondIndex = 1;
+                mDownPoint.set(ev.getRawX(mFirstIndex), ev.getRawY(mFirstIndex));
+                mDownSecondPoint.set(ev.getRawX(mSecondIndex), ev.getRawY(mSecondIndex));
+                mDownBounds.set(pipBounds);
+
+                mLastPoint.set(mDownPoint);
+                mLastSecondPoint.set(mLastSecondPoint);
+                mLastResizeBounds.set(mDownBounds);
+
+                // start the high perf session as the second pointer gets detected
+                if (mPipPerfHintController != null) {
+                    mPipHighPerfSession = mPipPerfHintController.startSession(
+                            this::onHighPerfSessionTimeout, "onPinchResize");
+                }
+            }
+        }
+
+        if (action == MotionEvent.ACTION_MOVE) {
+            if (mFirstIndex == -1 || mSecondIndex == -1) {
+                return;
+            }
+
+            float x0 = ev.getRawX(mFirstIndex);
+            float y0 = ev.getRawY(mFirstIndex);
+            float x1 = ev.getRawX(mSecondIndex);
+            float y1 = ev.getRawY(mSecondIndex);
+            mLastPoint.set(x0, y0);
+            mLastSecondPoint.set(x1, y1);
+
+            // Capture inputs
+            if (!mThresholdCrossed
+                    && (distanceBetween(mDownSecondPoint, mLastSecondPoint) > mTouchSlop
+                            || distanceBetween(mDownPoint, mLastPoint) > mTouchSlop)) {
+                pilferPointers();
+                mThresholdCrossed = true;
+                // Reset the down to begin resizing from this point
+                mDownPoint.set(mLastPoint);
+                mDownSecondPoint.set(mLastSecondPoint);
+
+                if (mPhonePipMenuController.isMenuVisible()) {
+                    mPhonePipMenuController.hideMenu();
+                }
+            }
+
+            if (mThresholdCrossed) {
+                mAngle = mPinchResizingAlgorithm.calculateBoundsAndAngle(mDownPoint,
+                        mDownSecondPoint, mLastPoint, mLastSecondPoint, mMinSize, mMaxSize,
+                        mDownBounds, mLastResizeBounds);
+
+                /*
+                mPipTaskOrganizer.scheduleUserResizePip(mDownBounds, mLastResizeBounds,
+                        mAngle, null);
+                 */
+                mPipBoundsState.setHasUserResizedPip(true);
+            }
+        }
+    }
+
+    private void snapToMovementBoundsEdge(Rect bounds, Rect movementBounds) {
+        final int leftEdge = bounds.left;
+
+
+        final int fromLeft = Math.abs(leftEdge - movementBounds.left);
+        final int fromRight = Math.abs(movementBounds.right - leftEdge);
+
+        // The PIP will be snapped to either the right or left edge, so calculate which one
+        // is closest to the current position.
+        final int newLeft = fromLeft < fromRight
+                ? movementBounds.left : movementBounds.right;
+
+        bounds.offsetTo(newLeft, mLastResizeBounds.top);
+    }
+
+    /**
+     * Resizes the pip window and updates user-resized bounds.
+     *
+     * @param bounds target bounds to resize to
+     * @param snapFraction snap fraction to apply after resizing
+     */
+    void userResizeTo(Rect bounds, float snapFraction) {
+        Rect finalBounds = new Rect(bounds);
+
+        // get the current movement bounds
+        final Rect movementBounds = mPipBoundsAlgorithm.getMovementBounds(finalBounds);
+
+        // snap the target bounds to the either left or right edge, by choosing the closer one
+        snapToMovementBoundsEdge(finalBounds, movementBounds);
+
+        // apply the requested snap fraction onto the target bounds
+        mPipBoundsAlgorithm.applySnapFraction(finalBounds, snapFraction);
+
+        // resize from current bounds to target bounds without animation
+        // mPipTaskOrganizer.scheduleUserResizePip(mPipBoundsState.getBounds(), finalBounds, null);
+        // set the flag that pip has been resized
+        mPipBoundsState.setHasUserResizedPip(true);
+
+        // finish the resize operation and update the state of the bounds
+        // mPipTaskOrganizer.scheduleFinishResizePip(finalBounds, mUpdateResizeBoundsCallback);
+    }
+
+    private void finishResize() {
+        if (!mLastResizeBounds.isEmpty()) {
+            // Pinch-to-resize needs to re-calculate snap fraction and animate to the snapped
+            // position correctly. Drag-resize does not need to move, so just finalize resize.
+            if (mOngoingPinchToResize) {
+                final Rect startBounds = new Rect(mLastResizeBounds);
+                // If user resize is pretty close to max size, just auto resize to max.
+                if (mLastResizeBounds.width() >= PINCH_RESIZE_AUTO_MAX_RATIO * mMaxSize.x
+                        || mLastResizeBounds.height() >= PINCH_RESIZE_AUTO_MAX_RATIO * mMaxSize.y) {
+                    resizeRectAboutCenter(mLastResizeBounds, mMaxSize.x, mMaxSize.y);
+                }
+
+                // If user resize is smaller than min size, auto resize to min
+                if (mLastResizeBounds.width() < mMinSize.x
+                        || mLastResizeBounds.height() < mMinSize.y) {
+                    resizeRectAboutCenter(mLastResizeBounds, mMinSize.x, mMinSize.y);
+                }
+
+                // get the current movement bounds
+                final Rect movementBounds = mPipBoundsAlgorithm
+                        .getMovementBounds(mLastResizeBounds);
+
+                // snap mLastResizeBounds to the correct edge based on movement bounds
+                snapToMovementBoundsEdge(mLastResizeBounds, movementBounds);
+
+                final float snapFraction = mPipBoundsAlgorithm.getSnapFraction(
+                        mLastResizeBounds, movementBounds);
+                mPipBoundsAlgorithm.applySnapFraction(mLastResizeBounds, snapFraction);
+
+                // disable any touch events beyond resizing too
+                mPipTouchState.setAllowInputEvents(false);
+
+                /*
+                mPipTaskOrganizer.scheduleAnimateResizePip(startBounds, mLastResizeBounds,
+                        PINCH_RESIZE_SNAP_DURATION, mAngle, mUpdateResizeBoundsCallback, () -> {
+                            // enable touch events
+                            mPipTouchState.setAllowInputEvents(true);
+                        });
+                 */
+            } else {
+                /*
+                mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds,
+                        TRANSITION_DIRECTION_USER_RESIZE,
+                        mUpdateResizeBoundsCallback);
+                 */
+            }
+            final float magnetRadiusPercent = (float) mLastResizeBounds.width() / mMinSize.x / 2.f;
+            mPipUiEventLogger.log(
+                    PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_RESIZE);
+        } else {
+            resetState();
+        }
+    }
+
+    private void resetState() {
+        mCtrlType = CTRL_NONE;
+        mAngle = 0;
+        mOngoingPinchToResize = false;
+        mAllowGesture = false;
+        mThresholdCrossed = false;
+    }
+
+    void setUserResizeBounds(Rect bounds) {
+        mUserResizeBounds.set(bounds);
+    }
+
+    void invalidateUserResizeBounds() {
+        mUserResizeBounds.setEmpty();
+    }
+
+    Rect getUserResizeBounds() {
+        return mUserResizeBounds;
+    }
+
+    @VisibleForTesting
+    Rect getLastResizeBounds() {
+        return mLastResizeBounds;
+    }
+
+    @VisibleForTesting
+    void pilferPointers() {
+        mInputMonitor.pilferPointers();
+    }
+
+
+    void updateMaxSize(int maxX, int maxY) {
+        mMaxSize.set(maxX, maxY);
+    }
+
+    void updateMinSize(int minX, int minY) {
+        mMinSize.set(minX, minY);
+    }
+
+    void setOhmOffset(int offset) {
+        mOhmOffset = offset;
+    }
+
+    private float distanceBetween(PointF p1, PointF p2) {
+        return (float) Math.hypot(p2.x - p1.x, p2.y - p1.y);
+    }
+
+    private void resizeRectAboutCenter(Rect rect, int w, int h) {
+        int cx = rect.centerX();
+        int cy = rect.centerY();
+        int l = cx - w / 2;
+        int r = l + w;
+        int t = cy - h / 2;
+        int b = t + h;
+        rect.set(l, t, r, b);
+    }
+
+    /**
+     * Dumps the {@link PipResizeGestureHandler} state.
+     */
+    public void dump(PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "mAllowGesture=" + mAllowGesture);
+        pw.println(innerPrefix + "mIsAttached=" + mIsAttached);
+        pw.println(innerPrefix + "mIsEnabled=" + mIsEnabled);
+        pw.println(innerPrefix + "mEnablePinchResize=" + mEnablePinchResize);
+        pw.println(innerPrefix + "mThresholdCrossed=" + mThresholdCrossed);
+        pw.println(innerPrefix + "mOhmOffset=" + mOhmOffset);
+        pw.println(innerPrefix + "mMinSize=" + mMinSize);
+        pw.println(innerPrefix + "mMaxSize=" + mMaxSize);
+    }
+
+    class PipResizeInputEventReceiver extends BatchedInputEventReceiver {
+        PipResizeInputEventReceiver(InputChannel channel, Looper looper) {
+            super(channel, looper, Choreographer.getInstance());
+        }
+
+        public void onInputEvent(InputEvent event) {
+            PipResizeGestureHandler.this.onInputEvent(event);
+            finishInputEvent(event, true);
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
index 6665013..b4ca7df 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipScheduler.java
@@ -21,6 +21,7 @@
 import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP;
 
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -30,9 +31,11 @@
 import android.window.WindowContainerTransaction;
 
 import androidx.annotation.IntDef;
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.core.content.ContextCompat;
 
+import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.pip.PipBoundsState;
 import com.android.wm.shell.common.pip.PipUtils;
@@ -52,6 +55,7 @@
     private final Context mContext;
     private final PipBoundsState mPipBoundsState;
     private final ShellExecutor mMainExecutor;
+    private final ShellTaskOrganizer mShellTaskOrganizer;
     private PipSchedulerReceiver mSchedulerReceiver;
     private PipTransitionController mPipTransitionController;
 
@@ -66,6 +70,16 @@
     // true if Launcher has started swipe PiP to home animation
     private boolean mInSwipePipToHomeTransition;
 
+    // Overlay leash potentially used during swipe PiP to home transition;
+    // if null while mInSwipePipToHomeTransition is true, then srcRectHint was invalid.
+    @Nullable
+    SurfaceControl mSwipePipToHomeOverlay;
+
+    // App bounds used when as a starting point to swipe PiP to home animation in Launcher;
+    // these are also used to calculate the app icon overlay buffer size.
+    @NonNull
+    final Rect mSwipePipToHomeAppBounds = new Rect();
+
     /**
      * Temporary PiP CUJ codes to schedule PiP related transitions directly from Shell.
      * This is used for a broadcast receiver to resolve intents. This should be removed once
@@ -101,11 +115,14 @@
         }
     }
 
-    public PipScheduler(Context context, PipBoundsState pipBoundsState,
-            ShellExecutor mainExecutor) {
+    public PipScheduler(Context context,
+            PipBoundsState pipBoundsState,
+            ShellExecutor mainExecutor,
+            ShellTaskOrganizer shellTaskOrganizer) {
         mContext = context;
         mPipBoundsState = pipBoundsState;
         mMainExecutor = mainExecutor;
+        mShellTaskOrganizer = shellTaskOrganizer;
 
         if (PipUtils.isPip2ExperimentEnabled()) {
             // temporary broadcast receiver to initiate exit PiP via expand
@@ -115,6 +132,10 @@
         }
     }
 
+    ShellExecutor getMainExecutor() {
+        return mMainExecutor;
+    }
+
     void setPipTransitionController(PipTransitionController pipTransitionController) {
         mPipTransitionController = pipTransitionController;
     }
@@ -171,6 +192,24 @@
         mPipTransitionController.startResizeTransition(wct, onFinishResizeCallback);
     }
 
+    void onSwipePipToHomeAnimationStart(int taskId, ComponentName componentName,
+            Rect destinationBounds, SurfaceControl overlay, Rect appBounds) {
+        mInSwipePipToHomeTransition = true;
+        mSwipePipToHomeOverlay = overlay;
+        mSwipePipToHomeAppBounds.set(appBounds);
+        if (overlay != null) {
+            // Shell transitions might use a root animation leash, which will be removed when
+            // the Recents transition is finished. Launcher attaches the overlay leash to this
+            // animation target leash; thus, we need to reparent it to the actual Task surface now.
+            // PipTransition is responsible to fade it out and cleanup when finishing the enter PIP
+            // transition.
+            SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
+            mShellTaskOrganizer.reparentChildSurfaceToTask(taskId, overlay, tx);
+            tx.setLayer(overlay, Integer.MAX_VALUE);
+            tx.apply();
+        }
+    }
+
     void setInSwipePipToHomeTransition(boolean inSwipePipToHome) {
         mInSwipePipToHomeTransition = inSwipePipToHome;
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchGesture.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchGesture.java
new file mode 100644
index 0000000..efa5fc8
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchGesture.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.pip2.phone;
+
+/**
+ * A generic interface for a touch gesture.
+ */
+public abstract class PipTouchGesture {
+
+    /**
+     * Handle the touch down.
+     */
+    public void onDown(PipTouchState touchState) {}
+
+    /**
+     * Handle the touch move, and return whether the event was consumed.
+     */
+    public boolean onMove(PipTouchState touchState) {
+        return false;
+    }
+
+    /**
+     * Handle the touch up, and return whether the gesture was consumed.
+     */
+    public boolean onUp(PipTouchState touchState) {
+        return false;
+    }
+
+    /**
+     * Cleans up the high performance hint session if needed.
+     */
+    public void cleanUpHighPerfSessionMaybe() {}
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
new file mode 100644
index 0000000..cc8e3e0
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchHandler.java
@@ -0,0 +1,1081 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.pip2.phone;
+
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.PIP_STASHING;
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.PIP_STASH_MINIMUM_VELOCITY_THRESHOLD;
+import static com.android.wm.shell.common.pip.PipBoundsState.STASH_TYPE_LEFT;
+import static com.android.wm.shell.common.pip.PipBoundsState.STASH_TYPE_NONE;
+import static com.android.wm.shell.common.pip.PipBoundsState.STASH_TYPE_RIGHT;
+import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
+import static com.android.wm.shell.pip2.phone.PhonePipMenuController.MENU_STATE_FULL;
+import static com.android.wm.shell.pip2.phone.PhonePipMenuController.MENU_STATE_NONE;
+import static com.android.wm.shell.pip2.phone.PipMenuView.ANIM_TYPE_NONE;
+import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.provider.DeviceConfig;
+import android.util.Size;
+import android.view.DisplayCutout;
+import android.view.InputEvent;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.R;
+import com.android.wm.shell.common.FloatingContentCoordinator;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.common.pip.PipBoundsAlgorithm;
+import com.android.wm.shell.common.pip.PipBoundsState;
+import com.android.wm.shell.common.pip.PipDoubleTapHelper;
+import com.android.wm.shell.common.pip.PipPerfHintController;
+import com.android.wm.shell.common.pip.PipUiEventLogger;
+import com.android.wm.shell.common.pip.PipUtils;
+import com.android.wm.shell.common.pip.SizeSpecSource;
+import com.android.wm.shell.pip.PipAnimationController;
+import com.android.wm.shell.pip.PipTransitionController;
+import com.android.wm.shell.sysui.ShellInit;
+
+import java.io.PrintWriter;
+import java.util.Optional;
+
+/**
+ * Manages all the touch handling for PIP on the Phone, including moving, dismissing and expanding
+ * the PIP.
+ */
+public class PipTouchHandler {
+
+    private static final String TAG = "PipTouchHandler";
+    private static final float DEFAULT_STASH_VELOCITY_THRESHOLD = 18000.f;
+
+    // Allow PIP to resize to a slightly bigger state upon touch
+    private boolean mEnableResize;
+    private final Context mContext;
+    private final PipBoundsAlgorithm mPipBoundsAlgorithm;
+    @NonNull private final PipBoundsState mPipBoundsState;
+    @NonNull private final SizeSpecSource mSizeSpecSource;
+    private final PipUiEventLogger mPipUiEventLogger;
+    private final PipDismissTargetHandler mPipDismissTargetHandler;
+    private final ShellExecutor mMainExecutor;
+    @Nullable private final PipPerfHintController mPipPerfHintController;
+
+    private PipResizeGestureHandler mPipResizeGestureHandler;
+
+    private final PhonePipMenuController mMenuController;
+    private final AccessibilityManager mAccessibilityManager;
+
+    /**
+     * Whether PIP stash is enabled or not. When enabled, if the user flings toward the edge of the
+     * screen, it will be shown in "stashed" mode, where PIP will only show partially.
+     */
+    private boolean mEnableStash = true;
+
+    private float mStashVelocityThreshold;
+
+    // The reference inset bounds, used to determine the dismiss fraction
+    private final Rect mInsetBounds = new Rect();
+
+    // Used to workaround an issue where the WM rotation happens before we are notified, allowing
+    // us to send stale bounds
+    private int mDeferResizeToNormalBoundsUntilRotation = -1;
+    private int mDisplayRotation;
+
+    // Behaviour states
+    private int mMenuState = MENU_STATE_NONE;
+    private boolean mIsImeShowing;
+    private int mImeHeight;
+    private int mImeOffset;
+    private boolean mIsShelfShowing;
+    private int mShelfHeight;
+    private int mMovementBoundsExtraOffsets;
+    private int mBottomOffsetBufferPx;
+    private float mSavedSnapFraction = -1f;
+    private boolean mSendingHoverAccessibilityEvents;
+    private boolean mMovementWithinDismiss;
+
+    // Touch state
+    private final PipTouchState mTouchState;
+    private final FloatingContentCoordinator mFloatingContentCoordinator;
+    private PipMotionHelper mMotionHelper;
+    private PipTouchGesture mGesture;
+
+    // Temp vars
+    private final Rect mTmpBounds = new Rect();
+
+    /**
+     * A listener for the PIP menu activity.
+     */
+    private class PipMenuListener implements PhonePipMenuController.Listener {
+        @Override
+        public void onPipMenuStateChangeStart(int menuState, boolean resize, Runnable callback) {
+            PipTouchHandler.this.onPipMenuStateChangeStart(menuState, resize, callback);
+        }
+
+        @Override
+        public void onPipMenuStateChangeFinish(int menuState) {
+            setMenuState(menuState);
+        }
+
+        @Override
+        public void onPipExpand() {
+            mMotionHelper.expandLeavePip(false /* skipAnimation */);
+        }
+
+        @Override
+        public void onPipDismiss() {
+            mTouchState.removeDoubleTapTimeoutCallback();
+            mMotionHelper.dismissPip();
+        }
+
+        @Override
+        public void onPipShowMenu() {
+            mMenuController.showMenu(MENU_STATE_FULL, mPipBoundsState.getBounds(),
+                    true /* allowMenuTimeout */, willResizeMenu(), shouldShowResizeHandle());
+        }
+    }
+
+    @SuppressLint("InflateParams")
+    public PipTouchHandler(Context context,
+            ShellInit shellInit,
+            PhonePipMenuController menuController,
+            PipBoundsAlgorithm pipBoundsAlgorithm,
+            @NonNull PipBoundsState pipBoundsState,
+            @NonNull SizeSpecSource sizeSpecSource,
+            PipMotionHelper pipMotionHelper,
+            FloatingContentCoordinator floatingContentCoordinator,
+            PipUiEventLogger pipUiEventLogger,
+            ShellExecutor mainExecutor,
+            Optional<PipPerfHintController> pipPerfHintControllerOptional) {
+        mContext = context;
+        mMainExecutor = mainExecutor;
+        mPipPerfHintController = pipPerfHintControllerOptional.orElse(null);
+        mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
+        mPipBoundsAlgorithm = pipBoundsAlgorithm;
+        mPipBoundsState = pipBoundsState;
+        mSizeSpecSource = sizeSpecSource;
+        mMenuController = menuController;
+        mPipUiEventLogger = pipUiEventLogger;
+        mFloatingContentCoordinator = floatingContentCoordinator;
+        mMenuController.addListener(new PipMenuListener());
+        mGesture = new DefaultPipTouchGesture();
+        mMotionHelper = pipMotionHelper;
+        mPipDismissTargetHandler = new PipDismissTargetHandler(context, pipUiEventLogger,
+                mMotionHelper, mainExecutor);
+        mTouchState = new PipTouchState(ViewConfiguration.get(context),
+                () -> {
+                    if (mPipBoundsState.isStashed()) {
+                        animateToUnStashedState();
+                        mPipUiEventLogger.log(
+                                PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_STASH_UNSTASHED);
+                        mPipBoundsState.setStashed(STASH_TYPE_NONE);
+                    } else {
+                        mMenuController.showMenuWithPossibleDelay(MENU_STATE_FULL,
+                                mPipBoundsState.getBounds(), true /* allowMenuTimeout */,
+                                willResizeMenu(),
+                                shouldShowResizeHandle());
+                    }
+                },
+                menuController::hideMenu,
+                mainExecutor);
+        mPipResizeGestureHandler =
+                new PipResizeGestureHandler(context, pipBoundsAlgorithm, pipBoundsState,
+                        mTouchState, this::updateMovementBounds, pipUiEventLogger,
+                        menuController, mainExecutor, mPipPerfHintController);
+
+        if (PipUtils.isPip2ExperimentEnabled()) {
+            shellInit.addInitCallback(this::onInit, this);
+        }
+    }
+
+    /**
+     * Called when the touch handler is initialized.
+     */
+    public void onInit() {
+        Resources res = mContext.getResources();
+        mEnableResize = res.getBoolean(R.bool.config_pipEnableResizeForMenu);
+        reloadResources();
+
+        mMotionHelper.init();
+        mPipResizeGestureHandler.init();
+        mPipDismissTargetHandler.init();
+
+        mEnableStash = DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                PIP_STASHING,
+                /* defaultValue = */ true);
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
+                mMainExecutor,
+                properties -> {
+                    if (properties.getKeyset().contains(PIP_STASHING)) {
+                        mEnableStash = properties.getBoolean(
+                                PIP_STASHING, /* defaultValue = */ true);
+                    }
+                });
+        mStashVelocityThreshold = DeviceConfig.getFloat(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                PIP_STASH_MINIMUM_VELOCITY_THRESHOLD,
+                DEFAULT_STASH_VELOCITY_THRESHOLD);
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
+                mMainExecutor,
+                properties -> {
+                    if (properties.getKeyset().contains(PIP_STASH_MINIMUM_VELOCITY_THRESHOLD)) {
+                        mStashVelocityThreshold = properties.getFloat(
+                                PIP_STASH_MINIMUM_VELOCITY_THRESHOLD,
+                                DEFAULT_STASH_VELOCITY_THRESHOLD);
+                    }
+                });
+    }
+
+    public PipTransitionController getTransitionHandler() {
+        // return mPipTaskOrganizer.getTransitionController();
+        return null;
+    }
+
+    private void reloadResources() {
+        final Resources res = mContext.getResources();
+        mBottomOffsetBufferPx = res.getDimensionPixelSize(R.dimen.pip_bottom_offset_buffer);
+        mImeOffset = res.getDimensionPixelSize(R.dimen.pip_ime_offset);
+        mPipDismissTargetHandler.updateMagneticTargetSize();
+    }
+
+    void onOverlayChanged() {
+        // onOverlayChanged is triggered upon theme change, update the dismiss target accordingly.
+        mPipDismissTargetHandler.init();
+    }
+
+    private boolean shouldShowResizeHandle() {
+        return false;
+    }
+
+    void setTouchGesture(PipTouchGesture gesture) {
+        mGesture = gesture;
+    }
+
+    void setTouchEnabled(boolean enabled) {
+        mTouchState.setAllowTouches(enabled);
+    }
+
+    void showPictureInPictureMenu() {
+        // Only show the menu if the user isn't currently interacting with the PiP
+        if (!mTouchState.isUserInteracting()) {
+            mMenuController.showMenu(MENU_STATE_FULL, mPipBoundsState.getBounds(),
+                    false /* allowMenuTimeout */, willResizeMenu(),
+                    shouldShowResizeHandle());
+        }
+    }
+
+    void onActivityPinned() {
+        mPipDismissTargetHandler.createOrUpdateDismissTarget();
+
+        mPipResizeGestureHandler.onActivityPinned();
+        mFloatingContentCoordinator.onContentAdded(mMotionHelper);
+    }
+
+    void onActivityUnpinned(ComponentName topPipActivity) {
+        if (topPipActivity == null) {
+            // Clean up state after the last PiP activity is removed
+            mPipDismissTargetHandler.cleanUpDismissTarget();
+
+            mFloatingContentCoordinator.onContentRemoved(mMotionHelper);
+        }
+        mPipResizeGestureHandler.onActivityUnpinned();
+    }
+
+    void onPinnedStackAnimationEnded(
+            @PipAnimationController.TransitionDirection int direction) {
+        // Always synchronize the motion helper bounds once PiP animations finish
+        mMotionHelper.synchronizePinnedStackBounds();
+        updateMovementBounds();
+        if (direction == TRANSITION_DIRECTION_TO_PIP) {
+            // Set the initial bounds as the user resize bounds.
+            mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
+        }
+    }
+
+    void onConfigurationChanged() {
+        mPipResizeGestureHandler.onConfigurationChanged();
+        mMotionHelper.synchronizePinnedStackBounds();
+        reloadResources();
+
+        /*
+        if (mPipTaskOrganizer.isInPip()) {
+            // Recreate the dismiss target for the new orientation.
+            mPipDismissTargetHandler.createOrUpdateDismissTarget();
+        }
+         */
+    }
+
+    void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
+        mIsImeShowing = imeVisible;
+        mImeHeight = imeHeight;
+    }
+
+    void onShelfVisibilityChanged(boolean shelfVisible, int shelfHeight) {
+        mIsShelfShowing = shelfVisible;
+        mShelfHeight = shelfHeight;
+    }
+
+    /**
+     * Called when SysUI state changed.
+     *
+     * @param isSysUiStateValid Is SysUI valid or not.
+     */
+    public void onSystemUiStateChanged(boolean isSysUiStateValid) {
+        mPipResizeGestureHandler.onSystemUiStateChanged(isSysUiStateValid);
+    }
+
+    void adjustBoundsForRotation(Rect outBounds, Rect curBounds, Rect insetBounds) {
+        final Rect toMovementBounds = new Rect();
+        mPipBoundsAlgorithm.getMovementBounds(outBounds, insetBounds, toMovementBounds, 0);
+        final int prevBottom = mPipBoundsState.getMovementBounds().bottom
+                - mMovementBoundsExtraOffsets;
+        if ((prevBottom - mBottomOffsetBufferPx) <= curBounds.top) {
+            outBounds.offsetTo(outBounds.left, toMovementBounds.bottom);
+        }
+    }
+
+    /**
+     * Responds to IPinnedStackListener on resetting aspect ratio for the pinned window.
+     */
+    public void onAspectRatioChanged() {
+        mPipResizeGestureHandler.invalidateUserResizeBounds();
+    }
+
+    void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds, Rect curBounds,
+            boolean fromImeAdjustment, boolean fromShelfAdjustment, int displayRotation) {
+        // Set the user resized bounds equal to the new normal bounds in case they were
+        // invalidated (e.g. by an aspect ratio change).
+        if (mPipResizeGestureHandler.getUserResizeBounds().isEmpty()) {
+            mPipResizeGestureHandler.setUserResizeBounds(normalBounds);
+        }
+
+        final int bottomOffset = mIsImeShowing ? mImeHeight : 0;
+        final boolean fromDisplayRotationChanged = (mDisplayRotation != displayRotation);
+        if (fromDisplayRotationChanged) {
+            mTouchState.reset();
+        }
+
+        // Re-calculate the expanded bounds
+        Rect normalMovementBounds = new Rect();
+        mPipBoundsAlgorithm.getMovementBounds(normalBounds, insetBounds,
+                normalMovementBounds, bottomOffset);
+
+        if (mPipBoundsState.getMovementBounds().isEmpty()) {
+            // mMovementBounds is not initialized yet and a clean movement bounds without
+            // bottom offset shall be used later in this function.
+            mPipBoundsAlgorithm.getMovementBounds(curBounds, insetBounds,
+                    mPipBoundsState.getMovementBounds(), 0 /* bottomOffset */);
+        }
+
+        // Calculate the expanded size
+        float aspectRatio = (float) normalBounds.width() / normalBounds.height();
+        Size expandedSize = mSizeSpecSource.getDefaultSize(aspectRatio);
+        mPipBoundsState.setExpandedBounds(
+                new Rect(0, 0, expandedSize.getWidth(), expandedSize.getHeight()));
+        Rect expandedMovementBounds = new Rect();
+        mPipBoundsAlgorithm.getMovementBounds(
+                mPipBoundsState.getExpandedBounds(), insetBounds, expandedMovementBounds,
+                bottomOffset);
+
+        updatePipSizeConstraints(normalBounds, aspectRatio);
+
+        // The extra offset does not really affect the movement bounds, but are applied based on the
+        // current state (ime showing, or shelf offset) when we need to actually shift
+        int extraOffset = Math.max(
+                mIsImeShowing ? mImeOffset : 0,
+                !mIsImeShowing && mIsShelfShowing ? mShelfHeight : 0);
+
+        // Update the movement bounds after doing the calculations based on the old movement bounds
+        // above
+        mPipBoundsState.setNormalMovementBounds(normalMovementBounds);
+        mPipBoundsState.setExpandedMovementBounds(expandedMovementBounds);
+        mDisplayRotation = displayRotation;
+        mInsetBounds.set(insetBounds);
+        updateMovementBounds();
+        mMovementBoundsExtraOffsets = extraOffset;
+
+        // If we have a deferred resize, apply it now
+        if (mDeferResizeToNormalBoundsUntilRotation == displayRotation) {
+            mMotionHelper.animateToUnexpandedState(normalBounds, mSavedSnapFraction,
+                    mPipBoundsState.getNormalMovementBounds(), mPipBoundsState.getMovementBounds(),
+                    true /* immediate */);
+            mSavedSnapFraction = -1f;
+            mDeferResizeToNormalBoundsUntilRotation = -1;
+        }
+    }
+
+    /**
+     * Update the values for min/max allowed size of picture in picture window based on the aspect
+     * ratio.
+     * @param aspectRatio aspect ratio to use for the calculation of min/max size
+     */
+    public void updateMinMaxSize(float aspectRatio) {
+        updatePipSizeConstraints(mPipBoundsState.getNormalBounds(),
+                aspectRatio);
+    }
+
+    private void updatePipSizeConstraints(Rect normalBounds,
+            float aspectRatio) {
+        if (mPipResizeGestureHandler.isUsingPinchToZoom()) {
+            updatePinchResizeSizeConstraints(aspectRatio);
+        } else {
+            mPipResizeGestureHandler.updateMinSize(normalBounds.width(), normalBounds.height());
+            mPipResizeGestureHandler.updateMaxSize(mPipBoundsState.getExpandedBounds().width(),
+                    mPipBoundsState.getExpandedBounds().height());
+        }
+    }
+
+    private void updatePinchResizeSizeConstraints(float aspectRatio) {
+        mPipBoundsState.updateMinMaxSize(aspectRatio);
+        mPipResizeGestureHandler.updateMinSize(mPipBoundsState.getMinSize().x,
+                mPipBoundsState.getMinSize().y);
+        mPipResizeGestureHandler.updateMaxSize(mPipBoundsState.getMaxSize().x,
+                mPipBoundsState.getMaxSize().y);
+    }
+
+    /**
+     * TODO Add appropriate description
+     */
+    public void onRegistrationChanged(boolean isRegistered) {
+        if (isRegistered) {
+            // Register the accessibility connection.
+        } else {
+            mAccessibilityManager.setPictureInPictureActionReplacingConnection(null);
+        }
+        if (!isRegistered && mTouchState.isUserInteracting()) {
+            // If the input consumer is unregistered while the user is interacting, then we may not
+            // get the final TOUCH_UP event, so clean up the dismiss target as well
+            mPipDismissTargetHandler.cleanUpDismissTarget();
+        }
+    }
+
+    private void onAccessibilityShowMenu() {
+        mMenuController.showMenu(MENU_STATE_FULL, mPipBoundsState.getBounds(),
+                true /* allowMenuTimeout */, willResizeMenu(),
+                shouldShowResizeHandle());
+    }
+
+    /**
+     * TODO Add appropriate description
+     */
+    public boolean handleTouchEvent(InputEvent inputEvent) {
+        // Skip any non motion events
+        if (!(inputEvent instanceof MotionEvent)) {
+            return true;
+        }
+
+        // do not process input event if not allowed
+        if (!mTouchState.getAllowInputEvents()) {
+            return true;
+        }
+
+        MotionEvent ev = (MotionEvent) inputEvent;
+        if (!mPipBoundsState.isStashed() && mPipResizeGestureHandler.willStartResizeGesture(ev)) {
+            // Initialize the touch state for the gesture, but immediately reset to invalidate the
+            // gesture
+            mTouchState.onTouchEvent(ev);
+            mTouchState.reset();
+            return true;
+        }
+
+        if (mPipResizeGestureHandler.hasOngoingGesture()) {
+            mGesture.cleanUpHighPerfSessionMaybe();
+            mPipDismissTargetHandler.hideDismissTargetMaybe();
+            return true;
+        }
+
+        if ((ev.getAction() == MotionEvent.ACTION_DOWN || mTouchState.isUserInteracting())
+                && mPipDismissTargetHandler.maybeConsumeMotionEvent(ev)) {
+            // If the first touch event occurs within the magnetic field, pass the ACTION_DOWN event
+            // to the touch state. Touch state needs a DOWN event in order to later process MOVE
+            // events it'll receive if the object is dragged out of the magnetic field.
+            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+                mTouchState.onTouchEvent(ev);
+            }
+
+            // Continue tracking velocity when the object is in the magnetic field, since we want to
+            // respect touch input velocity if the object is dragged out and then flung.
+            mTouchState.addMovementToVelocityTracker(ev);
+
+            return true;
+        }
+
+        if (!mTouchState.isUserInteracting()) {
+            ProtoLog.wtf(WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Waiting to start the entry animation, skip the motion event.", TAG);
+            return true;
+        }
+
+        // Update the touch state
+        mTouchState.onTouchEvent(ev);
+
+        boolean shouldDeliverToMenu = mMenuState != MENU_STATE_NONE;
+
+        switch (ev.getAction()) {
+            case MotionEvent.ACTION_DOWN: {
+                mGesture.onDown(mTouchState);
+                break;
+            }
+            case MotionEvent.ACTION_MOVE: {
+                if (mGesture.onMove(mTouchState)) {
+                    break;
+                }
+
+                shouldDeliverToMenu = !mTouchState.isDragging();
+                break;
+            }
+            case MotionEvent.ACTION_UP: {
+                // Update the movement bounds again if the state has changed since the user started
+                // dragging (ie. when the IME shows)
+                updateMovementBounds();
+
+                if (mGesture.onUp(mTouchState)) {
+                    break;
+                }
+            }
+            // Fall through to clean up
+            case MotionEvent.ACTION_CANCEL: {
+                shouldDeliverToMenu = !mTouchState.startedDragging() && !mTouchState.isDragging();
+                mTouchState.reset();
+                break;
+            }
+            case MotionEvent.ACTION_HOVER_ENTER: {
+                // If Touch Exploration is enabled, some a11y services (e.g. Talkback) is probably
+                // on and changing MotionEvents into HoverEvents.
+                // Let's not enable menu show/hide for a11y services.
+                if (!mAccessibilityManager.isTouchExplorationEnabled()) {
+                    mTouchState.removeHoverExitTimeoutCallback();
+                    mMenuController.showMenu(MENU_STATE_FULL, mPipBoundsState.getBounds(),
+                            false /* allowMenuTimeout */, false /* willResizeMenu */,
+                            shouldShowResizeHandle());
+                }
+            }
+            // Fall through
+            case MotionEvent.ACTION_HOVER_MOVE: {
+                if (!shouldDeliverToMenu && !mSendingHoverAccessibilityEvents) {
+                    sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
+                    mSendingHoverAccessibilityEvents = true;
+                }
+                break;
+            }
+            case MotionEvent.ACTION_HOVER_EXIT: {
+                // If Touch Exploration is enabled, some a11y services (e.g. Talkback) is probably
+                // on and changing MotionEvents into HoverEvents.
+                // Let's not enable menu show/hide for a11y services.
+                if (!mAccessibilityManager.isTouchExplorationEnabled()) {
+                    mTouchState.scheduleHoverExitTimeoutCallback();
+                }
+                if (!shouldDeliverToMenu && mSendingHoverAccessibilityEvents) {
+                    sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
+                    mSendingHoverAccessibilityEvents = false;
+                }
+                break;
+            }
+        }
+
+        shouldDeliverToMenu &= !mPipBoundsState.isStashed();
+
+        // Deliver the event to PipMenuActivity to handle button click if the menu has shown.
+        if (shouldDeliverToMenu) {
+            final MotionEvent cloneEvent = MotionEvent.obtain(ev);
+            // Send the cancel event and cancel menu timeout if it starts to drag.
+            if (mTouchState.startedDragging()) {
+                cloneEvent.setAction(MotionEvent.ACTION_CANCEL);
+                mMenuController.pokeMenu();
+            }
+
+            mMenuController.handlePointerEvent(cloneEvent);
+            cloneEvent.recycle();
+        }
+
+        return true;
+    }
+
+    private void sendAccessibilityHoverEvent(int type) {
+        if (!mAccessibilityManager.isEnabled()) {
+            return;
+        }
+
+        AccessibilityEvent event = AccessibilityEvent.obtain(type);
+        event.setImportantForAccessibility(true);
+        event.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID);
+        event.setWindowId(
+                AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID);
+        mAccessibilityManager.sendAccessibilityEvent(event);
+    }
+
+    /**
+     * Called when the PiP menu state is in the process of animating/changing from one to another.
+     */
+    private void onPipMenuStateChangeStart(int menuState, boolean resize, Runnable callback) {
+        if (mMenuState == menuState && !resize) {
+            return;
+        }
+
+        if (menuState == MENU_STATE_FULL && mMenuState != MENU_STATE_FULL) {
+            // Save the current snap fraction and if we do not drag or move the PiP, then
+            // we store back to this snap fraction.  Otherwise, we'll reset the snap
+            // fraction and snap to the closest edge.
+            if (resize) {
+                // PIP is too small to show the menu actions and thus needs to be resized to a
+                // size that can fit them all. Resize to the default size.
+                animateToNormalSize(callback);
+            }
+        } else if (menuState == MENU_STATE_NONE && mMenuState == MENU_STATE_FULL) {
+            // Try and restore the PiP to the closest edge, using the saved snap fraction
+            // if possible
+            if (resize && !mPipResizeGestureHandler.isResizing()) {
+                if (mDeferResizeToNormalBoundsUntilRotation == -1) {
+                    // This is a very special case: when the menu is expanded and visible,
+                    // navigating to another activity can trigger auto-enter PiP, and if the
+                    // revealed activity has a forced rotation set, then the controller will get
+                    // updated with the new rotation of the display. However, at the same time,
+                    // SystemUI will try to hide the menu by creating an animation to the normal
+                    // bounds which are now stale.  In such a case we defer the animation to the
+                    // normal bounds until after the next onMovementBoundsChanged() call to get the
+                    // bounds in the new orientation
+                    int displayRotation = mContext.getDisplay().getRotation();
+                    if (mDisplayRotation != displayRotation) {
+                        mDeferResizeToNormalBoundsUntilRotation = displayRotation;
+                    }
+                }
+
+                if (mDeferResizeToNormalBoundsUntilRotation == -1) {
+                    animateToUnexpandedState(getUserResizeBounds());
+                }
+            } else {
+                mSavedSnapFraction = -1f;
+            }
+        }
+    }
+
+    private void setMenuState(int menuState) {
+        mMenuState = menuState;
+        updateMovementBounds();
+        // If pip menu has dismissed, we should register the A11y ActionReplacingConnection for pip
+        // as well, or it can't handle a11y focus and pip menu can't perform any action.
+        onRegistrationChanged(menuState == MENU_STATE_NONE);
+        if (menuState == MENU_STATE_NONE) {
+            mPipUiEventLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_HIDE_MENU);
+        } else if (menuState == MENU_STATE_FULL) {
+            mPipUiEventLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_SHOW_MENU);
+        }
+    }
+
+    private void animateToMaximizedState(Runnable callback) {
+        Rect maxMovementBounds = new Rect();
+        Rect maxBounds = new Rect(0, 0, mPipBoundsState.getMaxSize().x,
+                mPipBoundsState.getMaxSize().y);
+        mPipBoundsAlgorithm.getMovementBounds(maxBounds, mInsetBounds, maxMovementBounds,
+                mIsImeShowing ? mImeHeight : 0);
+        mSavedSnapFraction = mMotionHelper.animateToExpandedState(maxBounds,
+                mPipBoundsState.getMovementBounds(), maxMovementBounds,
+                callback);
+    }
+
+    private void animateToNormalSize(Runnable callback) {
+        // Save the current bounds as the user-resize bounds.
+        mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
+
+        final Size minMenuSize = mMenuController.getEstimatedMinMenuSize();
+        final Rect normalBounds = mPipBoundsState.getNormalBounds();
+        final Rect destBounds = mPipBoundsAlgorithm.adjustNormalBoundsToFitMenu(normalBounds,
+                minMenuSize);
+        Rect restoredMovementBounds = new Rect();
+        mPipBoundsAlgorithm.getMovementBounds(destBounds,
+                mInsetBounds, restoredMovementBounds, mIsImeShowing ? mImeHeight : 0);
+        mSavedSnapFraction = mMotionHelper.animateToExpandedState(destBounds,
+                mPipBoundsState.getMovementBounds(), restoredMovementBounds, callback);
+    }
+
+    private void animateToUnexpandedState(Rect restoreBounds) {
+        Rect restoredMovementBounds = new Rect();
+        mPipBoundsAlgorithm.getMovementBounds(restoreBounds,
+                mInsetBounds, restoredMovementBounds, mIsImeShowing ? mImeHeight : 0);
+        mMotionHelper.animateToUnexpandedState(restoreBounds, mSavedSnapFraction,
+                restoredMovementBounds, mPipBoundsState.getMovementBounds(), false /* immediate */);
+        mSavedSnapFraction = -1f;
+    }
+
+    private void animateToUnStashedState() {
+        final Rect pipBounds = mPipBoundsState.getBounds();
+        final boolean onLeftEdge = pipBounds.left < mPipBoundsState.getDisplayBounds().left;
+        final Rect unStashedBounds = new Rect(0, pipBounds.top, 0, pipBounds.bottom);
+        unStashedBounds.left = onLeftEdge ? mInsetBounds.left
+                : mInsetBounds.right - pipBounds.width();
+        unStashedBounds.right = onLeftEdge ? mInsetBounds.left + pipBounds.width()
+                : mInsetBounds.right;
+        mMotionHelper.animateToUnStashedBounds(unStashedBounds);
+    }
+
+    /**
+     * @return the motion helper.
+     */
+    public PipMotionHelper getMotionHelper() {
+        return mMotionHelper;
+    }
+
+    @VisibleForTesting
+    public PipResizeGestureHandler getPipResizeGestureHandler() {
+        return mPipResizeGestureHandler;
+    }
+
+    @VisibleForTesting
+    public void setPipResizeGestureHandler(PipResizeGestureHandler pipResizeGestureHandler) {
+        mPipResizeGestureHandler = pipResizeGestureHandler;
+    }
+
+    @VisibleForTesting
+    public void setPipMotionHelper(PipMotionHelper pipMotionHelper) {
+        mMotionHelper = pipMotionHelper;
+    }
+
+    Rect getUserResizeBounds() {
+        return mPipResizeGestureHandler.getUserResizeBounds();
+    }
+
+    /**
+     * Sets the user resize bounds tracked by {@link PipResizeGestureHandler}
+     */
+    void setUserResizeBounds(Rect bounds) {
+        mPipResizeGestureHandler.setUserResizeBounds(bounds);
+    }
+
+    /**
+     * Gesture controlling normal movement of the PIP.
+     */
+    private class DefaultPipTouchGesture extends PipTouchGesture {
+        private final Point mStartPosition = new Point();
+        private final PointF mDelta = new PointF();
+        private boolean mShouldHideMenuAfterFling;
+
+        @Nullable private PipPerfHintController.PipHighPerfSession mPipHighPerfSession;
+
+        private void onHighPerfSessionTimeout(PipPerfHintController.PipHighPerfSession session) {}
+
+        @Override
+        public void cleanUpHighPerfSessionMaybe() {
+            if (mPipHighPerfSession != null) {
+                // Close the high perf session once pointer interactions are over;
+                mPipHighPerfSession.close();
+                mPipHighPerfSession = null;
+            }
+        }
+
+        @Override
+        public void onDown(PipTouchState touchState) {
+            if (!touchState.isUserInteracting()) {
+                return;
+            }
+
+            if (mPipPerfHintController != null) {
+                // Cache the PiP high perf session to close it upon touch up.
+                mPipHighPerfSession = mPipPerfHintController.startSession(
+                        this::onHighPerfSessionTimeout, "DefaultPipTouchGesture#onDown");
+            }
+
+            Rect bounds = getPossiblyMotionBounds();
+            mDelta.set(0f, 0f);
+            mStartPosition.set(bounds.left, bounds.top);
+            mMovementWithinDismiss = touchState.getDownTouchPosition().y
+                    >= mPipBoundsState.getMovementBounds().bottom;
+            mMotionHelper.setSpringingToTouch(false);
+            // mPipDismissTargetHandler.setTaskLeash(mPipTaskOrganizer.getSurfaceControl());
+
+            // If the menu is still visible then just poke the menu
+            // so that it will timeout after the user stops touching it
+            if (mMenuState != MENU_STATE_NONE && !mPipBoundsState.isStashed()) {
+                mMenuController.pokeMenu();
+            }
+        }
+
+        @Override
+        public boolean onMove(PipTouchState touchState) {
+            if (!touchState.isUserInteracting()) {
+                return false;
+            }
+
+            if (touchState.startedDragging()) {
+                mSavedSnapFraction = -1f;
+                mPipDismissTargetHandler.showDismissTargetMaybe();
+            }
+
+            if (touchState.isDragging()) {
+                mPipBoundsState.setHasUserMovedPip(true);
+
+                // Move the pinned stack freely
+                final PointF lastDelta = touchState.getLastTouchDelta();
+                float lastX = mStartPosition.x + mDelta.x;
+                float lastY = mStartPosition.y + mDelta.y;
+                float left = lastX + lastDelta.x;
+                float top = lastY + lastDelta.y;
+
+                // Add to the cumulative delta after bounding the position
+                mDelta.x += left - lastX;
+                mDelta.y += top - lastY;
+
+                mTmpBounds.set(getPossiblyMotionBounds());
+                mTmpBounds.offsetTo((int) left, (int) top);
+                mMotionHelper.movePip(mTmpBounds, true /* isDragging */);
+
+                final PointF curPos = touchState.getLastTouchPosition();
+                if (mMovementWithinDismiss) {
+                    // Track if movement remains near the bottom edge to identify swipe to dismiss
+                    mMovementWithinDismiss = curPos.y >= mPipBoundsState.getMovementBounds().bottom;
+                }
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public boolean onUp(PipTouchState touchState) {
+            mPipDismissTargetHandler.hideDismissTargetMaybe();
+            mPipDismissTargetHandler.setTaskLeash(null);
+
+            if (!touchState.isUserInteracting()) {
+                return false;
+            }
+
+            final PointF vel = touchState.getVelocity();
+
+            if (touchState.isDragging()) {
+                if (mMenuState != MENU_STATE_NONE) {
+                    // If the menu is still visible, then just poke the menu so that
+                    // it will timeout after the user stops touching it
+                    mMenuController.showMenu(mMenuState, mPipBoundsState.getBounds(),
+                            true /* allowMenuTimeout */, willResizeMenu(),
+                            shouldShowResizeHandle());
+                }
+                mShouldHideMenuAfterFling = mMenuState == MENU_STATE_NONE;
+
+                // Reset the touch state on up before the fling settles
+                mTouchState.reset();
+                if (mEnableStash && shouldStash(vel, getPossiblyMotionBounds())) {
+                    mMotionHelper.stashToEdge(vel.x, vel.y, this::stashEndAction /* endAction */);
+                } else {
+                    if (mPipBoundsState.isStashed()) {
+                        // Reset stashed state if previously stashed
+                        mPipUiEventLogger.log(
+                                PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_STASH_UNSTASHED);
+                        mPipBoundsState.setStashed(STASH_TYPE_NONE);
+                    }
+                    mMotionHelper.flingToSnapTarget(vel.x, vel.y,
+                            this::flingEndAction /* endAction */);
+                }
+            } else if (mTouchState.isDoubleTap() && !mPipBoundsState.isStashed()
+                    && mMenuState != MENU_STATE_FULL) {
+                // If using pinch to zoom, double-tap functions as resizing between max/min size
+                if (mPipResizeGestureHandler.isUsingPinchToZoom()) {
+                    final boolean toExpand = mPipBoundsState.getBounds().width()
+                            < mPipBoundsState.getMaxSize().x
+                            && mPipBoundsState.getBounds().height()
+                            < mPipBoundsState.getMaxSize().y;
+                    if (mMenuController.isMenuVisible()) {
+                        mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */);
+                    }
+
+                    // the size to toggle to after a double tap
+                    int nextSize = PipDoubleTapHelper
+                            .nextSizeSpec(mPipBoundsState, getUserResizeBounds());
+
+                    // actually toggle to the size chosen
+                    if (nextSize == PipDoubleTapHelper.SIZE_SPEC_MAX) {
+                        mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
+                        animateToMaximizedState(null);
+                    } else if (nextSize == PipDoubleTapHelper.SIZE_SPEC_DEFAULT) {
+                        mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds());
+                        animateToNormalSize(null);
+                    } else {
+                        animateToUnexpandedState(getUserResizeBounds());
+                    }
+                } else {
+                    // Expand to fullscreen if this is a double tap
+                    // the PiP should be frozen until the transition ends
+                    setTouchEnabled(false);
+                    mMotionHelper.expandLeavePip(false /* skipAnimation */);
+                }
+            } else if (mMenuState != MENU_STATE_FULL) {
+                if (mPipBoundsState.isStashed()) {
+                    // Unstash immediately if stashed, and don't wait for the double tap timeout
+                    animateToUnStashedState();
+                    mPipUiEventLogger.log(
+                            PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_STASH_UNSTASHED);
+                    mPipBoundsState.setStashed(STASH_TYPE_NONE);
+                    mTouchState.removeDoubleTapTimeoutCallback();
+                } else if (!mTouchState.isWaitingForDoubleTap()) {
+                    // User has stalled long enough for this not to be a drag or a double tap,
+                    // just expand the menu
+                    mMenuController.showMenu(MENU_STATE_FULL, mPipBoundsState.getBounds(),
+                            true /* allowMenuTimeout */, willResizeMenu(),
+                            shouldShowResizeHandle());
+                } else {
+                    // Next touch event _may_ be the second tap for the double-tap, schedule a
+                    // fallback runnable to trigger the menu if no touch event occurs before the
+                    // next tap
+                    mTouchState.scheduleDoubleTapTimeoutCallback();
+                }
+            }
+            cleanUpHighPerfSessionMaybe();
+            return true;
+        }
+
+        private void stashEndAction() {
+            if (mPipBoundsState.getBounds().left < 0
+                    && mPipBoundsState.getStashedState() != STASH_TYPE_LEFT) {
+                mPipUiEventLogger.log(
+                        PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_STASH_LEFT);
+                mPipBoundsState.setStashed(STASH_TYPE_LEFT);
+            } else if (mPipBoundsState.getBounds().left >= 0
+                    && mPipBoundsState.getStashedState() != STASH_TYPE_RIGHT) {
+                mPipUiEventLogger.log(
+                        PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_STASH_RIGHT);
+                mPipBoundsState.setStashed(STASH_TYPE_RIGHT);
+            }
+            mMenuController.hideMenu();
+        }
+
+        private void flingEndAction() {
+            if (mShouldHideMenuAfterFling) {
+                // If the menu is not visible, then we can still be showing the activity for the
+                // dismiss overlay, so just finish it after the animation completes
+                mMenuController.hideMenu();
+            }
+        }
+
+        private boolean shouldStash(PointF vel, Rect motionBounds) {
+            final boolean flingToLeft = vel.x < -mStashVelocityThreshold;
+            final boolean flingToRight = vel.x > mStashVelocityThreshold;
+            final int offset = motionBounds.width() / 2;
+            final boolean droppingOnLeft =
+                    motionBounds.left < mPipBoundsState.getDisplayBounds().left - offset;
+            final boolean droppingOnRight =
+                    motionBounds.right > mPipBoundsState.getDisplayBounds().right + offset;
+
+            // Do not allow stash if the destination edge contains display cutout. We only
+            // compare the left and right edges since we do not allow stash on top / bottom.
+            final DisplayCutout displayCutout =
+                    mPipBoundsState.getDisplayLayout().getDisplayCutout();
+            if (displayCutout != null) {
+                if ((flingToLeft || droppingOnLeft)
+                        && !displayCutout.getBoundingRectLeft().isEmpty()) {
+                    return false;
+                } else if ((flingToRight || droppingOnRight)
+                        && !displayCutout.getBoundingRectRight().isEmpty()) {
+                    return false;
+                }
+            }
+
+            // If user flings the PIP window above the minimum velocity, stash PIP.
+            // Only allow stashing to the edge if PIP wasn't previously stashed on the opposite
+            // edge.
+            final boolean stashFromFlingToEdge =
+                    (flingToLeft && mPipBoundsState.getStashedState() != STASH_TYPE_RIGHT)
+                    || (flingToRight && mPipBoundsState.getStashedState() != STASH_TYPE_LEFT);
+
+            // If User releases the PIP window while it's out of the display bounds, put
+            // PIP into stashed mode.
+            final boolean stashFromDroppingOnEdge = droppingOnLeft || droppingOnRight;
+
+            return stashFromFlingToEdge || stashFromDroppingOnEdge;
+        }
+    }
+
+    /**
+     * Updates the current movement bounds based on whether the menu is currently visible and
+     * resized.
+     */
+    private void updateMovementBounds() {
+        mPipBoundsAlgorithm.getMovementBounds(mPipBoundsState.getBounds(),
+                mInsetBounds, mPipBoundsState.getMovementBounds(), mIsImeShowing ? mImeHeight : 0);
+        mMotionHelper.onMovementBoundsChanged();
+    }
+
+    private Rect getMovementBounds(Rect curBounds) {
+        Rect movementBounds = new Rect();
+        mPipBoundsAlgorithm.getMovementBounds(curBounds, mInsetBounds,
+                movementBounds, mIsImeShowing ? mImeHeight : 0);
+        return movementBounds;
+    }
+
+    /**
+     * @return {@code true} if the menu should be resized on tap because app explicitly specifies
+     * PiP window size that is too small to hold all the actions.
+     */
+    private boolean willResizeMenu() {
+        if (!mEnableResize) {
+            return false;
+        }
+        final Size estimatedMinMenuSize = mMenuController.getEstimatedMinMenuSize();
+        if (estimatedMinMenuSize == null) {
+            ProtoLog.wtf(WM_SHELL_PICTURE_IN_PICTURE,
+                    "%s: Failed to get estimated menu size", TAG);
+            return false;
+        }
+        final Rect currentBounds = mPipBoundsState.getBounds();
+        return currentBounds.width() < estimatedMinMenuSize.getWidth()
+                || currentBounds.height() < estimatedMinMenuSize.getHeight();
+    }
+
+    /**
+     * Returns the PIP bounds if we're not in the middle of a motion operation, or the current,
+     * temporary motion bounds otherwise.
+     */
+    Rect getPossiblyMotionBounds() {
+        return mPipBoundsState.getMotionBoundsState().isInMotion()
+                ? mPipBoundsState.getMotionBoundsState().getBoundsInMotion()
+                : mPipBoundsState.getBounds();
+    }
+
+    void setOhmOffset(int offset) {
+        mPipResizeGestureHandler.setOhmOffset(offset);
+    }
+
+    /**
+     * Dumps the {@link PipTouchHandler} state.
+     */
+    public void dump(PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "mMenuState=" + mMenuState);
+        pw.println(innerPrefix + "mIsImeShowing=" + mIsImeShowing);
+        pw.println(innerPrefix + "mImeHeight=" + mImeHeight);
+        pw.println(innerPrefix + "mIsShelfShowing=" + mIsShelfShowing);
+        pw.println(innerPrefix + "mShelfHeight=" + mShelfHeight);
+        pw.println(innerPrefix + "mSavedSnapFraction=" + mSavedSnapFraction);
+        pw.println(innerPrefix + "mMovementBoundsExtraOffsets=" + mMovementBoundsExtraOffsets);
+        mPipBoundsAlgorithm.dump(pw, innerPrefix);
+        mTouchState.dump(pw, innerPrefix);
+        if (mPipResizeGestureHandler != null) {
+            mPipResizeGestureHandler.dump(pw, innerPrefix);
+        }
+    }
+
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchState.java
new file mode 100644
index 0000000..d093f1e
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTouchState.java
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.pip2.phone;
+
+import android.graphics.PointF;
+import android.view.Display;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.ViewConfiguration;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.protolog.ShellProtoLogGroup;
+
+import java.io.PrintWriter;
+
+/**
+ * This keeps track of the touch state throughout the current touch gesture.
+ */
+public class PipTouchState {
+    private static final String TAG = "PipTouchState";
+    private static final boolean DEBUG = false;
+
+    @VisibleForTesting
+    public static final long DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();
+    static final long HOVER_EXIT_TIMEOUT = 50;
+
+    private final ShellExecutor mMainExecutor;
+    private final ViewConfiguration mViewConfig;
+    private final Runnable mDoubleTapTimeoutCallback;
+    private final Runnable mHoverExitTimeoutCallback;
+
+    private VelocityTracker mVelocityTracker;
+    private long mDownTouchTime = 0;
+    private long mLastDownTouchTime = 0;
+    private long mUpTouchTime = 0;
+    private final PointF mDownTouch = new PointF();
+    private final PointF mDownDelta = new PointF();
+    private final PointF mLastTouch = new PointF();
+    private final PointF mLastDelta = new PointF();
+    private final PointF mVelocity = new PointF();
+    private boolean mAllowTouches = true;
+
+    // Set to false to block both PipTouchHandler and PipResizeGestureHandler's input processing
+    private boolean mAllowInputEvents = true;
+    private boolean mIsUserInteracting = false;
+    // Set to true only if the multiple taps occur within the double tap timeout
+    private boolean mIsDoubleTap = false;
+    // Set to true only if a gesture
+    private boolean mIsWaitingForDoubleTap = false;
+    private boolean mIsDragging = false;
+    // The previous gesture was a drag
+    private boolean mPreviouslyDragging = false;
+    private boolean mStartedDragging = false;
+    private boolean mAllowDraggingOffscreen = false;
+    private int mActivePointerId;
+    private int mLastTouchDisplayId = Display.INVALID_DISPLAY;
+
+    public PipTouchState(ViewConfiguration viewConfig, Runnable doubleTapTimeoutCallback,
+            Runnable hoverExitTimeoutCallback, ShellExecutor mainExecutor) {
+        mViewConfig = viewConfig;
+        mDoubleTapTimeoutCallback = doubleTapTimeoutCallback;
+        mHoverExitTimeoutCallback = hoverExitTimeoutCallback;
+        mMainExecutor = mainExecutor;
+    }
+
+    /**
+     * @return true if input processing is enabled for PiP in general.
+     */
+    public boolean getAllowInputEvents() {
+        return mAllowInputEvents;
+    }
+
+    /**
+     * @param allowInputEvents true to enable input processing for PiP in general.
+     */
+    public void setAllowInputEvents(boolean allowInputEvents) {
+        mAllowInputEvents = allowInputEvents;
+    }
+
+    /**
+     * Resets this state.
+     */
+    public void reset() {
+        mAllowDraggingOffscreen = false;
+        mIsDragging = false;
+        mStartedDragging = false;
+        mIsUserInteracting = false;
+        mLastTouchDisplayId = Display.INVALID_DISPLAY;
+    }
+
+    /**
+     * Processes a given touch event and updates the state.
+     */
+    public void onTouchEvent(MotionEvent ev) {
+        mLastTouchDisplayId = ev.getDisplayId();
+        switch (ev.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN: {
+                if (!mAllowTouches) {
+                    return;
+                }
+
+                // Initialize the velocity tracker
+                initOrResetVelocityTracker();
+                addMovementToVelocityTracker(ev);
+
+                mActivePointerId = ev.getPointerId(0);
+                if (DEBUG) {
+                    ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                            "%s: Setting active pointer id on DOWN: %d", TAG, mActivePointerId);
+                }
+                mLastTouch.set(ev.getRawX(), ev.getRawY());
+                mDownTouch.set(mLastTouch);
+                mAllowDraggingOffscreen = true;
+                mIsUserInteracting = true;
+                mDownTouchTime = ev.getEventTime();
+                mIsDoubleTap = !mPreviouslyDragging
+                        && (mDownTouchTime - mLastDownTouchTime) < DOUBLE_TAP_TIMEOUT;
+                mIsWaitingForDoubleTap = false;
+                mIsDragging = false;
+                mLastDownTouchTime = mDownTouchTime;
+                if (mDoubleTapTimeoutCallback != null) {
+                    mMainExecutor.removeCallbacks(mDoubleTapTimeoutCallback);
+                }
+                break;
+            }
+            case MotionEvent.ACTION_MOVE: {
+                // Skip event if we did not start processing this touch gesture
+                if (!mIsUserInteracting) {
+                    break;
+                }
+
+                // Update the velocity tracker
+                addMovementToVelocityTracker(ev);
+                int pointerIndex = ev.findPointerIndex(mActivePointerId);
+                if (pointerIndex == -1) {
+                    ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                            "%s: Invalid active pointer id on MOVE: %d", TAG, mActivePointerId);
+                    break;
+                }
+
+                float x = ev.getRawX(pointerIndex);
+                float y = ev.getRawY(pointerIndex);
+                mLastDelta.set(x - mLastTouch.x, y - mLastTouch.y);
+                mDownDelta.set(x - mDownTouch.x, y - mDownTouch.y);
+
+                boolean hasMovedBeyondTap = mDownDelta.length() > mViewConfig.getScaledTouchSlop();
+                if (!mIsDragging) {
+                    if (hasMovedBeyondTap) {
+                        mIsDragging = true;
+                        mStartedDragging = true;
+                    }
+                } else {
+                    mStartedDragging = false;
+                }
+                mLastTouch.set(x, y);
+                break;
+            }
+            case MotionEvent.ACTION_POINTER_UP: {
+                // Skip event if we did not start processing this touch gesture
+                if (!mIsUserInteracting) {
+                    break;
+                }
+
+                // Update the velocity tracker
+                addMovementToVelocityTracker(ev);
+
+                int pointerIndex = ev.getActionIndex();
+                int pointerId = ev.getPointerId(pointerIndex);
+                if (pointerId == mActivePointerId) {
+                    // Select a new active pointer id and reset the movement state
+                    final int newPointerIndex = (pointerIndex == 0) ? 1 : 0;
+                    mActivePointerId = ev.getPointerId(newPointerIndex);
+                    if (DEBUG) {
+                        ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                                "%s: Relinquish active pointer id on POINTER_UP: %d",
+                                TAG, mActivePointerId);
+                    }
+                    mLastTouch.set(ev.getRawX(newPointerIndex), ev.getRawY(newPointerIndex));
+                }
+                break;
+            }
+            case MotionEvent.ACTION_UP: {
+                // Skip event if we did not start processing this touch gesture
+                if (!mIsUserInteracting) {
+                    break;
+                }
+
+                // Update the velocity tracker
+                addMovementToVelocityTracker(ev);
+                mVelocityTracker.computeCurrentVelocity(1000,
+                        mViewConfig.getScaledMaximumFlingVelocity());
+                mVelocity.set(mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity());
+
+                int pointerIndex = ev.findPointerIndex(mActivePointerId);
+                if (pointerIndex == -1) {
+                    ProtoLog.e(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                            "%s: Invalid active pointer id on UP: %d", TAG, mActivePointerId);
+                    break;
+                }
+
+                mUpTouchTime = ev.getEventTime();
+                mLastTouch.set(ev.getRawX(pointerIndex), ev.getRawY(pointerIndex));
+                mPreviouslyDragging = mIsDragging;
+                mIsWaitingForDoubleTap = !mIsDoubleTap && !mIsDragging
+                        && (mUpTouchTime - mDownTouchTime) < DOUBLE_TAP_TIMEOUT;
+
+            }
+            // fall through to clean up
+            case MotionEvent.ACTION_CANCEL: {
+                recycleVelocityTracker();
+                break;
+            }
+            case MotionEvent.ACTION_BUTTON_PRESS: {
+                removeHoverExitTimeoutCallback();
+                break;
+            }
+        }
+    }
+
+    /**
+     * @return the velocity of the active touch pointer at the point it is lifted off the screen.
+     */
+    public PointF getVelocity() {
+        return mVelocity;
+    }
+
+    /**
+     * @return the last touch position of the active pointer.
+     */
+    public PointF getLastTouchPosition() {
+        return mLastTouch;
+    }
+
+    /**
+     * @return the movement delta between the last handled touch event and the previous touch
+     * position.
+     */
+    public PointF getLastTouchDelta() {
+        return mLastDelta;
+    }
+
+    /**
+     * @return the down touch position.
+     */
+    public PointF getDownTouchPosition() {
+        return mDownTouch;
+    }
+
+    /**
+     * @return the movement delta between the last handled touch event and the down touch
+     * position.
+     */
+    public PointF getDownTouchDelta() {
+        return mDownDelta;
+    }
+
+    /**
+     * @return whether the user has started dragging.
+     */
+    public boolean isDragging() {
+        return mIsDragging;
+    }
+
+    /**
+     * @return whether the user is currently interacting with the PiP.
+     */
+    public boolean isUserInteracting() {
+        return mIsUserInteracting;
+    }
+
+    /**
+     * @return whether the user has started dragging just in the last handled touch event.
+     */
+    public boolean startedDragging() {
+        return mStartedDragging;
+    }
+
+    /**
+     * @return Display ID of the last touch event.
+     */
+    public int getLastTouchDisplayId() {
+        return mLastTouchDisplayId;
+    }
+
+    /**
+     * Sets whether touching is currently allowed.
+     */
+    public void setAllowTouches(boolean allowTouches) {
+        mAllowTouches = allowTouches;
+
+        // If the user happens to touch down before this is sent from the system during a transition
+        // then block any additional handling by resetting the state now
+        if (mIsUserInteracting) {
+            reset();
+        }
+    }
+
+    /**
+     * Disallows dragging offscreen for the duration of the current gesture.
+     */
+    public void setDisallowDraggingOffscreen() {
+        mAllowDraggingOffscreen = false;
+    }
+
+    /**
+     * @return whether dragging offscreen is allowed during this gesture.
+     */
+    public boolean allowDraggingOffscreen() {
+        return mAllowDraggingOffscreen;
+    }
+
+    /**
+     * @return whether this gesture is a double-tap.
+     */
+    public boolean isDoubleTap() {
+        return mIsDoubleTap;
+    }
+
+    /**
+     * @return whether this gesture will potentially lead to a following double-tap.
+     */
+    public boolean isWaitingForDoubleTap() {
+        return mIsWaitingForDoubleTap;
+    }
+
+    /**
+     * Schedules the callback to run if the next double tap does not occur.  Only runs if
+     * isWaitingForDoubleTap() is true.
+     */
+    public void scheduleDoubleTapTimeoutCallback() {
+        if (mIsWaitingForDoubleTap) {
+            long delay = getDoubleTapTimeoutCallbackDelay();
+            mMainExecutor.removeCallbacks(mDoubleTapTimeoutCallback);
+            mMainExecutor.executeDelayed(mDoubleTapTimeoutCallback, delay);
+        }
+    }
+
+    long getDoubleTapTimeoutCallbackDelay() {
+        if (mIsWaitingForDoubleTap) {
+            return Math.max(0, DOUBLE_TAP_TIMEOUT - (mUpTouchTime - mDownTouchTime));
+        }
+        return -1;
+    }
+
+    /**
+     * Removes the timeout callback if it's in queue.
+     */
+    public void removeDoubleTapTimeoutCallback() {
+        mIsWaitingForDoubleTap = false;
+        mMainExecutor.removeCallbacks(mDoubleTapTimeoutCallback);
+    }
+
+    void scheduleHoverExitTimeoutCallback() {
+        mMainExecutor.removeCallbacks(mHoverExitTimeoutCallback);
+        mMainExecutor.executeDelayed(mHoverExitTimeoutCallback, HOVER_EXIT_TIMEOUT);
+    }
+
+    void removeHoverExitTimeoutCallback() {
+        mMainExecutor.removeCallbacks(mHoverExitTimeoutCallback);
+    }
+
+    void addMovementToVelocityTracker(MotionEvent event) {
+        if (mVelocityTracker == null) {
+            return;
+        }
+
+        // Add movement to velocity tracker using raw screen X and Y coordinates instead
+        // of window coordinates because the window frame may be moving at the same time.
+        float deltaX = event.getRawX() - event.getX();
+        float deltaY = event.getRawY() - event.getY();
+        event.offsetLocation(deltaX, deltaY);
+        mVelocityTracker.addMovement(event);
+        event.offsetLocation(-deltaX, -deltaY);
+    }
+
+    private void initOrResetVelocityTracker() {
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        } else {
+            mVelocityTracker.clear();
+        }
+    }
+
+    private void recycleVelocityTracker() {
+        if (mVelocityTracker != null) {
+            mVelocityTracker.recycle();
+            mVelocityTracker = null;
+        }
+    }
+
+    /**
+     * Dumps the {@link PipTouchState}.
+     */
+    public void dump(PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "mAllowTouches=" + mAllowTouches);
+        pw.println(innerPrefix + "mAllowInputEvents=" + mAllowInputEvents);
+        pw.println(innerPrefix + "mActivePointerId=" + mActivePointerId);
+        pw.println(innerPrefix + "mLastTouchDisplayId=" + mLastTouchDisplayId);
+        pw.println(innerPrefix + "mDownTouch=" + mDownTouch);
+        pw.println(innerPrefix + "mDownDelta=" + mDownDelta);
+        pw.println(innerPrefix + "mLastTouch=" + mLastTouch);
+        pw.println(innerPrefix + "mLastDelta=" + mLastDelta);
+        pw.println(innerPrefix + "mVelocity=" + mVelocity);
+        pw.println(innerPrefix + "mIsUserInteracting=" + mIsUserInteracting);
+        pw.println(innerPrefix + "mIsDragging=" + mIsDragging);
+        pw.println(innerPrefix + "mStartedDragging=" + mStartedDragging);
+        pw.println(innerPrefix + "mAllowDraggingOffscreen=" + mAllowDraggingOffscreen);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index d15da4a..b179b5b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -24,6 +24,9 @@
 import static com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP;
 import static com.android.wm.shell.transition.Transitions.TRANSIT_RESIZE_PIP;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.PictureInPictureParams;
@@ -44,6 +47,7 @@
 import com.android.wm.shell.common.pip.PipBoundsState;
 import com.android.wm.shell.common.pip.PipMenuController;
 import com.android.wm.shell.common.pip.PipUtils;
+import com.android.wm.shell.pip.PipContentOverlay;
 import com.android.wm.shell.pip.PipTransitionController;
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.transition.Transitions;
@@ -55,6 +59,11 @@
  */
 public class PipTransition extends PipTransitionController {
     private static final String TAG = PipTransition.class.getSimpleName();
+    /**
+     * The fixed start delay in ms when fading out the content overlay from bounds animation.
+     * The fadeout animation is guaranteed to start after the client has drawn under the new config.
+     */
+    private static final int CONTENT_OVERLAY_FADE_OUT_DELAY_MS = 400;
 
     private final Context mContext;
     private final PipScheduler mPipScheduler;
@@ -230,10 +239,13 @@
 
         PictureInPictureParams params = pipChange.getTaskInfo().pictureInPictureParams;
         Rect srcRectHint = params.getSourceRectHint();
+        Rect startBounds = pipChange.getStartAbsBounds();
         Rect destinationBounds = pipChange.getEndAbsBounds();
 
+        WindowContainerTransaction finishWct = new WindowContainerTransaction();
+
         if (PipBoundsAlgorithm.isSourceRectHintValidForEnterPip(srcRectHint, destinationBounds)) {
-            float scale = (float) destinationBounds.width() / srcRectHint.width();
+            final float scale = (float) destinationBounds.width() / srcRectHint.width();
             startTransaction.setWindowCrop(pipLeash, srcRectHint);
             startTransaction.setPosition(pipLeash,
                     destinationBounds.left - srcRectHint.left * scale,
@@ -244,13 +256,62 @@
             // in multi-activity case, reparenting yields new reset scales coming from pinned task.
             startTransaction.setScale(pipLeash, scale, scale);
         } else {
-            // TODO(b/325481148): handle the case with invalid srcRectHint (using overlay).
+            final float scaleX = (float) destinationBounds.width() / startBounds.width();
+            final float scaleY = (float) destinationBounds.height() / startBounds.height();
+            final int overlaySize = PipContentOverlay.PipAppIconOverlay
+                    .getOverlaySize(mPipScheduler.mSwipePipToHomeAppBounds, destinationBounds);
+            SurfaceControl overlayLeash = mPipScheduler.mSwipePipToHomeOverlay;
+
+            startTransaction.setPosition(pipLeash, destinationBounds.left, destinationBounds.top)
+                    .setScale(pipLeash, scaleX, scaleY)
+                    .setWindowCrop(pipLeash, startBounds)
+                    .reparent(overlayLeash, pipLeash)
+                    .setLayer(overlayLeash, Integer.MAX_VALUE);
+
+            if (mPipTaskToken != null) {
+                SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
+                tx.addTransactionCommittedListener(mPipScheduler.getMainExecutor(),
+                                this::onClientDrawAtTransitionEnd)
+                        .setScale(overlayLeash, 1f, 1f)
+                        .setPosition(overlayLeash,
+                                (destinationBounds.width() - overlaySize) / 2f,
+                                (destinationBounds.height() - overlaySize) / 2f);
+                finishWct.setBoundsChangeTransaction(mPipTaskToken, tx);
+            }
         }
         startTransaction.apply();
-        finishCallback.onTransitionFinished(null);
+
+        // Note that finishWct should be free of any actual WM state changes; we are using
+        // it for syncing with the client draw after delayed configuration changes are dispatched.
+        finishCallback.onTransitionFinished(finishWct.isEmpty() ? null : finishWct);
         return true;
     }
 
+    private void onClientDrawAtTransitionEnd() {
+        startOverlayFadeoutAnimation();
+    }
+
+    private void startOverlayFadeoutAnimation() {
+        ValueAnimator animator = ValueAnimator.ofFloat(1f, 0f);
+        animator.setDuration(CONTENT_OVERLAY_FADE_OUT_DELAY_MS);
+        animator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
+                SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
+                tx.remove(mPipScheduler.mSwipePipToHomeOverlay);
+                tx.apply();
+                mPipScheduler.mSwipePipToHomeOverlay = null;
+            }
+        });
+        animator.addUpdateListener(animation -> {
+            float alpha = (float) animation.getAnimatedValue();
+            SurfaceControl.Transaction tx = new SurfaceControl.Transaction();
+            tx.setAlpha(mPipScheduler.mSwipePipToHomeOverlay, alpha).apply();
+        });
+        animator.start();
+    }
+
     private boolean startBoundsTypeEnterAnimation(@NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction startTransaction,
             @NonNull SurfaceControl.Transaction finishTransaction,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index 235456c..3b4fb9f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -1069,7 +1069,7 @@
         }
 
         private boolean allAppsAreTranslucent(ArrayList<TaskState> tasks) {
-            if (tasks == null || tasks.isEmpty()) {
+            if (tasks == null) {
                 return false;
             }
             for (int i = tasks.size() - 1; i >= 0; --i) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index c3261bb..088bb48 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -138,6 +138,7 @@
     public static final int EXIT_REASON_RECREATE_SPLIT = 10;
     public static final int EXIT_REASON_FULLSCREEN_SHORTCUT = 11;
     public static final int EXIT_REASON_DESKTOP_MODE = 12;
+    public static final int EXIT_REASON_FULLSCREEN_REQUEST = 13;
     @IntDef(value = {
             EXIT_REASON_UNKNOWN,
             EXIT_REASON_APP_DOES_NOT_SUPPORT_MULTIWINDOW,
@@ -151,7 +152,8 @@
             EXIT_REASON_CHILD_TASK_ENTER_PIP,
             EXIT_REASON_RECREATE_SPLIT,
             EXIT_REASON_FULLSCREEN_SHORTCUT,
-            EXIT_REASON_DESKTOP_MODE
+            EXIT_REASON_DESKTOP_MODE,
+            EXIT_REASON_FULLSCREEN_REQUEST
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface ExitReason{}
@@ -1054,6 +1056,8 @@
                 return "RECREATE_SPLIT";
             case EXIT_REASON_DESKTOP_MODE:
                 return "DESKTOP_MODE";
+            case EXIT_REASON_FULLSCREEN_REQUEST:
+                return "FULLSCREEN_REQUEST";
             default:
                 return "unknown reason, reason int = " + exitReason;
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index d5434e3..fadc970 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -59,6 +59,7 @@
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DESKTOP_MODE;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DEVICE_FOLDED;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_DRAG_DIVIDER;
+import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_FULLSCREEN_REQUEST;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_FULLSCREEN_SHORTCUT;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RECREATE_SPLIT;
 import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_RETURN_HOME;
@@ -2615,6 +2616,13 @@
                     prepareEnterSplitScreen(out);
                     mSplitTransitions.setEnterTransition(transition, request.getRemoteTransition(),
                             TRANSIT_SPLIT_SCREEN_PAIR_OPEN, !mIsDropEntering);
+                } else if (inFullscreen && isSplitScreenVisible()) {
+                    // If the trigger task is in fullscreen and in split, exit split and place
+                    // task on top
+                    final int stageType = getStageOfTask(triggerTask.taskId);
+                    prepareExitSplitScreen(stageType, out);
+                    mSplitTransitions.setDismissTransition(transition, stageType,
+                            EXIT_REASON_FULLSCREEN_REQUEST);
                 }
             } else if (isOpening && inFullscreen) {
                 final int activityType = triggerTask.getActivityType();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index 9a48922..beead6a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -90,12 +90,14 @@
     @Override
     @NonNull
     Rect calculateValidDragArea() {
+        final Context displayContext = mDisplayController.getDisplayContext(mTaskInfo.displayId);
+        if (displayContext == null) return new Rect();
         final int leftButtonsWidth = loadDimensionPixelSize(mContext.getResources(),
                 R.dimen.caption_left_buttons_width);
 
         // On a smaller screen, don't require as much empty space on screen, as offscreen
         // drags will be restricted too much.
-        final int requiredEmptySpaceId = mDisplayController.getDisplayContext(mTaskInfo.displayId)
+        final int requiredEmptySpaceId = displayContext
                 .getResources().getConfiguration().smallestScreenWidthDp >= 600
                 ? R.dimen.freeform_required_visible_empty_space_in_header :
                 R.dimen.small_screen_required_visible_empty_space_in_header;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 6d2109c..a0f9c6b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -25,22 +25,16 @@
 import static android.view.MotionEvent.ACTION_CANCEL;
 import static android.view.MotionEvent.ACTION_HOVER_ENTER;
 import static android.view.MotionEvent.ACTION_HOVER_EXIT;
+import static android.view.MotionEvent.ACTION_HOVER_MOVE;
+import static android.view.MotionEvent.ACTION_MOVE;
 import static android.view.MotionEvent.ACTION_UP;
 import static android.view.WindowInsets.Type.statusBars;
 
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
 import static com.android.wm.shell.compatui.AppCompatUtils.isSingleTopActivityTranslucent;
-import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR;
 import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
-import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR;
-import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR;
-import static com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.FREEFORM_ANIMATION_DURATION;
-import static com.android.wm.shell.windowdecor.MoveToDesktopAnimator.DRAG_FREEFORM_SCALE;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
@@ -364,7 +358,7 @@
 
     private class DesktopModeTouchEventListener extends GestureDetector.SimpleOnGestureListener
             implements View.OnClickListener, View.OnTouchListener, View.OnLongClickListener,
-            View.OnGenericMotionListener , DragDetector.MotionEventHandler {
+            View.OnGenericMotionListener, DragDetector.MotionEventHandler {
         private static final int CLOSE_MAXIMIZE_MENU_DELAY_MS = 150;
 
         private final int mTaskId;
@@ -493,6 +487,12 @@
                         (int) e.getRawX(), (int) e.getRawY());
                 final boolean isTransparentCaption =
                         TaskInfoKt.isTransparentCaptionBarAppearance(decoration.mTaskInfo);
+                // MotionEvent's coordinates are relative to view, we want location in window
+                // to offset position relative to caption as a whole.
+                int[] viewLocation = new int[2];
+                v.getLocationInWindow(viewLocation);
+                final boolean isResizeEvent = decoration.shouldResizeListenerHandleEvent(e,
+                        new Point(viewLocation[0], viewLocation[1]));
                 // The caption window may be a spy window when the caption background is
                 // transparent, which means events will fall through to the app window. Make
                 // sure to cancel these events if they do not happen in the intersection of the
@@ -500,11 +500,11 @@
                 // the drag-move or other caption gestures should take priority outside those
                 // regions.
                 mShouldPilferCaptionEvents = !(downInCustomizableCaptionRegion
-                        && downInExclusionRegion && isTransparentCaption);
+                        && downInExclusionRegion && isTransparentCaption) && !isResizeEvent;
             }
 
             if (!mShouldPilferCaptionEvents) {
-                // The event will be handled by a window below.
+                // The event will be handled by a window below or pilfered by resize handler.
                 return false;
             }
             // Otherwise pilfer so that windows below receive cancellations for this gesture, and
@@ -551,8 +551,14 @@
                     // Re-hovering over any of the maximize menu views should keep the menu open by
                     // cancelling any attempts to close the menu.
                     mMainHandler.removeCallbacks(mCloseMaximizeWindowRunnable);
+                    if (id != R.id.maximize_window) {
+                        decoration.onMaximizeMenuHoverEnter(id, ev);
+                    }
                 }
                 return true;
+            } else if (ev.getAction() == ACTION_HOVER_MOVE
+                    && MaximizeMenu.Companion.isMaximizeMenuView(id)) {
+                decoration.onMaximizeMenuHoverMove(id, ev);
             } else if (ev.getAction() == ACTION_HOVER_EXIT) {
                 if (!decoration.isMaximizeMenuActive() && id == R.id.maximize_window) {
                     decoration.onMaximizeWindowHoverExit();
@@ -562,6 +568,8 @@
                     // menu view to another.
                     mMainHandler.postDelayed(mCloseMaximizeWindowRunnable,
                             CLOSE_MAXIMIZE_MENU_DELAY_MS);
+                } else if (MaximizeMenu.Companion.isMaximizeMenuView(id)) {
+                    decoration.onMaximizeMenuHoverExit(id, ev);
                 }
                 return true;
             }
@@ -604,7 +612,7 @@
                     // prevent the button's ripple effect from showing.
                     return !touchingButton;
                 }
-                case MotionEvent.ACTION_MOVE: {
+                case ACTION_MOVE: {
                     // If a decor's resize drag zone is active, don't also try to reposition it.
                     if (decoration.isHandlingDragResize()) break;
                     decoration.closeMaximizeMenu();
@@ -788,7 +796,7 @@
         if (relevantDecor == null || relevantDecor.checkTouchEventInCaption(ev)) {
             return;
         }
-
+        relevantDecor.updateHoverAndPressStatus(ev);
         final int action = ev.getActionMasked();
         if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
             if (!mTransitionDragActive) {
@@ -805,52 +813,55 @@
      */
     private void handleCaptionThroughStatusBar(MotionEvent ev,
             DesktopModeWindowDecoration relevantDecor) {
+        if (relevantDecor == null) {
+            if (ev.getActionMasked() == ACTION_UP) {
+                mMoveToDesktopAnimator = null;
+                mTransitionDragActive = false;
+            }
+            return;
+        }
         switch (ev.getActionMasked()) {
+            case MotionEvent.ACTION_HOVER_EXIT:
+            case MotionEvent.ACTION_HOVER_MOVE:
+            case MotionEvent.ACTION_HOVER_ENTER: {
+                relevantDecor.updateHoverAndPressStatus(ev);
+                break;
+            }
             case MotionEvent.ACTION_DOWN: {
                 // Begin drag through status bar if applicable.
-                if (relevantDecor != null) {
-                    mDragToDesktopAnimationStartBounds.set(
-                            relevantDecor.mTaskInfo.configuration.windowConfiguration.getBounds());
-                    boolean dragFromStatusBarAllowed = false;
-                    if (DesktopModeStatus.isEnabled()) {
-                        // In proto2 any full screen or multi-window task can be dragged to
-                        // freeform.
-                        final int windowingMode = relevantDecor.mTaskInfo.getWindowingMode();
-                        dragFromStatusBarAllowed = windowingMode == WINDOWING_MODE_FULLSCREEN
-                                || windowingMode == WINDOWING_MODE_MULTI_WINDOW;
-                    }
+                relevantDecor.checkTouchEvent(ev);
+                relevantDecor.updateHoverAndPressStatus(ev);
+                mDragToDesktopAnimationStartBounds.set(
+                        relevantDecor.mTaskInfo.configuration.windowConfiguration.getBounds());
+                boolean dragFromStatusBarAllowed = false;
+                if (DesktopModeStatus.isEnabled()) {
+                    // In proto2 any full screen or multi-window task can be dragged to
+                    // freeform.
+                    final int windowingMode = relevantDecor.mTaskInfo.getWindowingMode();
+                    dragFromStatusBarAllowed = windowingMode == WINDOWING_MODE_FULLSCREEN
+                            || windowingMode == WINDOWING_MODE_MULTI_WINDOW;
+                }
 
-                    if (dragFromStatusBarAllowed
-                            && relevantDecor.checkTouchEventInFocusedCaptionHandle(ev)) {
-                        mTransitionDragActive = true;
-                    }
+                if (dragFromStatusBarAllowed
+                        && relevantDecor.checkTouchEventInFocusedCaptionHandle(ev)) {
+                    mTransitionDragActive = true;
                 }
                 break;
             }
             case MotionEvent.ACTION_UP: {
-                if (relevantDecor == null) {
-                    mMoveToDesktopAnimator = null;
-                    mTransitionDragActive = false;
-                    return;
-                }
                 if (mTransitionDragActive) {
-                    final DesktopModeVisualIndicator.IndicatorType indicatorType =
-                            mDesktopTasksController.updateVisualIndicator(relevantDecor.mTaskInfo,
-                                    relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY());
+                    mDesktopTasksController.updateVisualIndicator(relevantDecor.mTaskInfo,
+                            relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY());
                     mTransitionDragActive = false;
-                    if (indicatorType == TO_DESKTOP_INDICATOR
-                            || indicatorType == TO_SPLIT_LEFT_INDICATOR
-                            || indicatorType == TO_SPLIT_RIGHT_INDICATOR) {
-                        if (DesktopModeStatus.isEnabled()) {
-                            animateToDesktop(relevantDecor, ev);
-                        }
-                        mMoveToDesktopAnimator = null;
-                        return;
-                    } else if (mMoveToDesktopAnimator != null) {
+                    if (mMoveToDesktopAnimator != null) {
+                        // Though this isn't a hover event, we need to update handle's hover state
+                        // as it likely will change.
+                        relevantDecor.updateHoverAndPressStatus(ev);
                         mDesktopTasksController.onDragPositioningEndThroughStatusBar(
                                 new PointF(ev.getRawX(), ev.getRawY()),
                                 relevantDecor.mTaskInfo,
-                                calculateFreeformBounds(ev.getDisplayId(), DRAG_FREEFORM_SCALE));
+                                calculateFreeformBounds(ev.getDisplayId(),
+                                        DesktopTasksController.DESKTOP_MODE_INITIAL_BOUNDS_SCALE));
                         mMoveToDesktopAnimator = null;
                         return;
                     } else {
@@ -859,11 +870,11 @@
                         mDesktopTasksController.releaseVisualIndicator();
                     }
                 }
-                relevantDecor.checkClickEvent(ev);
+                relevantDecor.checkTouchEvent(ev);
                 break;
             }
 
-            case MotionEvent.ACTION_MOVE: {
+            case ACTION_MOVE: {
                 if (relevantDecor == null) {
                     return;
                 }
@@ -919,54 +930,6 @@
                 (int) (screenHeight * (adjustmentPercentage + scale)));
     }
 
-    /**
-     * Blocks relayout until transition is finished and transitions to Desktop
-     */
-    private void animateToDesktop(DesktopModeWindowDecoration relevantDecor,
-            MotionEvent ev) {
-        centerAndMoveToDesktopWithAnimation(relevantDecor, ev);
-    }
-
-    /**
-     * Animates a window to the center, grows to freeform size, and transitions to Desktop Mode.
-     * @param relevantDecor the window decor of the task to be animated
-     * @param ev the motion event that triggers the animation
-     * TODO(b/315527000): This animation needs to be adjusted to allow snap left/right cases.
-     *  Currently fullscreen -> split snap still animates to center screen before readjusting.
-     */
-    private void centerAndMoveToDesktopWithAnimation(DesktopModeWindowDecoration relevantDecor,
-            MotionEvent ev) {
-        ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
-        animator.setDuration(FREEFORM_ANIMATION_DURATION);
-        final SurfaceControl sc = relevantDecor.mTaskSurface;
-        final Rect endBounds = calculateFreeformBounds(ev.getDisplayId(), DRAG_FREEFORM_SCALE);
-        final Transaction t = mTransactionFactory.get();
-        final float diffX = endBounds.centerX() - ev.getRawX();
-        final float diffY = endBounds.top - ev.getRawY();
-        final float startingX = ev.getRawX() - DRAG_FREEFORM_SCALE
-                * mDragToDesktopAnimationStartBounds.width() / 2;
-
-        animator.addUpdateListener(animation -> {
-            final float animatorValue = (float) animation.getAnimatedValue();
-            final float x = startingX + diffX * animatorValue;
-            final float y = ev.getRawY() + diffY * animatorValue;
-            t.setPosition(sc, x, y);
-            t.apply();
-        });
-        animator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mDesktopTasksController.onDragPositioningEndThroughStatusBar(
-                        new PointF(ev.getRawX(), ev.getRawY()),
-                        relevantDecor.mTaskInfo,
-                        calculateFreeformBounds(ev.getDisplayId(),
-                                DesktopTasksController
-                                        .DESKTOP_MODE_INITIAL_BOUNDS_SCALE));
-            }
-        });
-        animator.start();
-    }
-
     @Nullable
     private DesktopModeWindowDecoration getRelevantWindowDecor(MotionEvent ev) {
         final DesktopModeWindowDecoration focusedDecor = getFocusedDecor();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
index ad290c6..d0879434 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java
@@ -19,6 +19,8 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.windowingModeToString;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_UP;
 
 import static com.android.launcher3.icons.BaseIconFactory.MODE_DEFAULT;
 
@@ -401,7 +403,8 @@
         final int menuHeight = loadDimensionPixelSize(
                 resources, R.dimen.desktop_mode_maximize_menu_height);
 
-        float menuLeft = (mPositionInParent.x + maximizeButtonLocation[0]);
+        float menuLeft = (mPositionInParent.x + maximizeButtonLocation[0] - ((float) (menuWidth
+                - maximizeWindowButton.getWidth()) / 2));
         float menuTop = (mPositionInParent.y + captionHeight);
         final float menuRight = menuLeft + menuWidth;
         final float menuBottom = menuTop + menuHeight;
@@ -421,6 +424,10 @@
         return mHandleMenu != null;
     }
 
+    boolean shouldResizeListenerHandleEvent(MotionEvent e, Point offset) {
+        return mDragResizeListener != null && mDragResizeListener.shouldHandleEvent(e, offset);
+    }
+
     boolean isHandlingDragResize() {
         return mDragResizeListener != null && mDragResizeListener.isHandlingDragResize();
     }
@@ -709,27 +716,48 @@
     }
 
     /**
-     * Check a passed MotionEvent if a click has occurred on any button on this caption
+     * Check a passed MotionEvent if it has occurred on any button related to this decor.
      * Note this should only be called when a regular onClick is not possible
      * (i.e. the button was clicked through status bar layer)
      *
      * @param ev the MotionEvent to compare
      */
-    void checkClickEvent(MotionEvent ev) {
+    void checkTouchEvent(MotionEvent ev) {
         if (mResult.mRootView == null) return;
-        if (!isHandleMenuActive()) {
-            // Click if point in caption handle view
-            final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
-            final View handle = caption.findViewById(R.id.caption_handle);
-            if (checkTouchEventInFocusedCaptionHandle(ev)) {
-                mOnCaptionButtonClickListener.onClick(handle);
-            }
-        } else {
-            mHandleMenu.checkClickEvent(ev);
+        final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
+        final View handle = caption.findViewById(R.id.caption_handle);
+        final boolean inHandle = !isHandleMenuActive()
+                && checkTouchEventInFocusedCaptionHandle(ev);
+        final int action = ev.getActionMasked();
+        if (action == ACTION_UP && inHandle) {
+            handle.performClick();
+        }
+        if (isHandleMenuActive()) {
+            mHandleMenu.checkMotionEvent(ev);
             closeHandleMenuIfNeeded(ev);
         }
     }
 
+    /**
+     * Updates hover and pressed status of views in this decoration. Should only be called
+     * when status cannot be updated normally (i.e. the button is hovered through status
+     * bar layer).
+     * @param ev the MotionEvent to compare against.
+     */
+    void updateHoverAndPressStatus(MotionEvent ev) {
+        if (mResult.mRootView == null) return;
+        final View handle = mResult.mRootView.findViewById(R.id.caption_handle);
+        final boolean inHandle = !isHandleMenuActive()
+                && checkTouchEventInFocusedCaptionHandle(ev);
+        final int action = ev.getActionMasked();
+        // The comparison against ACTION_UP is needed for the cancel drag to desktop case.
+        handle.setHovered(inHandle && action != ACTION_UP);
+        handle.setPressed(inHandle && action == ACTION_DOWN);
+        if (isHandleMenuActive()) {
+            mHandleMenu.checkMotionEvent(ev);
+        }
+    }
+
     private boolean pointInView(View v, float x, float y) {
         return v != null && v.getLeft() <= x && v.getRight() >= x
                 && v.getTop() <= y && v.getBottom() >= y;
@@ -767,7 +795,7 @@
      */
     private Region getGlobalExclusionRegion() {
         Region exclusionRegion;
-        if (mTaskInfo.isResizeable) {
+        if (mDragResizeListener != null && mTaskInfo.isResizeable) {
             exclusionRegion = mDragResizeListener.getCornersRegion();
         } else {
             exclusionRegion = new Region();
@@ -804,16 +832,34 @@
                 .setAnimatingTaskResize(animatingTaskResize);
     }
 
+    /** Called when there is a {@Link ACTION_HOVER_EXIT} on the maximize window button. */
     void onMaximizeWindowHoverExit() {
         ((DesktopModeAppControlsWindowDecorationViewHolder) mWindowDecorViewHolder)
                 .onMaximizeWindowHoverExit();
     }
 
+    /** Called when there is a {@Link ACTION_HOVER_ENTER} on the maximize window button. */
     void onMaximizeWindowHoverEnter() {
         ((DesktopModeAppControlsWindowDecorationViewHolder) mWindowDecorViewHolder)
                 .onMaximizeWindowHoverEnter();
     }
 
+    /** Called when there is a {@Link ACTION_HOVER_ENTER} on a view in the maximize menu. */
+    void onMaximizeMenuHoverEnter(int id, MotionEvent ev) {
+        mMaximizeMenu.onMaximizeMenuHoverEnter(id, ev);
+    }
+
+    /** Called when there is a {@Link ACTION_HOVER_MOVE} on a view in the maximize menu. */
+    void onMaximizeMenuHoverMove(int id, MotionEvent ev) {
+        mMaximizeMenu.onMaximizeMenuHoverMove(id, ev);
+    }
+
+    /** Called when there is a {@Link ACTION_HOVER_EXIT} on a view in the maximize menu. */
+    void onMaximizeMenuHoverExit(int id, MotionEvent ev) {
+        mMaximizeMenu.onMaximizeMenuHoverExit(id, ev);
+    }
+
+
     @Override
     public String toString() {
         return "{"
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index e83e5d1e..97eb4a4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -31,6 +31,7 @@
 import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP;
 
 import android.content.Context;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.hardware.input.InputManager;
@@ -321,6 +322,10 @@
         }
     }
 
+    boolean shouldHandleEvent(MotionEvent e, Point offset) {
+        return mInputEventReceiver.shouldHandleEvent(e, offset);
+    }
+
     boolean isHandlingDragResize() {
         return mInputEventReceiver.isHandlingEvents();
     }
@@ -408,18 +413,14 @@
             boolean result = false;
             // Check if this is a touch event vs mouse event.
             // Touch events are tracked in four corners. Other events are tracked in resize edges.
-            boolean isTouch = (e.getSource() & SOURCE_TOUCHSCREEN) == SOURCE_TOUCHSCREEN;
+            boolean isTouch = isTouchEvent(e);
             switch (e.getActionMasked()) {
                 case MotionEvent.ACTION_DOWN: {
-                    float x = e.getX(0);
-                    float y = e.getY(0);
-                    if (isTouch) {
-                        mShouldHandleEvents = isInCornerBounds(x, y);
-                    } else {
-                        mShouldHandleEvents = isInResizeHandleBounds(x, y);
-                    }
+                    mShouldHandleEvents = shouldHandleEvent(e, isTouch, new Point() /* offset */);
                     if (mShouldHandleEvents) {
                         mDragPointerId = e.getPointerId(0);
+                        float x = e.getX(0);
+                        float y = e.getY(0);
                         float rawX = e.getRawX(0);
                         float rawY = e.getRawY(0);
                         int ctrlType = calculateCtrlType(isTouch, x, y);
@@ -447,7 +448,6 @@
                 }
                 case MotionEvent.ACTION_UP:
                 case MotionEvent.ACTION_CANCEL: {
-                    mInputManager.pilferPointers(mInputChannel.getToken());
                     if (mShouldHandleEvents) {
                         int dragPointerIndex = e.findPointerIndex(mDragPointerId);
                         final Rect taskBounds = mCallback.onDragPositioningEnd(
@@ -638,5 +638,25 @@
                 mLastCursorType = cursorType;
             }
         }
+
+        private boolean shouldHandleEvent(MotionEvent e, Point offset) {
+            return shouldHandleEvent(e, isTouchEvent(e), offset);
+        }
+
+        private boolean shouldHandleEvent(MotionEvent e, boolean isTouch, Point offset) {
+            boolean result;
+            final float x = e.getX(0) + offset.x;
+            final float y = e.getY(0) + offset.y;
+            if (isTouch) {
+                result = isInCornerBounds(x, y);
+            } else {
+                result = isInResizeHandleBounds(x, y);
+            }
+            return result;
+        }
+
+        private boolean isTouchEvent(MotionEvent e) {
+            return (e.getSource() & SOURCE_TOUCHSCREEN) == SOURCE_TOUCHSCREEN;
+        }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
index 3d0dd31..65adcee 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenu.java
@@ -20,6 +20,8 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_UP;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -140,7 +142,8 @@
      * Set up interactive elements of handle menu's app info pill.
      */
     private void setupAppInfoPill(View handleMenu) {
-        final ImageButton collapseBtn = handleMenu.findViewById(R.id.collapse_menu_button);
+        final HandleMenuImageButton collapseBtn =
+                handleMenu.findViewById(R.id.collapse_menu_button);
         final ImageView appIcon = handleMenu.findViewById(R.id.application_icon);
         final TextView appName = handleMenu.findViewById(R.id.application_name);
         collapseBtn.setOnClickListener(mOnClickListener);
@@ -172,9 +175,9 @@
         final ColorStateList activeColorStateList = iconColors[1];
         final int windowingMode = mTaskInfo.getWindowingMode();
         fullscreenBtn.setImageTintList(windowingMode == WINDOWING_MODE_FULLSCREEN
-                        ? activeColorStateList : inActiveColorStateList);
+                ? activeColorStateList : inActiveColorStateList);
         splitscreenBtn.setImageTintList(windowingMode == WINDOWING_MODE_MULTI_WINDOW
-                        ? activeColorStateList : inActiveColorStateList);
+                ? activeColorStateList : inActiveColorStateList);
         floatingBtn.setImageTintList(windowingMode == WINDOWING_MODE_PINNED
                 ? activeColorStateList : inActiveColorStateList);
         desktopBtn.setImageTintList(windowingMode == WINDOWING_MODE_FREEFORM
@@ -243,24 +246,31 @@
     }
 
     /**
-     * Check a passed MotionEvent if a click has occurred on any button on this caption
-     * Note this should only be called when a regular onClick is not possible
+     * Check a passed MotionEvent if a click or hover has occurred on any button on this caption
+     * Note this should only be called when a regular onClick/onHover is not possible
      * (i.e. the button was clicked through status bar layer)
      *
      * @param ev the MotionEvent to compare against.
      */
-    void checkClickEvent(MotionEvent ev) {
+    void checkMotionEvent(MotionEvent ev) {
         final View handleMenu = mHandleMenuWindow.mWindowViewHost.getView();
-        final ImageButton collapse = handleMenu.findViewById(R.id.collapse_menu_button);
-        // Translate the input point from display coordinates to the same space as the collapse
-        // button, meaning its parent (app info pill view).
-        final PointF inputPoint = new PointF(ev.getX() - mHandleMenuPosition.x,
-                ev.getY() - mHandleMenuPosition.y);
-        if (pointInView(collapse, inputPoint.x, inputPoint.y)) {
-            mOnClickListener.onClick(collapse);
+        final HandleMenuImageButton collapse = handleMenu.findViewById(R.id.collapse_menu_button);
+        final PointF inputPoint = translateInputToLocalSpace(ev);
+        final boolean inputInCollapseButton = pointInView(collapse, inputPoint.x, inputPoint.y);
+        final int action = ev.getActionMasked();
+        collapse.setHovered(inputInCollapseButton && action != ACTION_UP);
+        collapse.setPressed(inputInCollapseButton && action == ACTION_DOWN);
+        if (action == ACTION_UP && inputInCollapseButton) {
+            collapse.performClick();
         }
     }
 
+    // Translate the input point from display coordinates to the same space as the handle menu.
+    private PointF translateInputToLocalSpace(MotionEvent ev) {
+        return new PointF(ev.getX() - mHandleMenuPosition.x,
+                ev.getY() - mHandleMenuPosition.y);
+    }
+
     /**
      * A valid menu input is one of the following:
      * An input that happens in the menu views.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuImageButton.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuImageButton.kt
new file mode 100644
index 0000000..2fda3ea
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuImageButton.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.wm.shell.windowdecor
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.widget.ImageButton
+
+/**
+ * A custom [ImageButton] that intentionally does not handle hover events.
+ * This is due to the hover events being handled by [DesktopModeWindowDecorViewModel]
+ * in order to take the status bar layer into account. Handling it in both classes results in a
+ * flicker when the hover moves from outside to inside status bar layer.
+ */
+class HandleMenuImageButton(context: Context?, attrs: AttributeSet?) :
+    ImageButton(context, attrs) {
+    override fun onHoverEvent(motionEvent: MotionEvent): Boolean {
+        return false
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
index b82f7ca..899b7cc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MaximizeMenu.kt
@@ -33,7 +33,11 @@
 import android.view.WindowManager
 import android.view.WindowlessWindowManager
 import android.widget.Button
+import android.widget.FrameLayout
+import android.widget.LinearLayout
 import android.window.TaskConstants
+import androidx.core.content.withStyledAttributes
+import com.android.internal.R.attr.colorAccentPrimary
 import com.android.wm.shell.R
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.common.DisplayController
@@ -70,6 +74,12 @@
     private val menuWidth = loadDimensionPixelSize(R.dimen.desktop_mode_maximize_menu_width)
     private val menuHeight = loadDimensionPixelSize(R.dimen.desktop_mode_maximize_menu_height)
 
+    private lateinit var snapRightButton: Button
+    private lateinit var snapLeftButton: Button
+    private lateinit var maximizeButton: Button
+    private lateinit var maximizeButtonLayout: FrameLayout
+    private lateinit var snapButtonsLayout: LinearLayout
+
     /** Position the menu relative to the caption's position. */
     fun positionMenu(position: PointF, t: Transaction) {
         menuPosition.set(position)
@@ -150,23 +160,23 @@
         maximizeMenuView.setOnGenericMotionListener(onGenericMotionListener)
         maximizeMenuView.setOnTouchListener(onTouchListener)
 
-        val maximizeButton = maximizeMenuView.requireViewById<Button>(
-                R.id.maximize_menu_maximize_button
-        )
+        maximizeButtonLayout = maximizeMenuView.requireViewById(
+                R.id.maximize_menu_maximize_button_layout)
+
+        maximizeButton = maximizeMenuView.requireViewById(R.id.maximize_menu_maximize_button)
         maximizeButton.setOnClickListener(onClickListener)
         maximizeButton.setOnGenericMotionListener(onGenericMotionListener)
 
-        val snapRightButton = maximizeMenuView.requireViewById<Button>(
-                R.id.maximize_menu_snap_right_button
-        )
+        snapRightButton = maximizeMenuView.requireViewById(R.id.maximize_menu_snap_right_button)
         snapRightButton.setOnClickListener(onClickListener)
         snapRightButton.setOnGenericMotionListener(onGenericMotionListener)
 
-        val snapLeftButton = maximizeMenuView.requireViewById<Button>(
-                R.id.maximize_menu_snap_left_button
-        )
+        snapLeftButton = maximizeMenuView.requireViewById(R.id.maximize_menu_snap_left_button)
         snapLeftButton.setOnClickListener(onClickListener)
         snapLeftButton.setOnGenericMotionListener(onGenericMotionListener)
+
+        snapButtonsLayout = maximizeMenuView.requireViewById(R.id.maximize_menu_snap_menu_layout)
+        snapButtonsLayout.setOnGenericMotionListener(onGenericMotionListener)
     }
 
     /**
@@ -190,11 +200,77 @@
         return maximizeMenu?.mWindowViewHost?.view?.isLaidOut ?: false
     }
 
+    fun onMaximizeMenuHoverEnter(viewId: Int, ev: MotionEvent) {
+        setSnapButtonsColorOnHover(viewId, ev)
+    }
+
+    fun onMaximizeMenuHoverMove(viewId: Int, ev: MotionEvent) {
+        setSnapButtonsColorOnHover(viewId, ev)
+    }
+
+    fun onMaximizeMenuHoverExit(id: Int, ev: MotionEvent) {
+        val inSnapMenuBounds = ev.x >= 0 && ev.x <= snapButtonsLayout.width &&
+                ev.y >= 0 && ev.y <= snapButtonsLayout.height
+        val colorList = decorWindowContext.getColorStateList(
+                R.color.desktop_mode_maximize_menu_button_color_selector)
+
+        if (id == R.id.maximize_menu_maximize_button) {
+            maximizeButton.background?.setTintList(colorList)
+            maximizeButtonLayout.setBackgroundResource(
+                    R.drawable.desktop_mode_maximize_menu_layout_background)
+        } else if (id == R.id.maximize_menu_snap_menu_layout && !inSnapMenuBounds) {
+            // After exiting the snap menu layout area, checks to see that user is not still
+            // hovering within the snap menu layout bounds which would indicate that the user is
+            // hovering over a snap button within the snap menu layout rather than having exited.
+            snapLeftButton.background?.setTintList(colorList)
+            snapLeftButton.background?.alpha = 255
+            snapRightButton.background?.setTintList(colorList)
+            snapRightButton.background?.alpha = 255
+            snapButtonsLayout.setBackgroundResource(
+                    R.drawable.desktop_mode_maximize_menu_layout_background)
+        }
+    }
+
+    private fun setSnapButtonsColorOnHover(viewId: Int, ev: MotionEvent) {
+        decorWindowContext.withStyledAttributes(null, intArrayOf(colorAccentPrimary), 0, 0) {
+            val materialColor = getColor(0, 0)
+            val snapMenuCenter = snapButtonsLayout.width / 2
+            if (viewId == R.id.maximize_menu_maximize_button) {
+                // Highlight snap maximize window button
+                maximizeButton.background?.setTint(materialColor)
+                maximizeButtonLayout.setBackgroundResource(
+                        R.drawable.desktop_mode_maximize_menu_layout_background_on_hover)
+            } else if (viewId == R.id.maximize_menu_snap_left_button ||
+                    (viewId == R.id.maximize_menu_snap_menu_layout && ev.x <= snapMenuCenter)) {
+                // Highlight snap left button
+                snapRightButton.background?.setTint(materialColor)
+                snapLeftButton.background?.setTint(materialColor)
+                snapButtonsLayout.setBackgroundResource(
+                        R.drawable.desktop_mode_maximize_menu_layout_background_on_hover)
+                snapRightButton.background?.alpha = 102
+                snapLeftButton.background?.alpha = 255
+            } else if (viewId == R.id.maximize_menu_snap_right_button ||
+                    (viewId == R.id.maximize_menu_snap_menu_layout && ev.x > snapMenuCenter)) {
+                // Highlight snap right button
+                snapRightButton.background?.setTint(materialColor)
+                snapLeftButton.background?.setTint(materialColor)
+                snapButtonsLayout.setBackgroundResource(
+                        R.drawable.desktop_mode_maximize_menu_layout_background_on_hover)
+                snapRightButton.background?.alpha = 255
+                snapLeftButton.background?.alpha = 102
+            }
+        }
+    }
+
     companion object {
         fun isMaximizeMenuView(@IdRes viewId: Int): Boolean {
-            return viewId == R.id.maximize_menu || viewId == R.id.maximize_menu_maximize_button ||
+            return viewId == R.id.maximize_menu ||
+                    viewId == R.id.maximize_menu_maximize_button ||
+                    viewId == R.id.maximize_menu_maximize_button_layout ||
                     viewId == R.id.maximize_menu_snap_left_button ||
-                    viewId == R.id.maximize_menu_snap_right_button
+                    viewId == R.id.maximize_menu_snap_right_button ||
+                    viewId == R.id.maximize_menu_snap_menu_layout ||
+                    viewId == R.id.maximize_menu_snap_menu_layout
         }
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt
index af05523..987aadf 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt
@@ -31,15 +31,16 @@
 
     private val animatedTaskWidth
         get() = dragToDesktopAnimator.animatedValue as Float * startBounds.width()
+    val scale: Float
+        get() = dragToDesktopAnimator.animatedValue as Float
     private val dragToDesktopAnimator: ValueAnimator = ValueAnimator.ofFloat(1f,
             DRAG_FREEFORM_SCALE)
             .setDuration(ANIMATION_DURATION.toLong())
             .apply {
                 val t = SurfaceControl.Transaction()
                 val cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
-                addUpdateListener { animation ->
-                    val animatorValue = animation.animatedValue as Float
-                    t.setScale(taskSurface, animatorValue, animatorValue)
+                addUpdateListener {
+                    t.setScale(taskSurface, scale, scale)
                             .setCornerRadius(taskSurface, cornerRadius)
                             .apply()
                 }
@@ -90,9 +91,9 @@
     }
 
     /**
-     * Ends the animation, setting the scale and position to the final animation value
+     * Cancels the animation, intended to be used when another animator will take over.
      */
-    fun endAnimator() {
-        dragToDesktopAnimator.end()
+    fun cancelAnimator() {
+        dragToDesktopAnimator.cancel()
     }
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenAutoEnterPipOnGoToHomeTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenAutoEnterPipOnGoToHomeTest.kt
index b94989d..12e395d 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenAutoEnterPipOnGoToHomeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/FromSplitScreenAutoEnterPipOnGoToHomeTest.kt
@@ -24,6 +24,7 @@
 import android.tools.flicker.legacy.LegacyFlickerTestFactory
 import android.tools.helpers.WindowUtils
 import android.tools.traces.parsers.toFlickerComponent
+import androidx.test.filters.FlakyTest
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.helpers.SimpleAppHelper
 import com.android.server.wm.flicker.testapp.ActivityOptions
@@ -143,6 +144,10 @@
         }
     }
 
+    @FlakyTest(bugId = 293133362)
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
+
     companion object {
         @Parameterized.Parameters(name = "{0}")
         @JvmStatic
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt
index 9b51538..e85da30 100644
--- a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/NetflixEnterPipTest.kt
@@ -18,7 +18,6 @@
 
 import android.Manifest
 import android.platform.test.annotations.Postsubmit
-import android.tools.NavBar
 import android.tools.Rotation
 import android.tools.traces.component.ComponentNameMatcher
 import android.tools.device.apphelpers.NetflixAppHelper
@@ -26,6 +25,7 @@
 import android.tools.flicker.legacy.FlickerBuilder
 import android.tools.flicker.legacy.LegacyFlickerTest
 import android.tools.flicker.legacy.LegacyFlickerTestFactory
+import android.tools.helpers.WindowUtils
 import androidx.test.filters.RequiresDevice
 import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
 import org.junit.Assume
@@ -62,6 +62,8 @@
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 open class NetflixEnterPipTest(flicker: LegacyFlickerTest) : AppsEnterPipTransition(flicker) {
     override val standardAppHelper: NetflixAppHelper = NetflixAppHelper(instrumentation)
+    private val startingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_90)
+    private val endingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_0)
 
     override val permissions: Array<String> = arrayOf(Manifest.permission.POST_NOTIFICATIONS)
 
@@ -134,6 +136,31 @@
         // Netflix plays in immersive fullscreen mode, so taskbar will be gone at some point
     }
 
+    @Postsubmit
+    @Test
+    override fun pipWindowRemainInsideVisibleBounds() {
+        // during the transition we assert the center point is within the display bounds, since it
+        // might go outside of bounds as we resize from landscape fullscreen to destination bounds,
+        // and once the animation is over we assert that it's fully within the display bounds, at
+        // which point the device also performs orientation change from landscape to portrait
+        flicker.assertWmVisibleRegion(standardAppHelper.packageNameMatcher) {
+            regionsCenterPointInside(startingBounds).then().coversAtMost(endingBounds)
+        }
+    }
+
+    @Postsubmit
+    @Test
+    override fun pipLayerOrOverlayRemainInsideVisibleBounds() {
+        // during the transition we assert the center point is within the display bounds, since it
+        // might go outside of bounds as we resize from landscape fullscreen to destination bounds,
+        // and once the animation is over we assert that it's fully within the display bounds, at
+        // which point the device also performs orientation change from landscape to portrait
+        // since Netflix uses source rect hint, there is no PiP overlay present
+        flicker.assertLayersVisibleRegion(standardAppHelper.packageNameMatcher) {
+            regionsCenterPointInside(startingBounds).then().coversAtMost(endingBounds)
+        }
+    }
+
     companion object {
         /**
          * Creates the test configurations.
@@ -145,8 +172,7 @@
         @JvmStatic
         fun getParams() =
             LegacyFlickerTestFactory.nonRotationTests(
-                supportedRotations = listOf(Rotation.ROTATION_0),
-                supportedNavigationModes = listOf(NavBar.MODE_GESTURAL)
+                supportedRotations = listOf(Rotation.ROTATION_0)
             )
     }
 }
diff --git a/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt
new file mode 100644
index 0000000..de8e7c3
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/flicker/pip/src/com/android/wm/shell/flicker/pip/apps/YouTubeEnterPipToOtherOrientationTest.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.flicker.pip.apps
+
+import android.Manifest
+import android.platform.test.annotations.Postsubmit
+import android.tools.Rotation
+import android.tools.traces.component.ComponentNameMatcher
+import android.tools.device.apphelpers.YouTubeAppHelper
+import android.tools.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.flicker.legacy.FlickerBuilder
+import android.tools.flicker.legacy.LegacyFlickerTest
+import android.tools.flicker.legacy.LegacyFlickerTestFactory
+import android.tools.helpers.WindowUtils
+import androidx.test.filters.RequiresDevice
+import com.android.server.wm.flicker.statusBarLayerPositionAtEnd
+import org.junit.Assume
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test entering pip from YouTube app by interacting with the app UI
+ *
+ * To run this test: `atest WMShellFlickerTests:YouTubeEnterPipTest`
+ *
+ * Actions:
+ * ```
+ *     Launch YouTube and start playing a video
+ *     Make the video fullscreen, aka immersive mode
+ *     Go home to enter PiP
+ * ```
+ *
+ * Notes:
+ * ```
+ *     1. Some default assertions (e.g., nav bar, status bar and screen covered)
+ *        are inherited from [PipTransition]
+ *     2. Part of the test setup occurs automatically via
+ *        [android.tools.flicker.legacy.runner.TransitionRunner],
+ *        including configuring navigation mode, initial orientation and ensuring no
+ *        apps are running before setup
+ * ```
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class YouTubeEnterPipToOtherOrientationTest(flicker: LegacyFlickerTest) :
+    YouTubeEnterPipTest(flicker) {
+    override val standardAppHelper: YouTubeAppHelper = YouTubeAppHelper(instrumentation)
+    private val startingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_90)
+    private val endingBounds = WindowUtils.getDisplayBounds(Rotation.ROTATION_0)
+
+    override val permissions: Array<String> = arrayOf(Manifest.permission.POST_NOTIFICATIONS)
+
+    override val defaultEnterPip: FlickerBuilder.() -> Unit = {
+        setup {
+            standardAppHelper.launchViaIntent(
+                wmHelper,
+                YouTubeAppHelper.getYoutubeVideoIntent("HPcEAtoXXLA"),
+                ComponentNameMatcher(YouTubeAppHelper.PACKAGE_NAME, "")
+            )
+            standardAppHelper.enterFullscreen()
+            standardAppHelper.waitForVideoPlaying()
+        }
+    }
+
+    override val thisTransition: FlickerBuilder.() -> Unit = {
+        transitions { tapl.goHomeFromImmersiveFullscreenApp() }
+    }
+
+    @Postsubmit
+    @Test
+    override fun taskBarLayerIsVisibleAtStartAndEnd() {
+        Assume.assumeTrue(flicker.scenario.isTablet)
+        // YouTube starts in immersive fullscreen mode, so taskbar bar is not visible at start
+        flicker.assertLayersStart { this.isInvisible(ComponentNameMatcher.TASK_BAR) }
+        flicker.assertLayersEnd { this.isVisible(ComponentNameMatcher.TASK_BAR) }
+    }
+
+    @Postsubmit
+    @Test
+    override fun pipWindowRemainInsideVisibleBounds() {
+        // during the transition we assert the center point is within the display bounds, since it
+        // might go outside of bounds as we resize from landscape fullscreen to destination bounds,
+        // and once the animation is over we assert that it's fully within the display bounds, at
+        // which point the device also performs orientation change from landscape to portrait
+        flicker.assertWmVisibleRegion(standardAppHelper.packageNameMatcher) {
+            regionsCenterPointInside(startingBounds).then().coversAtMost(endingBounds)
+        }
+    }
+
+    @Postsubmit
+    @Test
+    override fun pipLayerOrOverlayRemainInsideVisibleBounds() {
+        // during the transition we assert the center point is within the display bounds, since it
+        // might go outside of bounds as we resize from landscape fullscreen to destination bounds,
+        // and once the animation is over we assert that it's fully within the display bounds, at
+        // which point the device also performs orientation change from landscape to portrait
+        // since YouTube uses source rect hint, there is no PiP overlay present
+        flicker.assertLayersVisibleRegion(standardAppHelper.packageNameMatcher) {
+            regionsCenterPointInside(startingBounds).then().coversAtMost(endingBounds)
+        }
+    }
+
+    @Postsubmit
+    @Test
+    override fun taskBarWindowIsAlwaysVisible() {
+        // YouTube plays in immersive fullscreen mode, so taskbar will be gone at some point
+    }
+
+    @Postsubmit
+    @Test
+    override fun statusBarLayerIsVisibleAtStartAndEnd() {
+        // YouTube starts in immersive fullscreen mode, so status bar is not visible at start
+        flicker.assertLayersStart { this.isInvisible(ComponentNameMatcher.STATUS_BAR) }
+        flicker.assertLayersEnd { this.isVisible(ComponentNameMatcher.STATUS_BAR) }
+    }
+
+    @Postsubmit
+    @Test
+    override fun statusBarLayerPositionAtStartAndEnd() {
+        // YouTube starts in immersive fullscreen mode, so status bar is not visible at start
+        flicker.statusBarLayerPositionAtEnd()
+    }
+
+    @Postsubmit
+    @Test
+    override fun statusBarWindowIsAlwaysVisible() {
+        // YouTube plays in immersive fullscreen mode, so taskbar will be gone at some point
+    }
+
+    companion object {
+        /**
+         * Creates the test configurations.
+         *
+         * See [LegacyFlickerTestFactory.nonRotationTests] for configuring repetitions, screen
+         * orientation and navigation modes.
+         */
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams() =
+            LegacyFlickerTestFactory.nonRotationTests(
+                supportedRotations = listOf(Rotation.ROTATION_0)
+            )
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
index 4e9a9d6..9cc3a98 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
@@ -179,12 +179,13 @@
         val displayBounds =
             wmHelper.currentState.layerState.displays.firstOrNull { !it.isVirtual }?.layerStackSpace
                 ?: error("Display not found")
+        val swipeXCoordinate = displayBounds.centerX() / 2
 
         // Pull down the notifications
         device.swipe(
-            displayBounds.centerX(),
+            swipeXCoordinate,
             5,
-            displayBounds.centerX(),
+            swipeXCoordinate,
             displayBounds.bottom,
             50 /* steps */
         )
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 2919782..2ff1ddd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -69,7 +69,6 @@
 import com.android.wm.shell.sysui.ShellInit;
 import com.android.wm.shell.sysui.ShellSharedConstants;
 
-
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -182,7 +181,9 @@
     }
 
     RemoteAnimationTarget createAnimationTarget() {
-        SurfaceControl topWindowLeash = new SurfaceControl();
+        SurfaceControl topWindowLeash = new SurfaceControl.Builder()
+                .setName("FakeLeash")
+                .build();
         return new RemoteAnimationTarget(-1, RemoteAnimationTarget.MODE_CLOSING, topWindowLeash,
                 false, new Rect(), new Rect(), -1,
                 new Point(0, 0), new Rect(), new Rect(), new WindowConfiguration(),
@@ -557,6 +558,23 @@
     }
 
     @Test
+    public void skipsCancelWithoutStart() throws RemoteException {
+        final int type = BackNavigationInfo.TYPE_CALLBACK;
+        final ResultListener result = new ResultListener();
+        createNavigationInfo(new BackNavigationInfo.Builder()
+                .setType(type)
+                .setOnBackInvokedCallback(mAppCallback)
+                .setOnBackNavigationDone(new RemoteCallback(result)));
+        doMotionEvent(MotionEvent.ACTION_CANCEL, 0);
+        mShellExecutor.flushAll();
+
+        verify(mAppCallback, never()).onBackStarted(any());
+        verify(mAppCallback, never()).onBackProgressed(any());
+        verify(mAppCallback, never()).onBackInvoked();
+        verify(mAppCallback, never()).onBackCancelled();
+    }
+
+    @Test
     public void testBackToActivity() throws RemoteException {
         final CrossActivityBackAnimation animation = new CrossActivityBackAnimation(
                 mContext, mAnimationBackground, mRootTaskDisplayAreaOrganizer);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
index 445f74a..0c45d52 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeTaskRepositoryTest.kt
@@ -16,8 +16,10 @@
 
 package com.android.wm.shell.desktopmode
 
+import android.graphics.Rect
 import android.testing.AndroidTestingRunner
 import android.view.Display.DEFAULT_DISPLAY
+import android.view.Display.INVALID_DISPLAY
 import androidx.test.filters.SmallTest
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.TestShellExecutor
@@ -237,6 +239,27 @@
         assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(4)
     }
 
+    /**
+     * When a task vanishes, the displayId of the task is set to INVALID_DISPLAY.
+     * This tests that task is removed from the last parent display when it vanishes.
+     */
+    @Test
+    fun updateVisibleFreeformTasks_removeVisibleTasksRemovesTaskWithInvalidDisplay() {
+        val listener = TestVisibilityListener()
+        val executor = TestShellExecutor()
+        repo.addVisibleTasksListener(listener, executor)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 1, visible = true)
+        repo.updateVisibleFreeformTasks(DEFAULT_DISPLAY, taskId = 2, visible = true)
+        executor.flushAll()
+
+        assertThat(listener.visibleTasksCountOnDefaultDisplay).isEqualTo(2)
+        repo.updateVisibleFreeformTasks(INVALID_DISPLAY, taskId = 1, visible = false)
+        executor.flushAll()
+
+        assertThat(listener.visibleChangesOnDefaultDisplay).isEqualTo(3)
+        assertThat(listener.visibleTasksCountOnDefaultDisplay).isEqualTo(1)
+    }
+
     @Test
     fun getVisibleTaskCount() {
         // No tasks, count is 0
@@ -384,6 +407,31 @@
         assertThat(listener.stashedOnSecondaryDisplay).isTrue()
     }
 
+    @Test
+    fun removeFreeformTask_removesTaskBoundsBeforeMaximize() {
+        val taskId = 1
+        repo.saveBoundsBeforeMaximize(taskId, Rect(0, 0, 200, 200))
+        repo.removeFreeformTask(taskId)
+        assertThat(repo.removeBoundsBeforeMaximize(taskId)).isNull()
+    }
+
+    @Test
+    fun saveBoundsBeforeMaximize_boundsSavedByTaskId() {
+        val taskId = 1
+        val bounds = Rect(0, 0, 200, 200)
+        repo.saveBoundsBeforeMaximize(taskId, bounds)
+        assertThat(repo.removeBoundsBeforeMaximize(taskId)).isEqualTo(bounds)
+    }
+
+    @Test
+    fun removeBoundsBeforeMaximize_returnsNullAfterBoundsRemoved() {
+        val taskId = 1
+        val bounds = Rect(0, 0, 200, 200)
+        repo.saveBoundsBeforeMaximize(taskId, bounds)
+        repo.removeBoundsBeforeMaximize(taskId)
+        assertThat(repo.removeBoundsBeforeMaximize(taskId)).isNull()
+    }
+
     class TestListener : DesktopModeTaskRepository.ActiveTasksListener {
         var activeChangesOnDefaultDisplay = 0
         var activeChangesOnSecondaryDisplay = 0
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 4fbf2bd..93a967e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -95,9 +95,10 @@
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.mock
 import org.mockito.Mockito.verify
-import org.mockito.kotlin.times
-import org.mockito.Mockito.`when` as whenever
+import org.mockito.kotlin.atLeastOnce
+import org.mockito.kotlin.capture
 import org.mockito.quality.Strictness
+import org.mockito.Mockito.`when` as whenever
 
 /**
  * Test class for {@link DesktopTasksController}
@@ -116,13 +117,14 @@
     @Mock lateinit var shellCommandHandler: ShellCommandHandler
     @Mock lateinit var shellController: ShellController
     @Mock lateinit var displayController: DisplayController
+    @Mock lateinit var displayLayout: DisplayLayout
     @Mock lateinit var shellTaskOrganizer: ShellTaskOrganizer
     @Mock lateinit var syncQueue: SyncTransactionQueue
     @Mock lateinit var rootTaskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer
     @Mock lateinit var transitions: Transitions
     @Mock lateinit var exitDesktopTransitionHandler: ExitDesktopTaskTransitionHandler
     @Mock lateinit var enterDesktopTransitionHandler: EnterDesktopTaskTransitionHandler
-    @Mock lateinit var mToggleResizeDesktopTaskTransitionHandler:
+    @Mock lateinit var toggleResizeDesktopTaskTransitionHandler:
             ToggleResizeDesktopTaskTransitionHandler
     @Mock lateinit var dragToDesktopTransitionHandler: DragToDesktopTransitionHandler
     @Mock lateinit var launchAdjacentController: LaunchAdjacentController
@@ -154,6 +156,10 @@
 
         whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenAnswer { runningTasks }
         whenever(transitions.startTransition(anyInt(), any(), isNull())).thenAnswer { Binder() }
+        whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout)
+        whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
+                (i.arguments.first() as Rect).set(STABLE_BOUNDS)
+            }
 
         controller = createController()
         controller.setSplitScreenController(splitScreenController)
@@ -179,7 +185,7 @@
             transitions,
             enterDesktopTransitionHandler,
             exitDesktopTransitionHandler,
-            mToggleResizeDesktopTaskTransitionHandler,
+            toggleResizeDesktopTaskTransitionHandler,
             dragToDesktopTransitionHandler,
             desktopModeTaskRepository,
             desktopModeLoggerTransitionObserver,
@@ -929,15 +935,74 @@
         controller.enterSplit(DEFAULT_DISPLAY, false)
 
         verify(splitScreenController).requestEnterSplitSelect(
-            task2,
-            any(),
-            SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT,
-            task2.configuration.windowConfiguration.bounds
+                task2,
+                any(),
+                SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT,
+                task2.configuration.windowConfiguration.bounds
         )
     }
 
-    private fun setUpFreeformTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
-        val task = createFreeformTask(displayId)
+    @Test
+    fun toggleBounds_togglesToStableBounds() {
+        val bounds = Rect(0, 0, 100, 100)
+        val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds)
+
+        controller.toggleDesktopTaskSize(task)
+        // Assert bounds set to stable bounds
+        val wct = getLatestToggleResizeDesktopTaskWct()
+        assertThat(wct.changes[task.token.asBinder()]?.configuration?.windowConfiguration?.bounds)
+                .isEqualTo(STABLE_BOUNDS)
+    }
+
+    @Test
+    fun toggleBounds_lastBoundsBeforeMaximizeSaved() {
+        val bounds = Rect(0, 0, 100, 100)
+        val task = setUpFreeformTask(DEFAULT_DISPLAY, bounds)
+
+        controller.toggleDesktopTaskSize(task)
+        assertThat(desktopModeTaskRepository.removeBoundsBeforeMaximize(task.taskId))
+                .isEqualTo(bounds)
+    }
+
+    @Test
+    fun toggleBounds_togglesFromStableBoundsToLastBoundsBeforeMaximize() {
+        val boundsBeforeMaximize = Rect(0, 0, 100, 100)
+        val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize)
+
+        // Maximize
+        controller.toggleDesktopTaskSize(task)
+        task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS)
+
+        // Restore
+        controller.toggleDesktopTaskSize(task)
+
+        // Assert bounds set to last bounds before maximize
+        val wct = getLatestToggleResizeDesktopTaskWct()
+        assertThat(wct.changes[task.token.asBinder()]?.configuration?.windowConfiguration?.bounds)
+                .isEqualTo(boundsBeforeMaximize)
+    }
+
+    @Test
+    fun toggleBounds_removesLastBoundsBeforeMaximizeAfterRestoringBounds() {
+        val boundsBeforeMaximize = Rect(0, 0, 100, 100)
+        val task = setUpFreeformTask(DEFAULT_DISPLAY, boundsBeforeMaximize)
+
+        // Maximize
+        controller.toggleDesktopTaskSize(task)
+        task.configuration.windowConfiguration.bounds.set(STABLE_BOUNDS)
+
+        // Restore
+        controller.toggleDesktopTaskSize(task)
+
+        // Assert last bounds before maximize removed after use
+        assertThat(desktopModeTaskRepository.removeBoundsBeforeMaximize(task.taskId)).isNull()
+    }
+
+    private fun setUpFreeformTask(
+            displayId: Int = DEFAULT_DISPLAY,
+            bounds: Rect? = null
+    ): RunningTaskInfo {
+        val task = createFreeformTask(displayId, bounds)
         whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
         desktopModeTaskRepository.addActiveTask(displayId, task.taskId)
         desktopModeTaskRepository.addOrMoveFreeformTaskToTop(task.taskId)
@@ -1004,6 +1069,18 @@
         return arg.value
     }
 
+    private fun getLatestToggleResizeDesktopTaskWct(): WindowContainerTransaction {
+        val arg: ArgumentCaptor<WindowContainerTransaction> =
+                ArgumentCaptor.forClass(WindowContainerTransaction::class.java)
+        if (ENABLE_SHELL_TRANSITIONS) {
+            verify(toggleResizeDesktopTaskTransitionHandler, atLeastOnce())
+                    .startTransition(capture(arg))
+        } else {
+            verify(shellTaskOrganizer).applyTransaction(capture(arg))
+        }
+        return arg.value
+    }
+
     private fun getLatestMoveToDesktopWct(): WindowContainerTransaction {
         val arg = ArgumentCaptor.forClass(WindowContainerTransaction::class.java)
         if (ENABLE_SHELL_TRANSITIONS) {
@@ -1042,6 +1119,7 @@
 
     companion object {
         const val SECOND_DISPLAY = 2
+        private val STABLE_BOUNDS = Rect(0, 0, 1000, 1000)
     }
 }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
index 2f6f320..52da7fb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTestHelpers.kt
@@ -22,6 +22,7 @@
 import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
 import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
 import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
+import android.graphics.Rect
 import android.view.Display.DEFAULT_DISPLAY
 import com.android.wm.shell.MockToken
 import com.android.wm.shell.TestRunningTaskInfoBuilder
@@ -31,13 +32,17 @@
         /** Create a task that has windowing mode set to [WINDOWING_MODE_FREEFORM] */
         @JvmStatic
         @JvmOverloads
-        fun createFreeformTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
+        fun createFreeformTask(
+                displayId: Int = DEFAULT_DISPLAY,
+                bounds: Rect? = null
+        ): RunningTaskInfo {
             return TestRunningTaskInfoBuilder()
                     .setDisplayId(displayId)
                     .setToken(MockToken().token())
                     .setActivityType(ACTIVITY_TYPE_STANDARD)
                     .setWindowingMode(WINDOWING_MODE_FREEFORM)
                     .setLastActiveTime(100)
+                    .apply { bounds?.let { setBounds(it) }}
                     .build()
         }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
index 98e90d6..2ade3fb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
@@ -190,7 +190,7 @@
         handler.cancelDragToDesktopTransition()
 
         // Cancel animation should run since it had already started.
-        verify(dragAnimator).endAnimator()
+        verify(dragAnimator).cancelAnimator()
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhoneSizeSpecSourceTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhoneSizeSpecSourceTest.java
index 3d5cd69..85f1da5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhoneSizeSpecSourceTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PhoneSizeSpecSourceTest.java
@@ -16,33 +16,26 @@
 
 package com.android.wm.shell.pip.phone;
 
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
 import android.content.res.Resources;
-import android.os.SystemProperties;
 import android.testing.AndroidTestingRunner;
 import android.util.Size;
 import android.view.DisplayInfo;
 
-import com.android.dx.mockito.inline.extended.StaticMockitoSession;
+import com.android.wm.shell.R;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.pip.PhoneSizeSpecSource;
 import com.android.wm.shell.common.pip.PipDisplayLayoutState;
 import com.android.wm.shell.common.pip.SizeSpecSource;
 
-import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.exceptions.misusing.InvalidUseOfMatchersException;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -63,15 +56,24 @@
     private static final float DEFAULT_PERCENT = 0.6f;
     /** Minimum sizing percentage */
     private static final float MIN_PERCENT = 0.5f;
+    /** Threshold to determine if a Display is square-ish. */
+    private static final float SQUARE_DISPLAY_THRESHOLD = 0.95f;
+    /** Default sizing percentage for square-ish Display. */
+    private static final float SQUARE_DISPLAY_DEFAULT_PERCENT = 0.5f;
+    /** Minimum sizing percentage for square-ish Display. */
+    private static final float SQUARE_DISPLAY_MIN_PERCENT = 0.4f;
     /** Aspect ratio that the new PIP size spec logic optimizes for. */
     private static final float OPTIMIZED_ASPECT_RATIO = 9f / 16;
 
-    /** A map of aspect ratios to be tested to expected sizes */
-    private static Map<Float, Size> sExpectedMaxSizes;
-    private static Map<Float, Size> sExpectedDefaultSizes;
-    private static Map<Float, Size> sExpectedMinSizes;
-    /** A static mockito session object to mock {@link SystemProperties} */
-    private static StaticMockitoSession sStaticMockitoSession;
+    /** Maps of aspect ratios to be tested to expected sizes on non-square Display. */
+    private static Map<Float, Size> sNonSquareDisplayExpectedMaxSizes;
+    private static Map<Float, Size> sNonSquareDisplayExpectedDefaultSizes;
+    private static Map<Float, Size> sNonSquareDisplayExpectedMinSizes;
+
+    /** Maps of aspect ratios to be tested to expected sizes on square Display. */
+    private static Map<Float, Size> sSquareDisplayExpectedMaxSizes;
+    private static Map<Float, Size> sSquareDisplayExpectedDefaultSizes;
+    private static Map<Float, Size> sSquareDisplayExpectedMinSizes;
 
     @Mock private Context mContext;
     @Mock private Resources mResources;
@@ -80,49 +82,55 @@
     private SizeSpecSource mSizeSpecSource;
 
     /**
-     * Sets up static Mockito session for SystemProperties and mocks necessary static methods.
+     * Initializes the map with the aspect ratios to be tested and corresponding expected max sizes.
+     * This is to initialize the expectations on non-square Display only.
      */
-    private static void setUpStaticSystemPropertiesSession() {
-        sStaticMockitoSession = mockitoSession()
-                .mockStatic(SystemProperties.class).startMocking();
-        when(SystemProperties.get(anyString(), anyString())).thenAnswer(invocation -> {
-            String property = invocation.getArgument(0);
-            if (property.equals("com.android.wm.shell.pip.phone.def_percentage")) {
-                return Float.toString(DEFAULT_PERCENT);
-            } else if (property.equals("com.android.wm.shell.pip.phone.min_percentage")) {
-                return Float.toString(MIN_PERCENT);
-            }
+    private static void initNonSquareDisplayExpectedSizes() {
+        sNonSquareDisplayExpectedMaxSizes = new HashMap<>();
+        sNonSquareDisplayExpectedDefaultSizes = new HashMap<>();
+        sNonSquareDisplayExpectedMinSizes = new HashMap<>();
 
-            // throw an exception if illegal arguments are used for these tests
-            throw new InvalidUseOfMatchersException(
-                String.format("Argument %s does not match", property)
-            );
-        });
+        sNonSquareDisplayExpectedMaxSizes.put(16f / 9, new Size(1000, 563));
+        sNonSquareDisplayExpectedDefaultSizes.put(16f / 9, new Size(600, 338));
+        sNonSquareDisplayExpectedMinSizes.put(16f / 9, new Size(501, 282));
+
+        sNonSquareDisplayExpectedMaxSizes.put(4f / 3, new Size(893, 670));
+        sNonSquareDisplayExpectedDefaultSizes.put(4f / 3, new Size(536, 402));
+        sNonSquareDisplayExpectedMinSizes.put(4f / 3, new Size(447, 335));
+
+        sNonSquareDisplayExpectedMaxSizes.put(3f / 4, new Size(670, 893));
+        sNonSquareDisplayExpectedDefaultSizes.put(3f / 4, new Size(402, 536));
+        sNonSquareDisplayExpectedMinSizes.put(3f / 4, new Size(335, 447));
+
+        sNonSquareDisplayExpectedMaxSizes.put(9f / 16, new Size(563, 1001));
+        sNonSquareDisplayExpectedDefaultSizes.put(9f / 16, new Size(338, 601));
+        sNonSquareDisplayExpectedMinSizes.put(9f / 16, new Size(282, 501));
     }
 
     /**
      * Initializes the map with the aspect ratios to be tested and corresponding expected max sizes.
+     * This is to initialize the expectations on square Display only.
      */
-    private static void initExpectedSizes() {
-        sExpectedMaxSizes = new HashMap<>();
-        sExpectedDefaultSizes = new HashMap<>();
-        sExpectedMinSizes = new HashMap<>();
+    private static void initSquareDisplayExpectedSizes() {
+        sSquareDisplayExpectedMaxSizes = new HashMap<>();
+        sSquareDisplayExpectedDefaultSizes = new HashMap<>();
+        sSquareDisplayExpectedMinSizes = new HashMap<>();
 
-        sExpectedMaxSizes.put(16f / 9, new Size(1000, 563));
-        sExpectedDefaultSizes.put(16f / 9, new Size(600, 338));
-        sExpectedMinSizes.put(16f / 9, new Size(501, 282));
+        sSquareDisplayExpectedMaxSizes.put(16f / 9, new Size(1000, 563));
+        sSquareDisplayExpectedDefaultSizes.put(16f / 9, new Size(500, 281));
+        sSquareDisplayExpectedMinSizes.put(16f / 9, new Size(400, 225));
 
-        sExpectedMaxSizes.put(4f / 3, new Size(893, 670));
-        sExpectedDefaultSizes.put(4f / 3, new Size(536, 402));
-        sExpectedMinSizes.put(4f / 3, new Size(447, 335));
+        sSquareDisplayExpectedMaxSizes.put(4f / 3, new Size(893, 670));
+        sSquareDisplayExpectedDefaultSizes.put(4f / 3, new Size(447, 335));
+        sSquareDisplayExpectedMinSizes.put(4f / 3, new Size(357, 268));
 
-        sExpectedMaxSizes.put(3f / 4, new Size(670, 893));
-        sExpectedDefaultSizes.put(3f / 4, new Size(402, 536));
-        sExpectedMinSizes.put(3f / 4, new Size(335, 447));
+        sSquareDisplayExpectedMaxSizes.put(3f / 4, new Size(670, 893));
+        sSquareDisplayExpectedDefaultSizes.put(3f / 4, new Size(335, 447));
+        sSquareDisplayExpectedMinSizes.put(3f / 4, new Size(268, 357));
 
-        sExpectedMaxSizes.put(9f / 16, new Size(563, 1001));
-        sExpectedDefaultSizes.put(9f / 16, new Size(338, 601));
-        sExpectedMinSizes.put(9f / 16, new Size(282, 501));
+        sSquareDisplayExpectedMaxSizes.put(9f / 16, new Size(563, 1001));
+        sSquareDisplayExpectedDefaultSizes.put(9f / 16, new Size(282, 501));
+        sSquareDisplayExpectedMinSizes.put(9f / 16, new Size(225, 400));
     }
 
     private void forEveryTestCaseCheck(Map<Float, Size> expectedSizes,
@@ -137,20 +145,38 @@
 
     @Before
     public void setUp() {
-        initExpectedSizes();
+        initNonSquareDisplayExpectedSizes();
+        initSquareDisplayExpectedSizes();
 
-        when(mResources.getDimensionPixelSize(anyInt())).thenReturn(DEFAULT_MIN_EDGE_SIZE);
-        when(mResources.getFloat(anyInt())).thenReturn(OPTIMIZED_ASPECT_RATIO);
-        when(mResources.getString(anyInt())).thenReturn("0x0");
+        when(mResources.getFloat(R.dimen.config_pipSystemPreferredDefaultSizePercent))
+                .thenReturn(DEFAULT_PERCENT);
+        when(mResources.getFloat(R.dimen.config_pipSystemPreferredMinimumSizePercent))
+                .thenReturn(MIN_PERCENT);
+        when(mResources.getDimensionPixelSize(R.dimen.default_minimal_size_pip_resizable_task))
+                .thenReturn(DEFAULT_MIN_EDGE_SIZE);
+        when(mResources.getFloat(R.dimen.config_pipLargeScreenOptimizedAspectRatio))
+                .thenReturn(OPTIMIZED_ASPECT_RATIO);
+        when(mResources.getString(R.string.config_defaultPictureInPictureScreenEdgeInsets))
+                .thenReturn("0x0");
         when(mResources.getDisplayMetrics())
                 .thenReturn(getContext().getResources().getDisplayMetrics());
+        when(mResources.getFloat(R.dimen.config_pipSquareDisplayThresholdForSystemPreferredSize))
+                .thenReturn(SQUARE_DISPLAY_THRESHOLD);
+        when(mResources.getFloat(
+                R.dimen.config_pipSystemPreferredDefaultSizePercentForSquareDisplay))
+                .thenReturn(SQUARE_DISPLAY_DEFAULT_PERCENT);
+        when(mResources.getFloat(
+                R.dimen.config_pipSystemPreferredMinimumSizePercentForSquareDisplay))
+                .thenReturn(SQUARE_DISPLAY_MIN_PERCENT);
 
         // set up the mock context for spec handler specifically
         when(mContext.getResources()).thenReturn(mResources);
+    }
 
+    private void setupSizeSpecWithDisplayDimension(int width, int height) {
         DisplayInfo displayInfo = new DisplayInfo();
-        displayInfo.logicalWidth = DISPLAY_EDGE_SIZE;
-        displayInfo.logicalHeight = DISPLAY_EDGE_SIZE;
+        displayInfo.logicalWidth = width;
+        displayInfo.logicalHeight = height;
 
         // use the parent context (not the mocked one) to obtain the display layout
         // this is done to avoid unnecessary mocking while allowing for custom display dimensions
@@ -159,38 +185,57 @@
         mPipDisplayLayoutState = new PipDisplayLayoutState(mContext);
         mPipDisplayLayoutState.setDisplayLayout(displayLayout);
 
-        setUpStaticSystemPropertiesSession();
         mSizeSpecSource = new PhoneSizeSpecSource(mContext, mPipDisplayLayoutState);
 
         // no overridden min edge size by default
         mSizeSpecSource.setOverrideMinSize(null);
     }
 
-    @After
-    public void cleanUp() {
-        sStaticMockitoSession.finishMocking();
-    }
-
     @Test
-    public void testGetMaxSize() {
-        forEveryTestCaseCheck(sExpectedMaxSizes,
+    public void testGetMaxSize_nonSquareDisplay() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE * 2, DISPLAY_EDGE_SIZE);
+        forEveryTestCaseCheck(sNonSquareDisplayExpectedMaxSizes,
                 (aspectRatio) -> mSizeSpecSource.getMaxSize(aspectRatio));
     }
 
     @Test
-    public void testGetDefaultSize() {
-        forEveryTestCaseCheck(sExpectedDefaultSizes,
+    public void testGetDefaultSize_nonSquareDisplay() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE * 2, DISPLAY_EDGE_SIZE);
+        forEveryTestCaseCheck(sNonSquareDisplayExpectedDefaultSizes,
                 (aspectRatio) -> mSizeSpecSource.getDefaultSize(aspectRatio));
     }
 
     @Test
-    public void testGetMinSize() {
-        forEveryTestCaseCheck(sExpectedMinSizes,
+    public void testGetMinSize_nonSquareDisplay() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE * 2, DISPLAY_EDGE_SIZE);
+        forEveryTestCaseCheck(sNonSquareDisplayExpectedMinSizes,
+                (aspectRatio) -> mSizeSpecSource.getMinSize(aspectRatio));
+    }
+
+    @Test
+    public void testGetMaxSize_squareDisplay() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE, DISPLAY_EDGE_SIZE);
+        forEveryTestCaseCheck(sSquareDisplayExpectedMaxSizes,
+                (aspectRatio) -> mSizeSpecSource.getMaxSize(aspectRatio));
+    }
+
+    @Test
+    public void testGetDefaultSize_squareDisplay() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE, DISPLAY_EDGE_SIZE);
+        forEveryTestCaseCheck(sSquareDisplayExpectedDefaultSizes,
+                (aspectRatio) -> mSizeSpecSource.getDefaultSize(aspectRatio));
+    }
+
+    @Test
+    public void testGetMinSize_squareDisplay() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE, DISPLAY_EDGE_SIZE);
+        forEveryTestCaseCheck(sSquareDisplayExpectedMinSizes,
                 (aspectRatio) -> mSizeSpecSource.getMinSize(aspectRatio));
     }
 
     @Test
     public void testGetSizeForAspectRatio_noOverrideMinSize() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE * 2, DISPLAY_EDGE_SIZE);
         // an initial size with 16:9 aspect ratio
         Size initSize = new Size(600, 337);
 
@@ -202,6 +247,7 @@
 
     @Test
     public void testGetSizeForAspectRatio_withOverrideMinSize() {
+        setupSizeSpecWithDisplayDimension(DISPLAY_EDGE_SIZE * 2, DISPLAY_EDGE_SIZE);
         // an initial size with a 1:1 aspect ratio
         Size initSize = new Size(OVERRIDE_MIN_EDGE_SIZE, OVERRIDE_MIN_EDGE_SIZE);
         mSizeSpecSource.setOverrideMinSize(initSize);
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
index d7b5914..9d4b426 100644
--- a/libs/androidfw/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -304,7 +304,7 @@
     _ZipEntryRO *zipEntry = reinterpret_cast<_ZipEntryRO*>(entry);
     const int32_t error = ExtractEntryToFile(mHandle, &(zipEntry->entry), fd);
     if (error) {
-        ALOGW("ExtractToMemory failed with %s", ErrorCodeString(error));
+        ALOGW("ExtractToFile failed with %s", ErrorCodeString(error));
         return false;
     }
 
diff --git a/libs/dream/lowlight/tests/Android.bp b/libs/dream/lowlight/tests/Android.bp
index 4dafd0a..4254783 100644
--- a/libs/dream/lowlight/tests/Android.bp
+++ b/libs/dream/lowlight/tests/Android.bp
@@ -27,7 +27,7 @@
         "androidx.test.runner",
         "androidx.test.rules",
         "androidx.test.ext.junit",
-        "animationlib",
+        "//frameworks/libs/systemui:animationlib",
         "frameworks-base-testutils",
         "junit",
         "kotlinx_coroutines_test",
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 341c3e8c..29bb1b9 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",
     ],
@@ -78,13 +79,13 @@
     include_dirs: [
         "external/skia/include/private",
         "external/skia/src/core",
+        "external/skia/src/utils",
     ],
 
     target: {
         android: {
             include_dirs: [
                 "external/skia/src/image",
-                "external/skia/src/utils",
                 "external/skia/src/gpu",
                 "external/skia/src/shaders",
             ],
@@ -529,7 +530,9 @@
         "effects/GainmapRenderer.cpp",
         "pipeline/skia/BackdropFilterDrawable.cpp",
         "pipeline/skia/HolePunch.cpp",
+        "pipeline/skia/SkiaCpuPipeline.cpp",
         "pipeline/skia/SkiaDisplayList.cpp",
+        "pipeline/skia/SkiaPipeline.cpp",
         "pipeline/skia/SkiaRecordingCanvas.cpp",
         "pipeline/skia/StretchMask.cpp",
         "pipeline/skia/RenderNodeDrawable.cpp",
@@ -568,6 +571,7 @@
         "HWUIProperties.sysprop",
         "Interpolator.cpp",
         "JankTracker.cpp",
+        "LayerUpdateQueue.cpp",
         "LightingInfo.cpp",
         "Matrix.cpp",
         "Mesh.cpp",
@@ -604,9 +608,9 @@
                 "pipeline/skia/GLFunctorDrawable.cpp",
                 "pipeline/skia/LayerDrawable.cpp",
                 "pipeline/skia/ShaderCache.cpp",
+                "pipeline/skia/SkiaGpuPipeline.cpp",
                 "pipeline/skia/SkiaMemoryTracer.cpp",
                 "pipeline/skia/SkiaOpenGLPipeline.cpp",
-                "pipeline/skia/SkiaPipeline.cpp",
                 "pipeline/skia/SkiaProfileRenderer.cpp",
                 "pipeline/skia/SkiaVulkanPipeline.cpp",
                 "pipeline/skia/VkFunctorDrawable.cpp",
@@ -630,7 +634,6 @@
                 "DeferredLayerUpdater.cpp",
                 "HardwareBitmapUploader.cpp",
                 "Layer.cpp",
-                "LayerUpdateQueue.cpp",
                 "ProfileDataContainer.cpp",
                 "Readback.cpp",
                 "TreeInfo.cpp",
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index ec53070..c1510d9 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -242,7 +242,7 @@
 
 enum class OverdrawColorSet { Default = 0, Deuteranomaly };
 
-enum class RenderPipelineType { SkiaGL, SkiaVulkan, NotInitialized = 128 };
+enum class RenderPipelineType { SkiaGL, SkiaVulkan, SkiaCpu, NotInitialized = 128 };
 
 enum class StretchEffectBehavior {
     ShaderHWUI,   // Stretch shader in HWUI only, matrix scale in SF
diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig
index 659bcdc..50f8b39 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: "clip_shader"
diff --git a/libs/hwui/pipeline/skia/SkiaCpuPipeline.cpp b/libs/hwui/pipeline/skia/SkiaCpuPipeline.cpp
new file mode 100644
index 0000000..5bbbc10
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaCpuPipeline.cpp
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+
+#include "pipeline/skia/SkiaCpuPipeline.h"
+
+#include <system/window.h>
+
+#include "DeviceInfo.h"
+#include "LightingInfo.h"
+#include "renderthread/Frame.h"
+#include "utils/Color.h"
+
+using namespace android::uirenderer::renderthread;
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+void SkiaCpuPipeline::renderLayersImpl(const LayerUpdateQueue& layers, bool opaque) {
+    // Render all layers that need to be updated, in order.
+    for (size_t i = 0; i < layers.entries().size(); i++) {
+        RenderNode* layerNode = layers.entries()[i].renderNode.get();
+        // only schedule repaint if node still on layer - possible it may have been
+        // removed during a dropped frame, but layers may still remain scheduled so
+        // as not to lose info on what portion is damaged
+        if (CC_UNLIKELY(layerNode->getLayerSurface() == nullptr)) {
+            continue;
+        }
+        bool rendered = renderLayerImpl(layerNode, layers.entries()[i].damage);
+        if (!rendered) {
+            return;
+        }
+    }
+}
+
+// If the given node didn't have a layer surface, or had one of the wrong size, this method
+// creates a new one and returns true. Otherwise does nothing and returns false.
+bool SkiaCpuPipeline::createOrUpdateLayer(RenderNode* node,
+                                          const DamageAccumulator& damageAccumulator,
+                                          ErrorHandler* errorHandler) {
+    // compute the size of the surface (i.e. texture) to be allocated for this layer
+    const int surfaceWidth = ceilf(node->getWidth() / float(LAYER_SIZE)) * LAYER_SIZE;
+    const int surfaceHeight = ceilf(node->getHeight() / float(LAYER_SIZE)) * LAYER_SIZE;
+
+    SkSurface* layer = node->getLayerSurface();
+    if (!layer || layer->width() != surfaceWidth || layer->height() != surfaceHeight) {
+        SkImageInfo info;
+        info = SkImageInfo::Make(surfaceWidth, surfaceHeight, getSurfaceColorType(),
+                                 kPremul_SkAlphaType, getSurfaceColorSpace());
+        SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
+        node->setLayerSurface(SkSurfaces::Raster(info, &props));
+        if (node->getLayerSurface()) {
+            // update the transform in window of the layer to reset its origin wrt light source
+            // position
+            Matrix4 windowTransform;
+            damageAccumulator.computeCurrentTransform(&windowTransform);
+            node->getSkiaLayer()->inverseTransformInWindow.loadInverse(windowTransform);
+        } else {
+            String8 cachesOutput;
+            mRenderThread.cacheManager().dumpMemoryUsage(cachesOutput,
+                                                         &mRenderThread.renderState());
+            ALOGE("%s", cachesOutput.c_str());
+            if (errorHandler) {
+                std::ostringstream err;
+                err << "Unable to create layer for " << node->getName();
+                const int maxTextureSize = DeviceInfo::get()->maxTextureSize();
+                err << ", size " << info.width() << "x" << info.height() << " max size "
+                    << maxTextureSize << " color type " << (int)info.colorType() << " has context "
+                    << (int)(mRenderThread.getGrContext() != nullptr);
+                errorHandler->onError(err.str());
+            }
+        }
+        return true;
+    }
+    return false;
+}
+
+MakeCurrentResult SkiaCpuPipeline::makeCurrent() {
+    return MakeCurrentResult::AlreadyCurrent;
+}
+
+Frame SkiaCpuPipeline::getFrame() {
+    return Frame(mSurface->width(), mSurface->height(), 0);
+}
+
+IRenderPipeline::DrawResult SkiaCpuPipeline::draw(
+        const Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
+        const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
+        const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo,
+        const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler,
+        const HardwareBufferRenderParams& bufferParams, std::mutex& profilerLock) {
+    LightingInfo::updateLighting(lightGeometry, lightInfo);
+    renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, mSurface,
+                SkMatrix::I());
+    return {true, IRenderPipeline::DrawResult::kUnknownTime, android::base::unique_fd{}};
+}
+
+bool SkiaCpuPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior) {
+    if (surface) {
+        ANativeWindowBuffer* buffer;
+        surface->dequeueBuffer(surface, &buffer, nullptr);
+        int width, height;
+        surface->query(surface, NATIVE_WINDOW_WIDTH, &width);
+        surface->query(surface, NATIVE_WINDOW_HEIGHT, &height);
+        SkImageInfo imageInfo =
+                SkImageInfo::Make(width, height, mSurfaceColorType,
+                                  SkAlphaType::kPremul_SkAlphaType, mSurfaceColorSpace);
+        size_t widthBytes = width * imageInfo.bytesPerPixel();
+        void* pixels = buffer->reserved[0];
+        mSurface = SkSurfaces::WrapPixels(imageInfo, pixels, widthBytes);
+    } else {
+        mSurface = sk_sp<SkSurface>();
+    }
+    return true;
+}
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaCpuPipeline.h b/libs/hwui/pipeline/skia/SkiaCpuPipeline.h
new file mode 100644
index 0000000..5a1014c
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaCpuPipeline.h
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "pipeline/skia/SkiaPipeline.h"
+
+namespace android {
+
+namespace uirenderer {
+namespace skiapipeline {
+
+class SkiaCpuPipeline : public SkiaPipeline {
+public:
+    SkiaCpuPipeline(renderthread::RenderThread& thread) : SkiaPipeline(thread) {}
+    ~SkiaCpuPipeline() {}
+
+    bool pinImages(std::vector<SkImage*>& mutableImages) override { return false; }
+    bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override { return false; }
+    void unpinImages() override {}
+
+    // If the given node didn't have a layer surface, or had one of the wrong size, this method
+    // creates a new one and returns true. Otherwise does nothing and returns false.
+    bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
+                             ErrorHandler* errorHandler) override;
+    void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque) override;
+    void setHardwareBuffer(AHardwareBuffer* hardwareBuffer) override {}
+    bool hasHardwareBuffer() override { return false; }
+
+    renderthread::MakeCurrentResult makeCurrent() override;
+    renderthread::Frame getFrame() override;
+    renderthread::IRenderPipeline::DrawResult draw(
+            const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
+            const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
+            const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo,
+            const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler,
+            const renderthread::HardwareBufferRenderParams& bufferParams,
+            std::mutex& profilerLock) override;
+    bool swapBuffers(const renderthread::Frame& frame, IRenderPipeline::DrawResult& drawResult,
+                     const SkRect& screenDirty, FrameInfo* currentFrameInfo,
+                     bool* requireSwap) override {
+        return false;
+    }
+    DeferredLayerUpdater* createTextureLayer() override { return nullptr; }
+    bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior) override;
+    [[nodiscard]] android::base::unique_fd flush() override {
+        return android::base::unique_fd(-1);
+    };
+    void onStop() override {}
+    bool isSurfaceReady() override { return mSurface.get() != nullptr; }
+    bool isContextReady() override { return true; }
+
+    const SkM44& getPixelSnapMatrix() const override {
+        static const SkM44 sSnapMatrix = SkM44();
+        return sSnapMatrix;
+    }
+
+private:
+    sk_sp<SkSurface> mSurface;
+};
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaGpuPipeline.cpp b/libs/hwui/pipeline/skia/SkiaGpuPipeline.cpp
new file mode 100644
index 0000000..7bfbfdc
--- /dev/null
+++ b/libs/hwui/pipeline/skia/SkiaGpuPipeline.cpp
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "pipeline/skia/SkiaGpuPipeline.h"
+
+#include <SkImageAndroid.h>
+#include <gui/TraceUtils.h>
+#include <include/android/SkSurfaceAndroid.h>
+#include <include/gpu/ganesh/SkSurfaceGanesh.h>
+
+using namespace android::uirenderer::renderthread;
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+SkiaGpuPipeline::SkiaGpuPipeline(RenderThread& thread) : SkiaPipeline(thread) {}
+
+SkiaGpuPipeline::~SkiaGpuPipeline() {
+    unpinImages();
+}
+
+void SkiaGpuPipeline::renderLayersImpl(const LayerUpdateQueue& layers, bool opaque) {
+    sk_sp<GrDirectContext> cachedContext;
+
+    // Render all layers that need to be updated, in order.
+    for (size_t i = 0; i < layers.entries().size(); i++) {
+        RenderNode* layerNode = layers.entries()[i].renderNode.get();
+        // only schedule repaint if node still on layer - possible it may have been
+        // removed during a dropped frame, but layers may still remain scheduled so
+        // as not to lose info on what portion is damaged
+        if (CC_UNLIKELY(layerNode->getLayerSurface() == nullptr)) {
+            continue;
+        }
+        bool rendered = renderLayerImpl(layerNode, layers.entries()[i].damage);
+        if (!rendered) {
+            return;
+        }
+        // cache the current context so that we can defer flushing it until
+        // either all the layers have been rendered or the context changes
+        GrDirectContext* currentContext =
+                GrAsDirectContext(layerNode->getLayerSurface()->getCanvas()->recordingContext());
+        if (cachedContext.get() != currentContext) {
+            if (cachedContext.get()) {
+                ATRACE_NAME("flush layers (context changed)");
+                cachedContext->flushAndSubmit();
+            }
+            cachedContext.reset(SkSafeRef(currentContext));
+        }
+    }
+    if (cachedContext.get()) {
+        ATRACE_NAME("flush layers");
+        cachedContext->flushAndSubmit();
+    }
+}
+
+// If the given node didn't have a layer surface, or had one of the wrong size, this method
+// creates a new one and returns true. Otherwise does nothing and returns false.
+bool SkiaGpuPipeline::createOrUpdateLayer(RenderNode* node,
+                                          const DamageAccumulator& damageAccumulator,
+                                          ErrorHandler* errorHandler) {
+    // compute the size of the surface (i.e. texture) to be allocated for this layer
+    const int surfaceWidth = ceilf(node->getWidth() / float(LAYER_SIZE)) * LAYER_SIZE;
+    const int surfaceHeight = ceilf(node->getHeight() / float(LAYER_SIZE)) * LAYER_SIZE;
+
+    SkSurface* layer = node->getLayerSurface();
+    if (!layer || layer->width() != surfaceWidth || layer->height() != surfaceHeight) {
+        SkImageInfo info;
+        info = SkImageInfo::Make(surfaceWidth, surfaceHeight, getSurfaceColorType(),
+                                 kPremul_SkAlphaType, getSurfaceColorSpace());
+        SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
+        SkASSERT(mRenderThread.getGrContext() != nullptr);
+        node->setLayerSurface(SkSurfaces::RenderTarget(mRenderThread.getGrContext(),
+                                                       skgpu::Budgeted::kYes, info, 0,
+                                                       this->getSurfaceOrigin(), &props));
+        if (node->getLayerSurface()) {
+            // update the transform in window of the layer to reset its origin wrt light source
+            // position
+            Matrix4 windowTransform;
+            damageAccumulator.computeCurrentTransform(&windowTransform);
+            node->getSkiaLayer()->inverseTransformInWindow.loadInverse(windowTransform);
+        } else {
+            String8 cachesOutput;
+            mRenderThread.cacheManager().dumpMemoryUsage(cachesOutput,
+                                                         &mRenderThread.renderState());
+            ALOGE("%s", cachesOutput.c_str());
+            if (errorHandler) {
+                std::ostringstream err;
+                err << "Unable to create layer for " << node->getName();
+                const int maxTextureSize = DeviceInfo::get()->maxTextureSize();
+                err << ", size " << info.width() << "x" << info.height() << " max size "
+                    << maxTextureSize << " color type " << (int)info.colorType() << " has context "
+                    << (int)(mRenderThread.getGrContext() != nullptr);
+                errorHandler->onError(err.str());
+            }
+        }
+        return true;
+    }
+    return false;
+}
+
+bool SkiaGpuPipeline::pinImages(std::vector<SkImage*>& mutableImages) {
+    if (!mRenderThread.getGrContext()) {
+        ALOGD("Trying to pin an image with an invalid GrContext");
+        return false;
+    }
+    for (SkImage* image : mutableImages) {
+        if (skgpu::ganesh::PinAsTexture(mRenderThread.getGrContext(), image)) {
+            mPinnedImages.emplace_back(sk_ref_sp(image));
+        } else {
+            return false;
+        }
+    }
+    return true;
+}
+
+void SkiaGpuPipeline::unpinImages() {
+    for (auto& image : mPinnedImages) {
+        skgpu::ganesh::UnpinTexture(mRenderThread.getGrContext(), image.get());
+    }
+    mPinnedImages.clear();
+}
+
+void SkiaGpuPipeline::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
+    GrDirectContext* context = thread.getGrContext();
+    if (context && !bitmap->isHardware()) {
+        ATRACE_FORMAT("Bitmap#prepareToDraw %dx%d", bitmap->width(), bitmap->height());
+        auto image = bitmap->makeImage();
+        if (image.get()) {
+            skgpu::ganesh::PinAsTexture(context, image.get());
+            skgpu::ganesh::UnpinTexture(context, image.get());
+            // A submit is necessary as there may not be a frame coming soon, so without a call
+            // to submit these texture uploads can just sit in the queue building up until
+            // we run out of RAM
+            context->flushAndSubmit();
+        }
+    }
+}
+
+sk_sp<SkSurface> SkiaGpuPipeline::getBufferSkSurface(
+        const renderthread::HardwareBufferRenderParams& bufferParams) {
+    auto bufferColorSpace = bufferParams.getColorSpace();
+    if (mBufferSurface == nullptr || mBufferColorSpace == nullptr ||
+        !SkColorSpace::Equals(mBufferColorSpace.get(), bufferColorSpace.get())) {
+        mBufferSurface = SkSurfaces::WrapAndroidHardwareBuffer(
+                mRenderThread.getGrContext(), mHardwareBuffer, kTopLeft_GrSurfaceOrigin,
+                bufferColorSpace, nullptr, true);
+        mBufferColorSpace = bufferColorSpace;
+    }
+    return mBufferSurface;
+}
+
+void SkiaGpuPipeline::dumpResourceCacheUsage() const {
+    int resources;
+    size_t bytes;
+    mRenderThread.getGrContext()->getResourceCacheUsage(&resources, &bytes);
+    size_t maxBytes = mRenderThread.getGrContext()->getResourceCacheLimit();
+
+    SkString log("Resource Cache Usage:\n");
+    log.appendf("%8d items\n", resources);
+    log.appendf("%8zu bytes (%.2f MB) out of %.2f MB maximum\n", bytes,
+                bytes * (1.0f / (1024.0f * 1024.0f)), maxBytes * (1.0f / (1024.0f * 1024.0f)));
+
+    ALOGD("%s", log.c_str());
+}
+
+void SkiaGpuPipeline::setHardwareBuffer(AHardwareBuffer* buffer) {
+    if (mHardwareBuffer) {
+        AHardwareBuffer_release(mHardwareBuffer);
+        mHardwareBuffer = nullptr;
+    }
+
+    if (buffer) {
+        AHardwareBuffer_acquire(buffer);
+        mHardwareBuffer = buffer;
+    }
+}
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index c8d5987..e4b1f91 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -14,25 +14,25 @@
  * limitations under the License.
  */
 
-#include "SkiaOpenGLPipeline.h"
+#include "pipeline/skia/SkiaOpenGLPipeline.h"
 
-#include <include/gpu/ganesh/SkSurfaceGanesh.h>
-#include <include/gpu/ganesh/gl/GrGLBackendSurface.h>
-#include <include/gpu/gl/GrGLTypes.h>
 #include <GrBackendSurface.h>
 #include <SkBlendMode.h>
 #include <SkImageInfo.h>
 #include <cutils/properties.h>
 #include <gui/TraceUtils.h>
+#include <include/gpu/ganesh/SkSurfaceGanesh.h>
+#include <include/gpu/ganesh/gl/GrGLBackendSurface.h>
+#include <include/gpu/gl/GrGLTypes.h>
 #include <strings.h>
 
 #include "DeferredLayerUpdater.h"
 #include "FrameInfo.h"
-#include "LayerDrawable.h"
 #include "LightingInfo.h"
-#include "SkiaPipeline.h"
-#include "SkiaProfileRenderer.h"
 #include "hwui/Bitmap.h"
+#include "pipeline/skia/LayerDrawable.h"
+#include "pipeline/skia/SkiaGpuPipeline.h"
+#include "pipeline/skia/SkiaProfileRenderer.h"
 #include "private/hwui/DrawGlInfo.h"
 #include "renderstate/RenderState.h"
 #include "renderthread/EglManager.h"
@@ -47,7 +47,7 @@
 namespace skiapipeline {
 
 SkiaOpenGLPipeline::SkiaOpenGLPipeline(RenderThread& thread)
-        : SkiaPipeline(thread), mEglManager(thread.eglManager()) {
+        : SkiaGpuPipeline(thread), mEglManager(thread.eglManager()) {
     thread.renderState().registerContextCallback(this);
 }
 
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index 99469d1..34932b1 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -14,11 +14,8 @@
  * limitations under the License.
  */
 
-#include "SkiaPipeline.h"
+#include "pipeline/skia/SkiaPipeline.h"
 
-#include <include/android/SkSurfaceAndroid.h>
-#include <include/gpu/ganesh/SkSurfaceGanesh.h>
-#include <include/encode/SkPngEncoder.h>
 #include <SkCanvas.h>
 #include <SkColor.h>
 #include <SkColorSpace.h>
@@ -40,6 +37,9 @@
 #include <SkTypeface.h>
 #include <android-base/properties.h>
 #include <gui/TraceUtils.h>
+#include <include/android/SkSurfaceAndroid.h>
+#include <include/encode/SkPngEncoder.h>
+#include <include/gpu/ganesh/SkSurfaceGanesh.h>
 #include <unistd.h>
 
 #include <sstream>
@@ -62,37 +62,13 @@
     setSurfaceColorProperties(mColorMode);
 }
 
-SkiaPipeline::~SkiaPipeline() {
-    unpinImages();
-}
+SkiaPipeline::~SkiaPipeline() {}
 
 void SkiaPipeline::onDestroyHardwareResources() {
     unpinImages();
     mRenderThread.cacheManager().trimStaleResources();
 }
 
-bool SkiaPipeline::pinImages(std::vector<SkImage*>& mutableImages) {
-    if (!mRenderThread.getGrContext()) {
-        ALOGD("Trying to pin an image with an invalid GrContext");
-        return false;
-    }
-    for (SkImage* image : mutableImages) {
-        if (skgpu::ganesh::PinAsTexture(mRenderThread.getGrContext(), image)) {
-            mPinnedImages.emplace_back(sk_ref_sp(image));
-        } else {
-            return false;
-        }
-    }
-    return true;
-}
-
-void SkiaPipeline::unpinImages() {
-    for (auto& image : mPinnedImages) {
-        skgpu::ganesh::UnpinTexture(mRenderThread.getGrContext(), image.get());
-    }
-    mPinnedImages.clear();
-}
-
 void SkiaPipeline::renderLayers(const LightGeometry& lightGeometry,
                                 LayerUpdateQueue* layerUpdateQueue, bool opaque,
                                 const LightInfo& lightInfo) {
@@ -102,136 +78,48 @@
     layerUpdateQueue->clear();
 }
 
-void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers, bool opaque) {
-    sk_sp<GrDirectContext> cachedContext;
-
-    // Render all layers that need to be updated, in order.
-    for (size_t i = 0; i < layers.entries().size(); i++) {
-        RenderNode* layerNode = layers.entries()[i].renderNode.get();
-        // only schedule repaint if node still on layer - possible it may have been
-        // removed during a dropped frame, but layers may still remain scheduled so
-        // as not to lose info on what portion is damaged
-        if (CC_UNLIKELY(layerNode->getLayerSurface() == nullptr)) {
-            continue;
-        }
-        SkASSERT(layerNode->getLayerSurface());
-        SkiaDisplayList* displayList = layerNode->getDisplayList().asSkiaDl();
-        if (!displayList || displayList->isEmpty()) {
-            ALOGE("%p drawLayers(%s) : missing drawable", layerNode, layerNode->getName());
-            return;
-        }
-
-        const Rect& layerDamage = layers.entries()[i].damage;
-
-        SkCanvas* layerCanvas = layerNode->getLayerSurface()->getCanvas();
-
-        int saveCount = layerCanvas->save();
-        SkASSERT(saveCount == 1);
-
-        layerCanvas->androidFramework_setDeviceClipRestriction(layerDamage.toSkIRect());
-
-        // TODO: put localized light center calculation and storage to a drawable related code.
-        // It does not seem right to store something localized in a global state
-        // fix here and in recordLayers
-        const Vector3 savedLightCenter(LightingInfo::getLightCenterRaw());
-        Vector3 transformedLightCenter(savedLightCenter);
-        // map current light center into RenderNode's coordinate space
-        layerNode->getSkiaLayer()->inverseTransformInWindow.mapPoint3d(transformedLightCenter);
-        LightingInfo::setLightCenterRaw(transformedLightCenter);
-
-        const RenderProperties& properties = layerNode->properties();
-        const SkRect bounds = SkRect::MakeWH(properties.getWidth(), properties.getHeight());
-        if (properties.getClipToBounds() && layerCanvas->quickReject(bounds)) {
-            return;
-        }
-
-        ATRACE_FORMAT("drawLayer [%s] %.1f x %.1f", layerNode->getName(), bounds.width(),
-                      bounds.height());
-
-        layerNode->getSkiaLayer()->hasRenderedSinceRepaint = false;
-        layerCanvas->clear(SK_ColorTRANSPARENT);
-
-        RenderNodeDrawable root(layerNode, layerCanvas, false);
-        root.forceDraw(layerCanvas);
-        layerCanvas->restoreToCount(saveCount);
-
-        LightingInfo::setLightCenterRaw(savedLightCenter);
-
-        // cache the current context so that we can defer flushing it until
-        // either all the layers have been rendered or the context changes
-        GrDirectContext* currentContext =
-            GrAsDirectContext(layerNode->getLayerSurface()->getCanvas()->recordingContext());
-        if (cachedContext.get() != currentContext) {
-            if (cachedContext.get()) {
-                ATRACE_NAME("flush layers (context changed)");
-                cachedContext->flushAndSubmit();
-            }
-            cachedContext.reset(SkSafeRef(currentContext));
-        }
+bool SkiaPipeline::renderLayerImpl(RenderNode* layerNode, const Rect& layerDamage) {
+    SkASSERT(layerNode->getLayerSurface());
+    SkiaDisplayList* displayList = layerNode->getDisplayList().asSkiaDl();
+    if (!displayList || displayList->isEmpty()) {
+        ALOGE("%p drawLayers(%s) : missing drawable", layerNode, layerNode->getName());
+        return false;
     }
 
-    if (cachedContext.get()) {
-        ATRACE_NAME("flush layers");
-        cachedContext->flushAndSubmit();
-    }
-}
+    SkCanvas* layerCanvas = layerNode->getLayerSurface()->getCanvas();
 
-bool SkiaPipeline::createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
-                                       ErrorHandler* errorHandler) {
-    // compute the size of the surface (i.e. texture) to be allocated for this layer
-    const int surfaceWidth = ceilf(node->getWidth() / float(LAYER_SIZE)) * LAYER_SIZE;
-    const int surfaceHeight = ceilf(node->getHeight() / float(LAYER_SIZE)) * LAYER_SIZE;
+    int saveCount = layerCanvas->save();
+    SkASSERT(saveCount == 1);
 
-    SkSurface* layer = node->getLayerSurface();
-    if (!layer || layer->width() != surfaceWidth || layer->height() != surfaceHeight) {
-        SkImageInfo info;
-        info = SkImageInfo::Make(surfaceWidth, surfaceHeight, getSurfaceColorType(),
-                                 kPremul_SkAlphaType, getSurfaceColorSpace());
-        SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
-        SkASSERT(mRenderThread.getGrContext() != nullptr);
-        node->setLayerSurface(SkSurfaces::RenderTarget(mRenderThread.getGrContext(),
-                                                       skgpu::Budgeted::kYes, info, 0,
-                                                       this->getSurfaceOrigin(), &props));
-        if (node->getLayerSurface()) {
-            // update the transform in window of the layer to reset its origin wrt light source
-            // position
-            Matrix4 windowTransform;
-            damageAccumulator.computeCurrentTransform(&windowTransform);
-            node->getSkiaLayer()->inverseTransformInWindow.loadInverse(windowTransform);
-        } else {
-            String8 cachesOutput;
-            mRenderThread.cacheManager().dumpMemoryUsage(cachesOutput,
-                                                         &mRenderThread.renderState());
-            ALOGE("%s", cachesOutput.c_str());
-            if (errorHandler) {
-                std::ostringstream err;
-                err << "Unable to create layer for " << node->getName();
-                const int maxTextureSize = DeviceInfo::get()->maxTextureSize();
-                err << ", size " << info.width() << "x" << info.height() << " max size "
-                    << maxTextureSize << " color type " << (int)info.colorType() << " has context "
-                    << (int)(mRenderThread.getGrContext() != nullptr);
-                errorHandler->onError(err.str());
-            }
-        }
-        return true;
-    }
-    return false;
-}
+    layerCanvas->androidFramework_setDeviceClipRestriction(layerDamage.toSkIRect());
 
-void SkiaPipeline::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
-    GrDirectContext* context = thread.getGrContext();
-    if (context && !bitmap->isHardware()) {
-        ATRACE_FORMAT("Bitmap#prepareToDraw %dx%d", bitmap->width(), bitmap->height());
-        auto image = bitmap->makeImage();
-        if (image.get()) {
-            skgpu::ganesh::PinAsTexture(context, image.get());
-            skgpu::ganesh::UnpinTexture(context, image.get());
-            // A submit is necessary as there may not be a frame coming soon, so without a call
-            // to submit these texture uploads can just sit in the queue building up until
-            // we run out of RAM
-            context->flushAndSubmit();
-        }
+    // TODO: put localized light center calculation and storage to a drawable related code.
+    // It does not seem right to store something localized in a global state
+    // fix here and in recordLayers
+    const Vector3 savedLightCenter(LightingInfo::getLightCenterRaw());
+    Vector3 transformedLightCenter(savedLightCenter);
+    // map current light center into RenderNode's coordinate space
+    layerNode->getSkiaLayer()->inverseTransformInWindow.mapPoint3d(transformedLightCenter);
+    LightingInfo::setLightCenterRaw(transformedLightCenter);
+
+    const RenderProperties& properties = layerNode->properties();
+    const SkRect bounds = SkRect::MakeWH(properties.getWidth(), properties.getHeight());
+    if (properties.getClipToBounds() && layerCanvas->quickReject(bounds)) {
+        return false;
     }
+
+    ATRACE_FORMAT("drawLayer [%s] %.1f x %.1f", layerNode->getName(), bounds.width(),
+                  bounds.height());
+
+    layerNode->getSkiaLayer()->hasRenderedSinceRepaint = false;
+    layerCanvas->clear(SK_ColorTRANSPARENT);
+
+    RenderNodeDrawable root(layerNode, layerCanvas, false);
+    root.forceDraw(layerCanvas);
+    layerCanvas->restoreToCount(saveCount);
+
+    LightingInfo::setLightCenterRaw(savedLightCenter);
+    return true;
 }
 
 static void savePictureAsync(const sk_sp<SkData>& data, const std::string& filename) {
@@ -599,45 +487,6 @@
     }
 }
 
-void SkiaPipeline::dumpResourceCacheUsage() const {
-    int resources;
-    size_t bytes;
-    mRenderThread.getGrContext()->getResourceCacheUsage(&resources, &bytes);
-    size_t maxBytes = mRenderThread.getGrContext()->getResourceCacheLimit();
-
-    SkString log("Resource Cache Usage:\n");
-    log.appendf("%8d items\n", resources);
-    log.appendf("%8zu bytes (%.2f MB) out of %.2f MB maximum\n", bytes,
-                bytes * (1.0f / (1024.0f * 1024.0f)), maxBytes * (1.0f / (1024.0f * 1024.0f)));
-
-    ALOGD("%s", log.c_str());
-}
-
-void SkiaPipeline::setHardwareBuffer(AHardwareBuffer* buffer) {
-    if (mHardwareBuffer) {
-        AHardwareBuffer_release(mHardwareBuffer);
-        mHardwareBuffer = nullptr;
-    }
-
-    if (buffer) {
-        AHardwareBuffer_acquire(buffer);
-        mHardwareBuffer = buffer;
-    }
-}
-
-sk_sp<SkSurface> SkiaPipeline::getBufferSkSurface(
-        const renderthread::HardwareBufferRenderParams& bufferParams) {
-    auto bufferColorSpace = bufferParams.getColorSpace();
-    if (mBufferSurface == nullptr || mBufferColorSpace == nullptr ||
-        !SkColorSpace::Equals(mBufferColorSpace.get(), bufferColorSpace.get())) {
-        mBufferSurface = SkSurfaces::WrapAndroidHardwareBuffer(
-                mRenderThread.getGrContext(), mHardwareBuffer, kTopLeft_GrSurfaceOrigin,
-                bufferColorSpace, nullptr, true);
-        mBufferColorSpace = bufferColorSpace;
-    }
-    return mBufferSurface;
-}
-
 void SkiaPipeline::setSurfaceColorProperties(ColorMode colorMode) {
     mColorMode = colorMode;
     switch (colorMode) {
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index befee89..cf14b1f 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -42,18 +42,9 @@
 
     void onDestroyHardwareResources() override;
 
-    bool pinImages(std::vector<SkImage*>& mutableImages) override;
-    bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override { return false; }
-    void unpinImages() override;
-
     void renderLayers(const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
                       bool opaque, const LightInfo& lightInfo) override;
 
-    // If the given node didn't have a layer surface, or had one of the wrong size, this method
-    // creates a new one and returns true. Otherwise does nothing and returns false.
-    bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
-                             ErrorHandler* errorHandler) override;
-
     void setSurfaceColorProperties(ColorMode colorMode) override;
     SkColorType getSurfaceColorType() const override { return mSurfaceColorType; }
     sk_sp<SkColorSpace> getSurfaceColorSpace() override { return mSurfaceColorSpace; }
@@ -63,9 +54,8 @@
                      const Rect& contentDrawBounds, sk_sp<SkSurface> surface,
                      const SkMatrix& preTransform);
 
-    static void prepareToDraw(const renderthread::RenderThread& thread, Bitmap* bitmap);
-
-    void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque);
+    bool renderLayerImpl(RenderNode* layerNode, const Rect& layerDamage);
+    virtual void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque) = 0;
 
     // Sets the recording callback to the provided function and the recording mode
     // to CallbackAPI
@@ -75,19 +65,11 @@
         mCaptureMode = callback ? CaptureMode::CallbackAPI : CaptureMode::None;
     }
 
-    virtual void setHardwareBuffer(AHardwareBuffer* buffer) override;
-    bool hasHardwareBuffer() override { return mHardwareBuffer != nullptr; }
-
     void setTargetSdrHdrRatio(float ratio) override;
 
 protected:
-    sk_sp<SkSurface> getBufferSkSurface(
-            const renderthread::HardwareBufferRenderParams& bufferParams);
-    void dumpResourceCacheUsage() const;
-
     renderthread::RenderThread& mRenderThread;
 
-    AHardwareBuffer* mHardwareBuffer = nullptr;
     sk_sp<SkSurface> mBufferSurface = nullptr;
     sk_sp<SkColorSpace> mBufferColorSpace = nullptr;
 
@@ -125,8 +107,6 @@
     // Set up a multi frame capture.
     bool setupMultiFrameCapture();
 
-    std::vector<sk_sp<SkImage>> mPinnedImages;
-
     // Block of properties used only for debugging to record a SkPicture and save it in a file.
     // There are three possible ways of recording drawing commands.
     enum class CaptureMode {
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index fd0a8e0..d06dba0 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "SkiaVulkanPipeline.h"
+#include "pipeline/skia/SkiaVulkanPipeline.h"
 
 #include <GrDirectContext.h>
 #include <GrTypes.h>
@@ -28,10 +28,10 @@
 #include "DeferredLayerUpdater.h"
 #include "LightingInfo.h"
 #include "Readback.h"
-#include "ShaderCache.h"
-#include "SkiaPipeline.h"
-#include "SkiaProfileRenderer.h"
-#include "VkInteropFunctorDrawable.h"
+#include "pipeline/skia/ShaderCache.h"
+#include "pipeline/skia/SkiaGpuPipeline.h"
+#include "pipeline/skia/SkiaProfileRenderer.h"
+#include "pipeline/skia/VkInteropFunctorDrawable.h"
 #include "renderstate/RenderState.h"
 #include "renderthread/Frame.h"
 #include "renderthread/IRenderPipeline.h"
@@ -42,7 +42,8 @@
 namespace uirenderer {
 namespace skiapipeline {
 
-SkiaVulkanPipeline::SkiaVulkanPipeline(renderthread::RenderThread& thread) : SkiaPipeline(thread) {
+SkiaVulkanPipeline::SkiaVulkanPipeline(renderthread::RenderThread& thread)
+        : SkiaGpuPipeline(thread) {
     thread.renderState().registerContextCallback(this);
 }
 
diff --git a/libs/hwui/platform/android/pipeline/skia/SkiaGpuPipeline.h b/libs/hwui/platform/android/pipeline/skia/SkiaGpuPipeline.h
new file mode 100644
index 0000000..9159eae
--- /dev/null
+++ b/libs/hwui/platform/android/pipeline/skia/SkiaGpuPipeline.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "pipeline/skia/SkiaPipeline.h"
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+class SkiaGpuPipeline : public SkiaPipeline {
+public:
+    SkiaGpuPipeline(renderthread::RenderThread& thread);
+    virtual ~SkiaGpuPipeline();
+
+    virtual GrSurfaceOrigin getSurfaceOrigin() = 0;
+
+    // If the given node didn't have a layer surface, or had one of the wrong size, this method
+    // creates a new one and returns true. Otherwise does nothing and returns false.
+    bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
+                             ErrorHandler* errorHandler) override;
+
+    bool pinImages(std::vector<SkImage*>& mutableImages) override;
+    bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override { return false; }
+    void unpinImages() override;
+    void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque) override;
+    void setHardwareBuffer(AHardwareBuffer* hardwareBuffer) override;
+    bool hasHardwareBuffer() override { return mHardwareBuffer != nullptr; }
+
+    static void prepareToDraw(const renderthread::RenderThread& thread, Bitmap* bitmap);
+
+protected:
+    sk_sp<SkSurface> getBufferSkSurface(
+            const renderthread::HardwareBufferRenderParams& bufferParams);
+    void dumpResourceCacheUsage() const;
+
+    AHardwareBuffer* mHardwareBuffer = nullptr;
+
+private:
+    std::vector<sk_sp<SkImage>> mPinnedImages;
+};
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/platform/android/pipeline/skia/SkiaOpenGLPipeline.h
similarity index 95%
rename from libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
rename to libs/hwui/platform/android/pipeline/skia/SkiaOpenGLPipeline.h
index ebe8b6e..6e74782 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
+++ b/libs/hwui/platform/android/pipeline/skia/SkiaOpenGLPipeline.h
@@ -19,7 +19,7 @@
 #include <EGL/egl.h>
 #include <system/window.h>
 
-#include "SkiaPipeline.h"
+#include "pipeline/skia/SkiaGpuPipeline.h"
 #include "renderstate/RenderState.h"
 #include "renderthread/HardwareBufferRenderParams.h"
 
@@ -30,7 +30,7 @@
 namespace uirenderer {
 namespace skiapipeline {
 
-class SkiaOpenGLPipeline : public SkiaPipeline, public IGpuContextCallback {
+class SkiaOpenGLPipeline : public SkiaGpuPipeline, public IGpuContextCallback {
 public:
     SkiaOpenGLPipeline(renderthread::RenderThread& thread);
     virtual ~SkiaOpenGLPipeline();
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/platform/android/pipeline/skia/SkiaVulkanPipeline.h
similarity index 95%
rename from libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
rename to libs/hwui/platform/android/pipeline/skia/SkiaVulkanPipeline.h
index 624eaa5..0d30df4 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/platform/android/pipeline/skia/SkiaVulkanPipeline.h
@@ -17,7 +17,7 @@
 #pragma once
 
 #include "SkRefCnt.h"
-#include "SkiaPipeline.h"
+#include "pipeline/skia/SkiaGpuPipeline.h"
 #include "renderstate/RenderState.h"
 #include "renderthread/HardwareBufferRenderParams.h"
 #include "renderthread/VulkanManager.h"
@@ -30,7 +30,7 @@
 namespace uirenderer {
 namespace skiapipeline {
 
-class SkiaVulkanPipeline : public SkiaPipeline, public IGpuContextCallback {
+class SkiaVulkanPipeline : public SkiaGpuPipeline, public IGpuContextCallback {
 public:
     explicit SkiaVulkanPipeline(renderthread::RenderThread& thread);
     virtual ~SkiaVulkanPipeline();
diff --git a/libs/hwui/platform/host/android/api-level.h b/libs/hwui/platform/host/android/api-level.h
new file mode 120000
index 0000000..4fb4784
--- /dev/null
+++ b/libs/hwui/platform/host/android/api-level.h
@@ -0,0 +1 @@
+../../../../../../../bionic/libc/include/android/api-level.h
\ No newline at end of file
diff --git a/libs/hwui/platform/host/pipeline/skia/SkiaGpuPipeline.h b/libs/hwui/platform/host/pipeline/skia/SkiaGpuPipeline.h
new file mode 100644
index 0000000..a717265
--- /dev/null
+++ b/libs/hwui/platform/host/pipeline/skia/SkiaGpuPipeline.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "pipeline/skia/SkiaPipeline.h"
+#include "renderthread/Frame.h"
+
+namespace android {
+namespace uirenderer {
+namespace skiapipeline {
+
+class SkiaGpuPipeline : public SkiaPipeline {
+public:
+    SkiaGpuPipeline(renderthread::RenderThread& thread) : SkiaPipeline(thread) {}
+    ~SkiaGpuPipeline() {}
+
+    bool pinImages(std::vector<SkImage*>& mutableImages) override { return false; }
+    bool pinImages(LsaVector<sk_sp<Bitmap>>& images) override { return false; }
+    void unpinImages() override {}
+
+    // If the given node didn't have a layer surface, or had one of the wrong size, this method
+    // creates a new one and returns true. Otherwise does nothing and returns false.
+    bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& damageAccumulator,
+                             ErrorHandler* errorHandler) override {
+        return false;
+    }
+    void renderLayersImpl(const LayerUpdateQueue& layers, bool opaque) override {}
+    void setHardwareBuffer(AHardwareBuffer* hardwareBuffer) override {}
+    bool hasHardwareBuffer() override { return false; }
+
+    renderthread::MakeCurrentResult makeCurrent() override {
+        return renderthread::MakeCurrentResult::Failed;
+    }
+    renderthread::Frame getFrame() override { return renderthread::Frame(0, 0, 0); }
+    renderthread::IRenderPipeline::DrawResult draw(
+            const renderthread::Frame& frame, const SkRect& screenDirty, const SkRect& dirty,
+            const LightGeometry& lightGeometry, LayerUpdateQueue* layerUpdateQueue,
+            const Rect& contentDrawBounds, bool opaque, const LightInfo& lightInfo,
+            const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler,
+            const renderthread::HardwareBufferRenderParams& bufferParams,
+            std::mutex& profilerLock) override {
+        return {false, IRenderPipeline::DrawResult::kUnknownTime, android::base::unique_fd(-1)};
+    }
+    bool swapBuffers(const renderthread::Frame& frame, IRenderPipeline::DrawResult& drawResult,
+                     const SkRect& screenDirty, FrameInfo* currentFrameInfo,
+                     bool* requireSwap) override {
+        return false;
+    }
+    DeferredLayerUpdater* createTextureLayer() override { return nullptr; }
+    bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior) override {
+        return false;
+    }
+    [[nodiscard]] android::base::unique_fd flush() override {
+        return android::base::unique_fd(-1);
+    };
+    void onStop() override {}
+    bool isSurfaceReady() override { return false; }
+    bool isContextReady() override { return false; }
+
+    const SkM44& getPixelSnapMatrix() const override {
+        static const SkM44 sSnapMatrix = SkM44();
+        return sSnapMatrix;
+    }
+    static void prepareToDraw(const renderthread::RenderThread& thread, Bitmap* bitmap) {}
+};
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/platform/host/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/platform/host/pipeline/skia/SkiaOpenGLPipeline.h
new file mode 100644
index 0000000..4fafbcc
--- /dev/null
+++ b/libs/hwui/platform/host/pipeline/skia/SkiaOpenGLPipeline.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "pipeline/skia/SkiaGpuPipeline.h"
+
+namespace android {
+
+namespace uirenderer {
+namespace skiapipeline {
+
+class SkiaOpenGLPipeline : public SkiaGpuPipeline {
+public:
+    SkiaOpenGLPipeline(renderthread::RenderThread& thread) : SkiaGpuPipeline(thread) {}
+
+    static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor) {}
+};
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/platform/host/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/platform/host/pipeline/skia/SkiaVulkanPipeline.h
new file mode 100644
index 0000000..d54caef
--- /dev/null
+++ b/libs/hwui/platform/host/pipeline/skia/SkiaVulkanPipeline.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "pipeline/skia/SkiaGpuPipeline.h"
+
+namespace android {
+
+namespace uirenderer {
+namespace skiapipeline {
+
+class SkiaVulkanPipeline : public SkiaGpuPipeline {
+public:
+    SkiaVulkanPipeline(renderthread::RenderThread& thread) : SkiaGpuPipeline(thread) {}
+
+    static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor) {}
+};
+
+} /* namespace skiapipeline */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 1fbd580..22de2f2 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -35,8 +35,8 @@
 #include "Properties.h"
 #include "RenderThread.h"
 #include "hwui/Canvas.h"
+#include "pipeline/skia/SkiaGpuPipeline.h"
 #include "pipeline/skia/SkiaOpenGLPipeline.h"
-#include "pipeline/skia/SkiaPipeline.h"
 #include "pipeline/skia/SkiaVulkanPipeline.h"
 #include "thread/CommonPool.h"
 #include "utils/GLUtils.h"
@@ -108,7 +108,7 @@
 }
 
 void CanvasContext::prepareToDraw(const RenderThread& thread, Bitmap* bitmap) {
-    skiapipeline::SkiaPipeline::prepareToDraw(thread, bitmap);
+    skiapipeline::SkiaGpuPipeline::prepareToDraw(thread, bitmap);
 }
 
 CanvasContext::CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index b8c3a4d..ee1d1f8 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -30,8 +30,6 @@
 #include "SwapBehavior.h"
 #include "hwui/Bitmap.h"
 
-class GrDirectContext;
-
 struct ANativeWindow;
 
 namespace android {
@@ -94,7 +92,6 @@
     virtual void setSurfaceColorProperties(ColorMode colorMode) = 0;
     virtual SkColorType getSurfaceColorType() const = 0;
     virtual sk_sp<SkColorSpace> getSurfaceColorSpace() = 0;
-    virtual GrSurfaceOrigin getSurfaceOrigin() = 0;
     virtual void setPictureCapturedCallback(
             const std::function<void(sk_sp<SkPicture>&&)>& callback) = 0;
 
diff --git a/location/java/android/location/flags/location.aconfig b/location/java/android/location/flags/location.aconfig
index 19e59a7..b8b03b6 100644
--- a/location/java/android/location/flags/location.aconfig
+++ b/location/java/android/location/flags/location.aconfig
@@ -1,4 +1,5 @@
 package: "android.location.flags"
+container: "system"
 
 flag {
     name: "new_geocoder"
diff --git a/media/java/android/media/FadeManagerConfiguration.java b/media/java/android/media/FadeManagerConfiguration.java
index eaafa59..6d84e70 100644
--- a/media/java/android/media/FadeManagerConfiguration.java
+++ b/media/java/android/media/FadeManagerConfiguration.java
@@ -836,7 +836,7 @@
          */
         public Builder(@NonNull FadeManagerConfiguration fmc) {
             mFadeState = fmc.mFadeState;
-            mUsageToFadeWrapperMap = fmc.mUsageToFadeWrapperMap.clone();
+            copyUsageToFadeWrapperMapInternal(fmc.mUsageToFadeWrapperMap);
             mAttrToFadeWrapperMap = new ArrayMap<AudioAttributes, FadeVolumeShaperConfigsWrapper>(
                     fmc.mAttrToFadeWrapperMap);
             mFadeableUsages = fmc.mFadeableUsages.clone();
@@ -1459,6 +1459,14 @@
             }
         }
 
+        private  void copyUsageToFadeWrapperMapInternal(
+                SparseArray<FadeVolumeShaperConfigsWrapper> usageToFadeWrapperMap) {
+            for (int index = 0; index < usageToFadeWrapperMap.size(); index++) {
+                mUsageToFadeWrapperMap.put(usageToFadeWrapperMap.keyAt(index),
+                        new FadeVolumeShaperConfigsWrapper(usageToFadeWrapperMap.valueAt(index)));
+            }
+        }
+
         private void validateFadeState(int state) {
             switch(state) {
                 case FADE_STATE_DISABLED:
@@ -1551,6 +1559,12 @@
 
         FadeVolumeShaperConfigsWrapper() {}
 
+        FadeVolumeShaperConfigsWrapper(@NonNull FadeVolumeShaperConfigsWrapper wrapper) {
+            Objects.requireNonNull(wrapper, "Fade volume shaper configs wrapper cannot be null");
+            this.mFadeOutVolShaperConfig = wrapper.mFadeOutVolShaperConfig;
+            this.mFadeInVolShaperConfig = wrapper.mFadeInVolShaperConfig;
+        }
+
         public void setFadeOutVolShaperConfig(@Nullable VolumeShaper.Configuration fadeOutConfig) {
             mFadeOutVolShaperConfig = fadeOutConfig;
         }
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 82d43bc..ce7474c 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -2364,12 +2364,16 @@
         }
 
         // at the moment no codecs support detachable surface
+        boolean canDetach = GetFlag(() -> android.media.codec.Flags.nullOutputSurfaceSupport());
         if (GetFlag(() -> android.media.codec.Flags.nullOutputSurface())) {
             // Detached surface flag is only meaningful if surface is null. Otherwise, it is
             // ignored.
-            if (surface == null && (flags & CONFIGURE_FLAG_DETACHED_SURFACE) != 0) {
+            if (surface == null && (flags & CONFIGURE_FLAG_DETACHED_SURFACE) != 0 && !canDetach) {
                 throw new IllegalArgumentException("Codec does not support detached surface");
             }
+        } else {
+            // don't allow detaching if API is disabled
+            canDetach = false;
         }
 
         String[] keys = null;
@@ -2411,6 +2415,14 @@
         }
 
         native_configure(keys, values, surface, crypto, descramblerBinder, flags);
+
+        if (canDetach) {
+            // If we were able to configure native codec with a detached surface
+            // we now know that we have a surface.
+            if (surface == null && (flags & CONFIGURE_FLAG_DETACHED_SURFACE) != 0) {
+                mHasSurface = true;
+            }
+        }
     }
 
     /**
@@ -2455,12 +2467,19 @@
         if (!mHasSurface) {
             throw new IllegalStateException("codec was not configured for an output surface");
         }
+
         // note: we still have a surface in detached mode, so keep mHasSurface
         // we also technically allow calling detachOutputSurface multiple times in a row
-        throw new IllegalStateException("codec does not support detaching output surface");
-        // native_detachSurface();
+
+        if (GetFlag(() -> android.media.codec.Flags.nullOutputSurfaceSupport())) {
+            native_detachOutputSurface();
+        } else {
+            throw new IllegalStateException("codec does not support detaching output surface");
+        }
     }
 
+    private native void native_detachOutputSurface();
+
     /**
      * Create a persistent input surface that can be used with codecs that normally have an input
      * surface, such as video encoders. A persistent input can be reused by subsequent
diff --git a/media/java/android/media/MediaDescription.java b/media/java/android/media/MediaDescription.java
index dece6bd..ec95279 100644
--- a/media/java/android/media/MediaDescription.java
+++ b/media/java/android/media/MediaDescription.java
@@ -397,8 +397,14 @@
          * @return a new media description.
          */
         public MediaDescription build() {
-            return new MediaDescription(mMediaId, mTitle, mSubtitle, mDescription, mIcon, mIconUri,
-                    mExtras, mMediaUri);
+            if (com.android.media.performance.flags.Flags.mediaDescriptionAshmemBitmap()) {
+                Bitmap icon = mIcon != null ? mIcon.asShared() : null;
+                return new MediaDescription(mMediaId, mTitle, mSubtitle, mDescription, icon,
+                        mIconUri, mExtras, mMediaUri);
+            } else {
+                return new MediaDescription(mMediaId, mTitle, mSubtitle, mDescription, mIcon,
+                        mIconUri, mExtras, mMediaUri);
+            }
         }
     }
 }
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 3f9440b..76bbca6 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -3129,20 +3129,8 @@
 
         private void onTransferred(
                 @NonNull RoutingSessionInfo oldSession, @NonNull RoutingSessionInfo newSession) {
-            if (!oldSession.isSystemSession()
-                    && !TextUtils.equals(
-                            getClientPackageName(), oldSession.getClientPackageName())) {
-                return;
-            }
-
-            if (!newSession.isSystemSession()
-                    && !TextUtils.equals(
-                            getClientPackageName(), newSession.getClientPackageName())) {
-                return;
-            }
-
-            // For successful in-session transfer, onControllerUpdated() handles it.
-            if (TextUtils.equals(oldSession.getId(), newSession.getId())) {
+            if (!isSessionRelatedToTargetPackageName(oldSession)
+                    || !isSessionRelatedToTargetPackageName(newSession)) {
                 return;
             }
 
@@ -3169,16 +3157,14 @@
 
         private void onTransferFailed(
                 @NonNull RoutingSessionInfo session, @NonNull MediaRoute2Info route) {
-            if (!session.isSystemSession()
-                    && !TextUtils.equals(getClientPackageName(), session.getClientPackageName())) {
+            if (!isSessionRelatedToTargetPackageName(session)) {
                 return;
             }
             notifyTransferFailure(route);
         }
 
         private void onSessionUpdated(@NonNull RoutingSessionInfo session) {
-            if (!session.isSystemSession()
-                    && !TextUtils.equals(getClientPackageName(), session.getClientPackageName())) {
+            if (!isSessionRelatedToTargetPackageName(session)) {
                 return;
             }
 
@@ -3193,6 +3179,15 @@
             notifyControllerUpdated(controller);
         }
 
+        /**
+         * Returns {@code true} if the session is a system session or if its client package name
+         * matches the proxy router's target package name.
+         */
+        private boolean isSessionRelatedToTargetPackageName(@NonNull RoutingSessionInfo session) {
+            return session.isSystemSession()
+                    || TextUtils.equals(getClientPackageName(), session.getClientPackageName());
+        }
+
         private void onSessionCreatedOnHandler(
                 int requestId, @NonNull RoutingSessionInfo sessionInfo) {
             MediaRouter2Manager.TransferRequest matchingRequest = null;
@@ -3237,19 +3232,19 @@
             }
         }
 
-        private void onSessionUpdatedOnHandler(@NonNull RoutingSessionInfo sessionInfo) {
+        private void onSessionUpdatedOnHandler(@NonNull RoutingSessionInfo updatedSession) {
             for (MediaRouter2Manager.TransferRequest request : mTransferRequests) {
                 String sessionId = request.mOldSessionInfo.getId();
-                if (!TextUtils.equals(sessionId, sessionInfo.getId())) {
+                if (!TextUtils.equals(sessionId, updatedSession.getId())) {
                     continue;
                 }
-                if (sessionInfo.getSelectedRoutes().contains(request.mTargetRoute.getId())) {
+
+                if (updatedSession.getSelectedRoutes().contains(request.mTargetRoute.getId())) {
                     mTransferRequests.remove(request);
-                    this.onTransferred(request.mOldSessionInfo, sessionInfo);
                     break;
                 }
             }
-            this.onSessionUpdated(sessionInfo);
+            this.onSessionUpdated(updatedSession);
         }
 
         private void onSessionReleasedOnHandler(@NonNull RoutingSessionInfo session) {
diff --git a/media/java/android/media/flags/editing.aconfig b/media/java/android/media/flags/editing.aconfig
index 5bf1b4e..bf6ec96 100644
--- a/media/java/android/media/flags/editing.aconfig
+++ b/media/java/android/media/flags/editing.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.media.editing.flags"
+container: "system"
 
 flag {
   name: "add_media_metrics_editing"
diff --git a/media/java/android/media/flags/media_better_together.aconfig b/media/java/android/media/flags/media_better_together.aconfig
index 40929f7..91c4f11 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"
@@ -24,13 +25,6 @@
 }
 
 flag {
-    name: "disable_screen_off_broadcast_receiver"
-    namespace: "media_solutions"
-    description: "Disables the broadcast receiver that prevents scanning when the screen is off."
-    bug: "304234628"
-}
-
-flag {
     name: "fallback_to_default_handling_when_media_session_has_fixed_volume_handling"
     namespace: "media_solutions"
     description: "Fallbacks to the default handling for volume adjustment when media session has fixed volume handling and its app is in the foreground and setting a media controller."
@@ -107,6 +101,16 @@
 }
 
 flag {
+    name: "enable_mr2_service_non_main_bg_thread"
+    namespace: "media_solutions"
+    description: "Enables the use of a background thread in the media routing framework, instead of using the main thread."
+    bug: "310145678"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
     name: "enable_screen_off_scanning"
     is_exported: true
     namespace: "media_solutions"
@@ -120,3 +124,13 @@
     description: "Enables apps owning a MediaBrowserService to disconnect all connected browsers."
     bug: "185136506"
 }
+
+flag {
+    name: "enable_prevention_of_manager_scans_when_no_apps_scan"
+    namespace: "media_solutions"
+    description: "Prevents waking up route providers when no apps are scanning, even if SysUI or Settings are scanning."
+    bug: "319604673"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/media/java/android/media/flags/performance.aconfig b/media/java/android/media/flags/performance.aconfig
new file mode 100644
index 0000000..9e9197e
--- /dev/null
+++ b/media/java/android/media/flags/performance.aconfig
@@ -0,0 +1,11 @@
+package: "com.android.media.performance.flags"
+
+flag {
+    name: "media_description_ashmem_bitmap"
+    namespace: "systemui"
+    description: "Use ashmem to pass bitmaps in MediaDescription to avoid excessive Bitmap copies."
+    bug: "288241280"
+    metadata {
+      purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/media/java/android/media/flags/projection.aconfig b/media/java/android/media/flags/projection.aconfig
index b165809..9a9a073 100644
--- a/media/java/android/media/flags/projection.aconfig
+++ b/media/java/android/media/flags/projection.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.media.projection.flags"
+container: "system"
 
 # Project link: https://gantry.corp.google.com/projects/android_platform_window_surfaces/changes
 
diff --git a/media/java/android/media/tv/flags/media_tv.aconfig b/media/java/android/media/tv/flags/media_tv.aconfig
index 1731e5e..97971e1 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/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 0fc80dd..82561f9 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -389,6 +389,14 @@
     return err;
 }
 
+status_t JMediaCodec::detachOutputSurface() {
+    status_t err = mCodec->detachOutputSurface();
+    if (err == OK) {
+        mSurfaceTextureClient.clear();
+    }
+    return err;
+}
+
 status_t JMediaCodec::createInputSurface(
         sp<IGraphicBufferProducer>* bufferProducer) {
     return mCodec->createInputSurface(bufferProducer);
@@ -1798,6 +1806,20 @@
     throwExceptionAsNecessary(env, err, codec);
 }
 
+static void android_media_MediaCodec_native_detachOutputSurface(
+        JNIEnv *env,
+        jobject thiz) {
+    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+    if (codec == NULL || codec->initCheck() != OK) {
+        throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
+        return;
+    }
+
+    status_t err = codec->detachOutputSurface();
+    throwExceptionAsNecessary(env, err, codec);
+}
+
 sp<PersistentSurface> android_media_MediaCodec_getPersistentInputSurface(
         JNIEnv* env, jobject object) {
     sp<PersistentSurface> persistentSurface;
@@ -4107,6 +4129,10 @@
       "(Landroid/view/Surface;)V",
       (void *)android_media_MediaCodec_native_setSurface },
 
+    { "native_detachOutputSurface",
+      "()V",
+      (void *)android_media_MediaCodec_native_detachOutputSurface },
+
     { "createInputSurface", "()Landroid/view/Surface;",
       (void *)android_media_MediaCodec_createInputSurface },
 
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index abb23f5..c9b6b7f6 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -80,6 +80,8 @@
     status_t setSurface(
             const sp<IGraphicBufferProducer> &surface);
 
+    status_t detachOutputSurface();
+
     status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer);
     status_t setInputSurface(const sp<PersistentSurface> &surface);
 
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/AudioPolicyTest/src/com/android/audiopolicytest/FadeManagerConfigurationUnitTest.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/FadeManagerConfigurationUnitTest.java
index c48a956..74b5afe 100644
--- a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/FadeManagerConfigurationUnitTest.java
+++ b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/FadeManagerConfigurationUnitTest.java
@@ -196,8 +196,7 @@
         FadeManagerConfiguration fmcObj = new FadeManagerConfiguration
                 .Builder(TEST_FADE_OUT_DURATION_MS, TEST_FADE_IN_DURATION_MS).build();
 
-        FadeManagerConfiguration fmc = new FadeManagerConfiguration
-                .Builder(fmcObj).build();
+        FadeManagerConfiguration fmc = new FadeManagerConfiguration.Builder(fmcObj).build();
 
         expect.withMessage("Fade state for copy builder").that(fmc.getFadeState())
                 .isEqualTo(fmcObj.getFadeState());
@@ -249,6 +248,45 @@
     }
 
     @Test
+    public void build_withCopyConstructor_doesnotChangeOriginal() {
+        FadeManagerConfiguration copyConstructedFmc = new FadeManagerConfiguration.Builder(mFmc)
+                .setFadeOutDurationForUsage(AudioAttributes.USAGE_MEDIA, TEST_FADE_OUT_DURATION_MS)
+                .setFadeInDurationForUsage(AudioAttributes.USAGE_MEDIA, TEST_FADE_IN_DURATION_MS)
+                .build();
+
+        expect.withMessage("Fade out duration for media usage of default constructor")
+                .that(mFmc.getFadeOutDurationForUsage(AudioAttributes.USAGE_MEDIA))
+                .isEqualTo(DEFAULT_FADE_OUT_DURATION_MS);
+        expect.withMessage("Fade out duration for media usage of default constructor")
+                .that(mFmc.getFadeInDurationForUsage(AudioAttributes.USAGE_MEDIA))
+                .isEqualTo(DEFAULT_FADE_IN_DURATION_MS);
+        expect.withMessage("Fade out duration for media usage of copy constructor")
+                .that(copyConstructedFmc.getFadeOutDurationForUsage(AudioAttributes.USAGE_MEDIA))
+                .isEqualTo(TEST_FADE_OUT_DURATION_MS);
+        expect.withMessage("Fade out duration for media usage of copy constructor")
+                .that(copyConstructedFmc.getFadeInDurationForUsage(AudioAttributes.USAGE_MEDIA))
+                .isEqualTo(TEST_FADE_IN_DURATION_MS);
+    }
+
+    @Test
+    public void build_withCopyConstructor_equals() {
+        FadeManagerConfiguration fmc = new FadeManagerConfiguration.Builder()
+                .setFadeableUsages(List.of(AudioAttributes.USAGE_MEDIA,
+                        AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+                        AudioAttributes.USAGE_ASSISTANT,
+                        AudioAttributes.USAGE_EMERGENCY))
+                .setFadeOutDurationForUsage(AudioAttributes.USAGE_MEDIA, TEST_FADE_OUT_DURATION_MS)
+                .setFadeInDurationForUsage(AudioAttributes.USAGE_MEDIA, TEST_FADE_IN_DURATION_MS)
+                .build();
+
+        FadeManagerConfiguration copyConstructedFmc =
+                new FadeManagerConfiguration.Builder(fmc).build();
+
+        expect.withMessage("Fade manager config constructed using copy constructor").that(fmc)
+                .isEqualTo(copyConstructedFmc);
+    }
+
+    @Test
     public void testGetDefaultFadeOutDuration() {
         expect.withMessage("Default fade out duration")
                 .that(FadeManagerConfiguration.getDefaultFadeOutDurationMillis())
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index 9b1330f..6ce83cd 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -367,7 +367,7 @@
 
 void ASurfaceTransaction_setVisibility(ASurfaceTransaction* aSurfaceTransaction,
                                        ASurfaceControl* aSurfaceControl,
-                                       int8_t visibility) {
+                                       ASurfaceTransactionVisibility visibility) {
     CHECK_NOT_NULL(aSurfaceTransaction);
     CHECK_NOT_NULL(aSurfaceControl);
 
@@ -496,7 +496,7 @@
 
 void ASurfaceTransaction_setBufferTransparency(ASurfaceTransaction* aSurfaceTransaction,
                                                ASurfaceControl* aSurfaceControl,
-                                               int8_t transparency) {
+                                               ASurfaceTransactionTransparency transparency) {
     CHECK_NOT_NULL(aSurfaceTransaction);
     CHECK_NOT_NULL(aSurfaceControl);
 
diff --git a/nfc/Android.bp b/nfc/Android.bp
index 0b3f291..c186804 100644
--- a/nfc/Android.bp
+++ b/nfc/Android.bp
@@ -39,6 +39,7 @@
     libs: [
         "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
         "framework-permission-s",
+        "framework-permission",
     ],
     static_libs: [
         "android.nfc.flags-aconfig-java",
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index a72e539..310130e 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -9,6 +9,7 @@
     method @FlaggedApi("android.nfc.enable_nfc_reader_option") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableReaderOption(boolean);
     method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean enableSecureNfc(boolean);
     method @FlaggedApi("android.nfc.enable_nfc_mainline") public int getAdapterState();
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public android.nfc.NfcOemExtension getNfcOemExtension();
     method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.Map<java.lang.String,java.lang.Boolean> getTagIntentAppPreferenceForUser(int);
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn();
     method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported();
@@ -55,6 +56,16 @@
     method public void onWlcStateChanged(@NonNull android.nfc.WlcListenerDeviceInfo);
   }
 
+  @FlaggedApi("android.nfc.nfc_oem_extension") public final class NfcOemExtension {
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void clearPreference();
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcOemExtension.Callback);
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void unregisterCallback(@NonNull android.nfc.NfcOemExtension.Callback);
+  }
+
+  public static interface NfcOemExtension.Callback {
+    method public void onTagConnected(boolean, @NonNull android.nfc.Tag);
+  }
+
 }
 
 package android.nfc.cardemulation {
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
index 7a78f3d..b57d548 100644
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ b/nfc/java/android/nfc/INfcAdapter.aidl
@@ -28,6 +28,7 @@
 import android.nfc.INfcTag;
 import android.nfc.INfcCardEmulation;
 import android.nfc.INfcFCardEmulation;
+import android.nfc.INfcOemExtensionCallback;
 import android.nfc.INfcUnlockHandler;
 import android.nfc.ITagRemovedCallback;
 import android.nfc.INfcDta;
@@ -105,4 +106,7 @@
     int sendVendorNciMessage(int mt, int gid, int oid, in byte[] payload);
     void registerVendorExtensionCallback(in INfcVendorNciCallback callbacks);
     void unregisterVendorExtensionCallback(in INfcVendorNciCallback callbacks);
+    void registerOemExtensionCallback(INfcOemExtensionCallback callbacks);
+    void unregisterOemExtensionCallback(INfcOemExtensionCallback callbacks);
+    void clearPreference();
 }
diff --git a/apex/jobscheduler/framework/java/android/app/tare/IEconomyManager.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
similarity index 70%
rename from apex/jobscheduler/framework/java/android/app/tare/IEconomyManager.aidl
rename to nfc/java/android/nfc/INfcOemExtensionCallback.aidl
index 2be0db7..6c9096d 100644
--- a/apex/jobscheduler/framework/java/android/app/tare/IEconomyManager.aidl
+++ b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
@@ -1,5 +1,5 @@
-/**
- * Copyright (C) 2021 The Android Open Source Project
+/*
+ * Copyright 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.
@@ -13,13 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package android.nfc;
 
-package android.app.tare;
+import android.nfc.Tag;
 
- /**
-  * IPC interface that supports the app-facing {@link #EconomyManager} api.
-  * {@hide}
-  */
-interface IEconomyManager {
-    int getEnabledMode();
+/**
+ * @hide
+ */
+interface INfcOemExtensionCallback {
+   void onTagConnected(boolean connected, in Tag tag);
 }
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index 7a7db31..b44a71b 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -581,6 +581,7 @@
     final Context mContext;
     final HashMap<NfcUnlockHandler, INfcUnlockHandler> mNfcUnlockHandlers;
     final Object mLock;
+    final NfcOemExtension mNfcOemExtension;
 
     ITagRemovedCallback mTagRemovedListener; // protected by mLock
 
@@ -891,6 +892,7 @@
         mControllerAlwaysOnListener = new NfcControllerAlwaysOnListener(getService());
         mNfcWlcStateListener = new NfcWlcStateListener(getService());
         mNfcVendorNciCallbackListener = new NfcVendorNciCallbackListener(getService());
+        mNfcOemExtension = new NfcOemExtension(mContext, this);
     }
 
     /**
@@ -3163,4 +3165,19 @@
         void onVendorNciNotification(
                 @IntRange(from = 9, to = 15) int gid, int oid, @NonNull byte[] payload);
     }
+
+    /**
+     * Returns an instance of {@link NfcOemExtension} associated with {@link NfcAdapter} instance.
+     * @hide
+     */
+    @SystemApi
+    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+    @NonNull public NfcOemExtension getNfcOemExtension() {
+        synchronized (sLock) {
+            if (!sHasNfcFeature) {
+                throw new UnsupportedOperationException();
+            }
+        }
+        return mNfcOemExtension;
+    }
 }
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
new file mode 100644
index 0000000..1eff58c
--- /dev/null
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Used for OEM extension APIs.
+ * This class holds all the APIs and callbacks defined for OEMs/vendors to extend the NFC stack
+ * for their proprietary features.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public final class NfcOemExtension {
+    private static final String TAG = "NfcOemExtension";
+    private static final int OEM_EXTENSION_RESPONSE_THRESHOLD_MS = 2000;
+    private final NfcAdapter mAdapter;
+    private final NfcOemExtensionCallback mOemNfcExtensionCallback;
+    private final Context mContext;
+    private Executor mExecutor = null;
+    private Callback mCallback = null;
+    private final Object mLock = new Object();
+
+    /**
+     * Interface for Oem extensions for NFC.
+     */
+    public interface Callback {
+        /**
+         * Notify Oem to tag is connected or not
+         * ex - if tag is connected  notify cover and Nfctest app if app is in testing mode
+         *
+         * @param connected status of the tag true if tag is connected otherwise false
+         * @param tag Tag details
+         */
+        void onTagConnected(boolean connected, @NonNull Tag tag);
+    }
+
+
+    /**
+     * Constructor to be used only by {@link NfcAdapter}.
+     * @hide
+     */
+    public NfcOemExtension(@NonNull Context context, @NonNull NfcAdapter adapter) {
+        mContext = context;
+        mAdapter = adapter;
+        mOemNfcExtensionCallback = new NfcOemExtensionCallback();
+    }
+
+    /**
+     * Register an {@link Callback} to listen for UWB oem extension callbacks
+     * <p>The provided callback will be invoked by the given {@link Executor}.
+     *
+     * @param executor an {@link Executor} to execute given callback
+     * @param callback oem implementation of {@link Callback}
+     */
+    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public void registerCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull Callback callback) {
+        synchronized (mLock) {
+            if (mCallback != null) {
+                Log.e(TAG, "Callback already registered. Unregister existing callback before"
+                        + "registering");
+                throw new IllegalArgumentException();
+            }
+            try {
+                NfcAdapter.sService.registerOemExtensionCallback(mOemNfcExtensionCallback);
+                mCallback = callback;
+                mExecutor = executor;
+            } catch (RemoteException e) {
+                mAdapter.attemptDeadServiceRecovery(e);
+            }
+        }
+    }
+
+    /**
+     * Unregister the specified {@link Callback}
+     *
+     * <p>The same {@link Callback} object used when calling
+     * {@link #registerCallback(Executor, Callback)} must be used.
+     *
+     * <p>Callbacks are automatically unregistered when an application process goes away
+     *
+     * @param callback oem implementation of {@link Callback}
+     */
+    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public void unregisterCallback(@NonNull Callback callback) {
+        synchronized (mLock) {
+            if (mCallback == null || mCallback != callback) {
+                Log.e(TAG, "Callback not registered");
+                throw new IllegalArgumentException();
+            }
+            try {
+                NfcAdapter.sService.unregisterOemExtensionCallback(mOemNfcExtensionCallback);
+                mCallback = null;
+                mExecutor = null;
+            } catch (RemoteException e) {
+                mAdapter.attemptDeadServiceRecovery(e);
+            }
+        }
+    }
+
+    /**
+     * Clear NfcService preference, interface method to clear NFC preference values on OEM specific
+     * events. For ex: on soft reset, Nfc default values needs to be overridden by OEM defaults.
+     */
+    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public void clearPreference() {
+        try {
+            NfcAdapter.sService.clearPreference();
+        } catch (RemoteException e) {
+            mAdapter.attemptDeadServiceRecovery(e);
+        }
+    }
+
+    private final class NfcOemExtensionCallback extends INfcOemExtensionCallback.Stub {
+        @Override
+        public void onTagConnected(boolean connected, Tag tag) throws RemoteException {
+            synchronized (mLock) {
+                if (mCallback == null || mExecutor == null) {
+                    return;
+                }
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() -> mCallback.onTagConnected(connected, tag));
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+        }
+    }
+}
diff --git a/nfc/java/android/nfc/flags.aconfig b/nfc/java/android/nfc/flags.aconfig
index 6d4a17c..73b29db 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"
@@ -84,3 +85,11 @@
     description: "Enable NFC vendor command support"
     bug: "289879306"
 }
+
+flag {
+    name: "nfc_oem_extension"
+    is_exported: true
+    namespace: "nfc"
+    description: "Enable NFC OEM extension support"
+    bug: "331206243"
+}
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index 1f623e1..932b5c5 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -45,7 +45,7 @@
     <string name="summary_generic" msgid="1761976003668044801">"Бул колдонмо маалыматты шайкештире алат, мисалы, чалып жаткан кишинин атын телефон жана тандалган түзмөк менен шайкештирет"</string>
     <string name="consent_yes" msgid="8344487259618762872">"Ооба"</string>
     <string name="consent_no" msgid="2640796915611404382">"Уруксат берилбесин"</string>
-    <string name="consent_cancel" msgid="5655005528379285841">"Жокко чыгаруу"</string>
+    <string name="consent_cancel" msgid="5655005528379285841">"Жок"</string>
     <string name="consent_back" msgid="2560683030046918882">"Артка"</string>
     <string name="permission_expand" msgid="893185038020887411">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> жайып көрсөтүү"</string>
     <string name="permission_collapse" msgid="3320833884220844084">"<xliff:g id="PERMISSION_TYPE">%1$s</xliff:g> жыйыштыруу"</string>
diff --git a/packages/CrashRecovery/aconfig/flags.aconfig b/packages/CrashRecovery/aconfig/flags.aconfig
index 8627eac..35d7393 100644
--- a/packages/CrashRecovery/aconfig/flags.aconfig
+++ b/packages/CrashRecovery/aconfig/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.crashrecovery.flags"
+container: "system"
 
 flag {
     name: "recoverability_detection"
diff --git a/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java b/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java
index a8d8f9a..6f20adf 100644
--- a/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java
+++ b/packages/CrashRecovery/services/java/com/android/server/PackageWatchdog.java
@@ -39,15 +39,15 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
+import android.util.LongArrayQueue;
 import android.util.Slog;
 import android.util.Xml;
-import android.utils.BackgroundThread;
-import android.utils.LongArrayQueue;
-import android.utils.XmlUtils;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.internal.util.XmlUtils;
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
 
@@ -137,17 +137,6 @@
     static final int DEFAULT_BOOT_LOOP_TRIGGER_COUNT = 5;
 
     static final long DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS = TimeUnit.MINUTES.toMillis(10);
-    // Boot loop at which packageWatchdog starts first mitigation
-    private static final String BOOT_LOOP_THRESHOLD =
-            "persist.device_config.configuration.boot_loop_threshold";
-    @VisibleForTesting
-    static final int DEFAULT_BOOT_LOOP_THRESHOLD = 15;
-    // Once boot_loop_threshold is surpassed next mitigation would be triggered after
-    // specified number of reboots.
-    private static final String BOOT_LOOP_MITIGATION_INCREMENT =
-            "persist.device_config.configuration..boot_loop_mitigation_increment";
-    @VisibleForTesting
-    static final int DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT = 2;
 
     // Threshold level at which or above user might experience significant disruption.
     private static final String MAJOR_USER_IMPACT_LEVEL_THRESHOLD =
@@ -253,15 +242,8 @@
         mConnectivityModuleConnector = connectivityModuleConnector;
         mSystemClock = clock;
         mNumberOfNativeCrashPollsRemaining = NUMBER_OF_NATIVE_CRASH_POLLS;
-        if (Flags.recoverabilityDetection()) {
-            mBootThreshold = new BootThreshold(DEFAULT_BOOT_LOOP_TRIGGER_COUNT,
-                    DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS,
-                    SystemProperties.getInt(BOOT_LOOP_MITIGATION_INCREMENT,
-                            DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT));
-        } else {
-            mBootThreshold = new BootThreshold(DEFAULT_BOOT_LOOP_TRIGGER_COUNT,
-                    DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS);
-        }
+        mBootThreshold = new BootThreshold(DEFAULT_BOOT_LOOP_TRIGGER_COUNT,
+                DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS);
 
         loadFromFile();
         sPackageWatchdog = this;
@@ -526,10 +508,16 @@
     /**
      * Called when the system server boots. If the system server is detected to be in a boot loop,
      * query each observer and perform the mitigation action with the lowest user impact.
+     *
+     * Note: PackageWatchdog considers system_server restart loop as bootloop. Full reboots
+     * are not counted in bootloop.
      */
     @SuppressWarnings("GuardedBy")
     public void noteBoot() {
         synchronized (mLock) {
+            // if boot count has reached threshold, start mitigation.
+            // We wait until threshold number of restarts only for the first time. Perform
+            // mitigations for every restart after that.
             boolean mitigate = mBootThreshold.incrementAndTest();
             if (mitigate) {
                 if (!Flags.recoverabilityDetection()) {
@@ -557,17 +545,13 @@
                 }
                 if (currentObserverToNotify != null) {
                     if (Flags.recoverabilityDetection()) {
-                        if (currentObserverImpact < getUserImpactLevelLimit()
-                                || (currentObserverImpact >= getUserImpactLevelLimit()
-                                        && mBootThreshold.getCount() >= getBootLoopThreshold())) {
-                            int currentObserverMitigationCount =
-                                    currentObserverInternal.getBootMitigationCount() + 1;
-                            currentObserverInternal.setBootMitigationCount(
-                                    currentObserverMitigationCount);
-                            saveAllObserversBootMitigationCountToMetadata(METADATA_FILE);
-                            currentObserverToNotify.executeBootLoopMitigation(
-                                    currentObserverMitigationCount);
-                        }
+                        int currentObserverMitigationCount =
+                                currentObserverInternal.getBootMitigationCount() + 1;
+                        currentObserverInternal.setBootMitigationCount(
+                                currentObserverMitigationCount);
+                        saveAllObserversBootMitigationCountToMetadata(METADATA_FILE);
+                        currentObserverToNotify.executeBootLoopMitigation(
+                                currentObserverMitigationCount);
                     } else {
                         mBootThreshold.setMitigationCount(mitigationCount);
                         mBootThreshold.saveMitigationCountToMetadata();
@@ -647,11 +631,6 @@
                 DEFAULT_MAJOR_USER_IMPACT_LEVEL_THRESHOLD);
     }
 
-    private int getBootLoopThreshold() {
-        return SystemProperties.getInt(BOOT_LOOP_THRESHOLD,
-                DEFAULT_BOOT_LOOP_THRESHOLD);
-    }
-
     /** Possible severity values of the user impact of a {@link PackageHealthObserver#execute}. */
     @Retention(SOURCE)
     @IntDef(value = {PackageHealthObserverImpact.USER_IMPACT_LEVEL_0,
@@ -1827,16 +1806,10 @@
 
         private final int mBootTriggerCount;
         private final long mTriggerWindow;
-        private final int mBootMitigationIncrement;
 
         BootThreshold(int bootTriggerCount, long triggerWindow) {
-            this(bootTriggerCount, triggerWindow, /*bootMitigationIncrement=*/ 1);
-        }
-
-        BootThreshold(int bootTriggerCount, long triggerWindow, int bootMitigationIncrement) {
             this.mBootTriggerCount = bootTriggerCount;
             this.mTriggerWindow = triggerWindow;
-            this.mBootMitigationIncrement = bootMitigationIncrement;
         }
 
         public void reset() {
@@ -1915,6 +1888,7 @@
             } else {
                 readMitigationCountFromMetadataIfNecessary();
             }
+
             final long now = mSystemClock.uptimeMillis();
             if (now - getStart() < 0) {
                 Slog.e(TAG, "Window was less than zero. Resetting start to current time.");
@@ -1939,20 +1913,32 @@
                 setCount(count);
                 EventLogTags.writeRescueNote(Process.ROOT_UID, count, window);
                 if (Flags.recoverabilityDetection()) {
-                    boolean mitigate = (count >= mBootTriggerCount)
-                            && (count - mBootTriggerCount) % mBootMitigationIncrement == 0;
-                    return mitigate;
+                    // After a reboot (e.g. by WARM_REBOOT or mainline rollback) we apply
+                    // mitigations without waiting for DEFAULT_BOOT_LOOP_TRIGGER_COUNT.
+                    return (count >= mBootTriggerCount)
+                            || (performedMitigationsDuringWindow() && count > 1);
                 }
                 return count >= mBootTriggerCount;
             }
         }
 
         @GuardedBy("mLock")
+        private boolean performedMitigationsDuringWindow() {
+            for (ObserverInternal observerInternal: mAllObservers.values()) {
+                if (observerInternal.getBootMitigationCount() > 0) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @GuardedBy("mLock")
         private void resetAllObserversBootMitigationCount() {
             for (int i = 0; i < mAllObservers.size(); i++) {
                 final ObserverInternal observer = mAllObservers.valueAt(i);
                 observer.setBootMitigationCount(0);
             }
+            saveAllObserversBootMitigationCountToMetadata(METADATA_FILE);
         }
 
         @GuardedBy("mLock")
diff --git a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java
index 7093ba4..271d552 100644
--- a/packages/CrashRecovery/services/java/com/android/server/RescueParty.java
+++ b/packages/CrashRecovery/services/java/com/android/server/RescueParty.java
@@ -31,6 +31,7 @@
 import android.crashrecovery.flags.Flags;
 import android.os.Build;
 import android.os.Environment;
+import android.os.FileUtils;
 import android.os.PowerManager;
 import android.os.RecoverySystem;
 import android.os.SystemClock;
@@ -43,11 +44,10 @@
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.Slog;
-import android.utils.ArrayUtils;
-import android.utils.FileUtils;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
 import com.android.server.PackageWatchdog.FailureReasons;
 import com.android.server.PackageWatchdog.PackageHealthObserver;
 import com.android.server.PackageWatchdog.PackageHealthObserverImpact;
@@ -139,7 +139,7 @@
     static final String NAMESPACE_TO_PACKAGE_MAPPING_FLAG =
             "namespace_to_package_mapping";
     @VisibleForTesting
-    static final long DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN = 10;
+    static final long DEFAULT_FACTORY_RESET_THROTTLE_DURATION_MIN = 1440;
 
     private static final String NAME = "rescue-party-observer";
 
diff --git a/packages/CrashRecovery/services/java/com/android/utils/ArrayUtils.java b/packages/CrashRecovery/services/java/com/android/utils/ArrayUtils.java
deleted file mode 100644
index fa4d6af..0000000
--- a/packages/CrashRecovery/services/java/com/android/utils/ArrayUtils.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.utils;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.io.File;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Copied over from frameworks/base/core/java/com/android/internal/util/ArrayUtils.java
- *
- * @hide
- */
-public class ArrayUtils {
-    private ArrayUtils() { /* cannot be instantiated */ }
-    public static final File[] EMPTY_FILE = new File[0];
-
-
-    /**
-     * Return first index of {@code value} in {@code array}, or {@code -1} if
-     * not found.
-     */
-    public static <T> int indexOf(@Nullable T[] array, T value) {
-        if (array == null) return -1;
-        for (int i = 0; i < array.length; i++) {
-            if (Objects.equals(array[i], value)) return i;
-        }
-        return -1;
-    }
-
-    /** @hide */
-    public static @NonNull File[] defeatNullable(@Nullable File[] val) {
-        return (val != null) ? val : EMPTY_FILE;
-    }
-
-    /**
-     * Checks if given array is null or has zero elements.
-     */
-    public static boolean isEmpty(@Nullable int[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
-     * True if the byte array is null or has length 0.
-     */
-    public static boolean isEmpty(@Nullable byte[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
-     * Converts from List of bytes to byte array
-     * @param list
-     * @return byte[]
-     */
-    public static byte[] toPrimitive(List<byte[]> list) {
-        if (list.size() == 0) {
-            return new byte[0];
-        }
-        int byteLen = list.get(0).length;
-        byte[] array = new byte[list.size() * byteLen];
-        for (int i = 0; i < list.size(); i++) {
-            for (int j = 0; j < list.get(i).length; j++) {
-                array[i * byteLen + j] = list.get(i)[j];
-            }
-        }
-        return array;
-    }
-
-    /**
-     * Adds value to given array if not already present, providing set-like
-     * behavior.
-     */
-    public static @NonNull int[] appendInt(@Nullable int[] cur, int val) {
-        return appendInt(cur, val, false);
-    }
-
-    /**
-     * Adds value to given array.
-     */
-    public static @NonNull int[] appendInt(@Nullable int[] cur, int val,
-            boolean allowDuplicates) {
-        if (cur == null) {
-            return new int[] { val };
-        }
-        final int n = cur.length;
-        if (!allowDuplicates) {
-            for (int i = 0; i < n; i++) {
-                if (cur[i] == val) {
-                    return cur;
-                }
-            }
-        }
-        int[] ret = new int[n + 1];
-        System.arraycopy(cur, 0, ret, 0, n);
-        ret[n] = val;
-        return ret;
-    }
-}
diff --git a/packages/CrashRecovery/services/java/com/android/utils/BackgroundThread.java b/packages/CrashRecovery/services/java/com/android/utils/BackgroundThread.java
deleted file mode 100644
index afcf689..0000000
--- a/packages/CrashRecovery/services/java/com/android/utils/BackgroundThread.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- *  * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.utils;
-
-import android.annotation.NonNull;
-import android.os.Handler;
-import android.os.HandlerThread;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.concurrent.Executor;
-
-/**
- * Thread for asynchronous event processing. This thread is configured as
- * {@link android.os.Process#THREAD_PRIORITY_BACKGROUND}, which means fewer CPU
- * resources will be dedicated to it, and it will "have less chance of impacting
- * the responsiveness of the user interface."
- * <p>
- * This thread is best suited for tasks that the user is not actively waiting
- * for, or for tasks that the user expects to be executed eventually.
- *
- * @see com.android.internal.os.BackgroundThread
- *
- * TODO: b/326916057 depend on modules-utils-backgroundthread instead
- * @hide
- */
-public final class BackgroundThread extends HandlerThread {
-    private static final Object sLock = new Object();
-
-    @GuardedBy("sLock")
-    private static BackgroundThread sInstance;
-    @GuardedBy("sLock")
-    private static Handler sHandler;
-    @GuardedBy("sLock")
-    private static HandlerExecutor sHandlerExecutor;
-
-    private BackgroundThread() {
-        super(BackgroundThread.class.getName(), android.os.Process.THREAD_PRIORITY_BACKGROUND);
-    }
-
-    @GuardedBy("sLock")
-    private static void ensureThreadLocked() {
-        if (sInstance == null) {
-            sInstance = new BackgroundThread();
-            sInstance.start();
-            sHandler = new Handler(sInstance.getLooper());
-            sHandlerExecutor = new HandlerExecutor(sHandler);
-        }
-    }
-
-    /**
-     * Get the singleton instance of this class.
-     *
-     * @return the singleton instance of this class
-     */
-    @NonNull
-    public static BackgroundThread get() {
-        synchronized (sLock) {
-            ensureThreadLocked();
-            return sInstance;
-        }
-    }
-
-    /**
-     * Get the singleton {@link Handler} for this class.
-     *
-     * @return the singleton {@link Handler} for this class.
-     */
-    @NonNull
-    public static Handler getHandler() {
-        synchronized (sLock) {
-            ensureThreadLocked();
-            return sHandler;
-        }
-    }
-
-    /**
-     * Get the singleton {@link Executor} for this class.
-     *
-     * @return the singleton {@link Executor} for this class.
-     */
-    @NonNull
-    public static Executor getExecutor() {
-        synchronized (sLock) {
-            ensureThreadLocked();
-            return sHandlerExecutor;
-        }
-    }
-}
diff --git a/packages/CrashRecovery/services/java/com/android/utils/FileUtils.java b/packages/CrashRecovery/services/java/com/android/utils/FileUtils.java
deleted file mode 100644
index e4923bf..0000000
--- a/packages/CrashRecovery/services/java/com/android/utils/FileUtils.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.utils;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Bits and pieces copied from hidden API of android.os.FileUtils.
- *
- * @hide
- */
-public class FileUtils {
-    /**
-     * Read a text file into a String, optionally limiting the length.
-     *
-     * @param file     to read (will not seek, so things like /proc files are OK)
-     * @param max      length (positive for head, negative of tail, 0 for no limit)
-     * @param ellipsis to add of the file was truncated (can be null)
-     * @return the contents of the file, possibly truncated
-     * @throws IOException if something goes wrong reading the file
-     * @hide
-     */
-    public static @Nullable String readTextFile(@Nullable File file, @Nullable int max,
-            @Nullable String ellipsis) throws IOException {
-        InputStream input = new FileInputStream(file);
-        // wrapping a BufferedInputStream around it because when reading /proc with unbuffered
-        // input stream, bytes read not equal to buffer size is not necessarily the correct
-        // indication for EOF; but it is true for BufferedInputStream due to its implementation.
-        BufferedInputStream bis = new BufferedInputStream(input);
-        try {
-            long size = file.length();
-            if (max > 0 || (size > 0 && max == 0)) {  // "head" mode: read the first N bytes
-                if (size > 0 && (max == 0 || size < max)) max = (int) size;
-                byte[] data = new byte[max + 1];
-                int length = bis.read(data);
-                if (length <= 0) return "";
-                if (length <= max) return new String(data, 0, length);
-                if (ellipsis == null) return new String(data, 0, max);
-                return new String(data, 0, max) + ellipsis;
-            } else if (max < 0) {  // "tail" mode: keep the last N
-                int len;
-                boolean rolled = false;
-                byte[] last = null;
-                byte[] data = null;
-                do {
-                    if (last != null) rolled = true;
-                    byte[] tmp = last;
-                    last = data;
-                    data = tmp;
-                    if (data == null) data = new byte[-max];
-                    len = bis.read(data);
-                } while (len == data.length);
-
-                if (last == null && len <= 0) return "";
-                if (last == null) return new String(data, 0, len);
-                if (len > 0) {
-                    rolled = true;
-                    System.arraycopy(last, len, last, 0, last.length - len);
-                    System.arraycopy(data, 0, last, last.length - len, len);
-                }
-                if (ellipsis == null || !rolled) return new String(last);
-                return ellipsis + new String(last);
-            } else {  // "cat" mode: size unknown, read it all in streaming fashion
-                ByteArrayOutputStream contents = new ByteArrayOutputStream();
-                int len;
-                byte[] data = new byte[1024];
-                do {
-                    len = bis.read(data);
-                    if (len > 0) contents.write(data, 0, len);
-                } while (len == data.length);
-                return contents.toString();
-            }
-        } finally {
-            bis.close();
-            input.close();
-        }
-    }
-
-    /**
-     * Perform an fsync on the given FileOutputStream. The stream at this
-     * point must be flushed but not yet closed.
-     *
-     * @hide
-     */
-    public static boolean sync(FileOutputStream stream) {
-        try {
-            if (stream != null) {
-                stream.getFD().sync();
-            }
-            return true;
-        } catch (IOException e) {
-        }
-        return false;
-    }
-
-    /**
-     * List the files in the directory or return empty file.
-     *
-     * @hide
-     */
-    public static @NonNull File[] listFilesOrEmpty(@Nullable File dir) {
-        return (dir != null) ? ArrayUtils.defeatNullable(dir.listFiles())
-            : ArrayUtils.EMPTY_FILE;
-    }
-}
diff --git a/packages/CrashRecovery/services/java/com/android/utils/HandlerExecutor.java b/packages/CrashRecovery/services/java/com/android/utils/HandlerExecutor.java
deleted file mode 100644
index fdb15e2..0000000
--- a/packages/CrashRecovery/services/java/com/android/utils/HandlerExecutor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.utils;
-
-import android.annotation.NonNull;
-import android.os.Handler;
-
-import java.util.Objects;
-import java.util.concurrent.Executor;
-import java.util.concurrent.RejectedExecutionException;
-
-/**
- * An adapter {@link Executor} that posts all executed tasks onto the given
- * {@link Handler}.
- *
- * TODO: b/326916057 depend on modules-utils-backgroundthread instead
- * @hide
- */
-public class HandlerExecutor implements Executor {
-    private final Handler mHandler;
-
-    public HandlerExecutor(@NonNull Handler handler) {
-        mHandler = Objects.requireNonNull(handler);
-    }
-
-    @Override
-    public void execute(Runnable command) {
-        if (!mHandler.post(command)) {
-            throw new RejectedExecutionException(mHandler + " is shutting down");
-        }
-    }
-}
diff --git a/packages/CrashRecovery/services/java/com/android/utils/LongArrayQueue.java b/packages/CrashRecovery/services/java/com/android/utils/LongArrayQueue.java
deleted file mode 100644
index 5cdc253..0000000
--- a/packages/CrashRecovery/services/java/com/android/utils/LongArrayQueue.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.utils;
-
-import libcore.util.EmptyArray;
-
-import java.util.NoSuchElementException;
-
-/**
- * Copied from frameworks/base/core/java/android/util/LongArrayQueue.java
- *
- * @hide
- */
-public class LongArrayQueue {
-
-    private long[] mValues;
-    private int mSize;
-    private int mHead;
-    private int mTail;
-
-    private long[] newUnpaddedLongArray(int num) {
-        return new long[num];
-    }
-    /**
-     * Initializes a queue with the given starting capacity.
-     *
-     * @param initialCapacity the capacity.
-     */
-    public LongArrayQueue(int initialCapacity) {
-        if (initialCapacity == 0) {
-            mValues = EmptyArray.LONG;
-        } else {
-            mValues = newUnpaddedLongArray(initialCapacity);
-        }
-        mSize = 0;
-        mHead = mTail = 0;
-    }
-
-    /**
-     * Initializes a queue with default starting capacity.
-     */
-    public LongArrayQueue() {
-        this(16);
-    }
-
-    /** @hide */
-    public static int growSize(int currentSize) {
-        return currentSize <= 4 ? 8 : currentSize * 2;
-    }
-
-    private void grow() {
-        if (mSize < mValues.length) {
-            throw new IllegalStateException("Queue not full yet!");
-        }
-        final int newSize = growSize(mSize);
-        final long[] newArray = newUnpaddedLongArray(newSize);
-        final int r = mValues.length - mHead; // Number of elements on and to the right of head.
-        System.arraycopy(mValues, mHead, newArray, 0, r);
-        System.arraycopy(mValues, 0, newArray, r, mHead);
-        mValues = newArray;
-        mHead = 0;
-        mTail = mSize;
-    }
-
-    /**
-     * Returns the number of elements in the queue.
-     */
-    public int size() {
-        return mSize;
-    }
-
-    /**
-     * Removes all elements from this queue.
-     */
-    public void clear() {
-        mSize = 0;
-        mHead = mTail = 0;
-    }
-
-    /**
-     * Adds a value to the tail of the queue.
-     *
-     * @param value the value to be added.
-     */
-    public void addLast(long value) {
-        if (mSize == mValues.length) {
-            grow();
-        }
-        mValues[mTail] = value;
-        mTail = (mTail + 1) % mValues.length;
-        mSize++;
-    }
-
-    /**
-     * Removes an element from the head of the queue.
-     *
-     * @return the element at the head of the queue.
-     * @throws NoSuchElementException if the queue is empty.
-     */
-    public long removeFirst() {
-        if (mSize == 0) {
-            throw new NoSuchElementException("Queue is empty!");
-        }
-        final long ret = mValues[mHead];
-        mHead = (mHead + 1) % mValues.length;
-        mSize--;
-        return ret;
-    }
-
-    /**
-     * Returns the element at the given position from the head of the queue, where 0 represents the
-     * head of the queue.
-     *
-     * @param position the position from the head of the queue.
-     * @return the element found at the given position.
-     * @throws IndexOutOfBoundsException if {@code position} < {@code 0} or
-     *                                   {@code position} >= {@link #size()}
-     */
-    public long get(int position) {
-        if (position < 0 || position >= mSize) {
-            throw new IndexOutOfBoundsException("Index " + position
-                + " not valid for a queue of size " + mSize);
-        }
-        final int index = (mHead + position) % mValues.length;
-        return mValues[index];
-    }
-
-    /**
-     * Returns the element at the head of the queue, without removing it.
-     *
-     * @return the element at the head of the queue.
-     * @throws NoSuchElementException if the queue is empty
-     */
-    public long peekFirst() {
-        if (mSize == 0) {
-            throw new NoSuchElementException("Queue is empty!");
-        }
-        return mValues[mHead];
-    }
-
-    /**
-     * Returns the element at the tail of the queue.
-     *
-     * @return the element at the tail of the queue.
-     * @throws NoSuchElementException if the queue is empty.
-     */
-    public long peekLast() {
-        if (mSize == 0) {
-            throw new NoSuchElementException("Queue is empty!");
-        }
-        final int index = (mTail == 0) ? mValues.length - 1 : mTail - 1;
-        return mValues[index];
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String toString() {
-        if (mSize <= 0) {
-            return "{}";
-        }
-
-        final StringBuilder buffer = new StringBuilder(mSize * 64);
-        buffer.append('{');
-        buffer.append(get(0));
-        for (int i = 1; i < mSize; i++) {
-            buffer.append(", ");
-            buffer.append(get(i));
-        }
-        buffer.append('}');
-        return buffer.toString();
-    }
-}
diff --git a/packages/CrashRecovery/services/java/com/android/utils/XmlUtils.java b/packages/CrashRecovery/services/java/com/android/utils/XmlUtils.java
deleted file mode 100644
index dbbef61..0000000
--- a/packages/CrashRecovery/services/java/com/android/utils/XmlUtils.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.utils;
-
-import android.annotation.NonNull;
-import android.system.ErrnoException;
-import android.system.Os;
-
-import com.android.modules.utils.TypedXmlPullParser;
-
-import libcore.util.XmlObjectFactory;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.BufferedInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Copied over partly from frameworks/base/core/java/com/android/internal/util/XmlUtils.java
- *
- * @hide
- */
-public class XmlUtils {
-
-    private static final String STRING_ARRAY_SEPARATOR = ":";
-
-    /** @hide */
-    public static final void beginDocument(XmlPullParser parser, String firstElementName)
-            throws XmlPullParserException, IOException {
-        int type;
-        while ((type = parser.next()) != parser.START_TAG
-            && type != parser.END_DOCUMENT) {
-            // Do nothing
-        }
-
-        if (type != parser.START_TAG) {
-            throw new XmlPullParserException("No start tag found");
-        }
-
-        if (!parser.getName().equals(firstElementName)) {
-            throw new XmlPullParserException("Unexpected start tag: found " + parser.getName()
-                + ", expected " + firstElementName);
-        }
-    }
-
-    /** @hide */
-    public static boolean nextElementWithin(XmlPullParser parser, int outerDepth)
-            throws IOException, XmlPullParserException {
-        for (;;) {
-            int type = parser.next();
-            if (type == XmlPullParser.END_DOCUMENT
-                    || (type == XmlPullParser.END_TAG && parser.getDepth() == outerDepth)) {
-                return false;
-            }
-            if (type == XmlPullParser.START_TAG
-                    && parser.getDepth() == outerDepth + 1) {
-                return true;
-            }
-        }
-    }
-
-    private static XmlPullParser newPullParser() {
-        try {
-            XmlPullParser parser = XmlObjectFactory.newXmlPullParser();
-            parser.setFeature(XmlPullParser.FEATURE_PROCESS_DOCDECL, true);
-            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-            return parser;
-        } catch (XmlPullParserException e) {
-            throw new AssertionError();
-        }
-    }
-
-    /** @hide */
-    public static @NonNull TypedXmlPullParser resolvePullParser(@NonNull InputStream in)
-            throws IOException {
-        final byte[] magic = new byte[4];
-        if (in instanceof FileInputStream) {
-            try {
-                Os.pread(((FileInputStream) in).getFD(), magic, 0, magic.length, 0);
-            } catch (ErrnoException e) {
-                throw e.rethrowAsIOException();
-            }
-        } else {
-            if (!in.markSupported()) {
-                in = new BufferedInputStream(in);
-            }
-            in.mark(8);
-            in.read(magic);
-            in.reset();
-        }
-
-        final TypedXmlPullParser xml;
-        xml = (TypedXmlPullParser) newPullParser();
-        try {
-            xml.setInput(in, "UTF_8");
-        } catch (XmlPullParserException e) {
-            throw new IOException(e);
-        }
-        return xml;
-    }
-}
diff --git a/packages/CredentialManager/res/values-af/strings.xml b/packages/CredentialManager/res/values-af/strings.xml
index c12b685..a24134b3 100644
--- a/packages/CredentialManager/res/values-af/strings.xml
+++ b/packages/CredentialManager/res/values-af/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Wagwoorde sal steeds saam met toegangsleutels beskikbaar wees terwyl ons na ’n wagwoordlose toekoms beweeg."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Kies waar om jou <xliff:g id="CREATETYPES">%1$s</xliff:g> te stoor"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Kies ’n wagwoordbestuurder om jou inligting te stoor en volgende keer vinniger aan te meld"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Skep toegangsleutel om by <xliff:g id="APP_NAME">%1$s</xliff:g> aan te meld?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Stoor wagwoord om by <xliff:g id="APP_NAME">%1$s</xliff:g> aan te meld?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Stoor aanmeldinligting vir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"toegangsleutel"</string>
     <string name="password" msgid="6738570945182936667">"wagwoord"</string>
     <string name="passkeys" msgid="5733880786866559847">"toegangsleutels"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Maak toe"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Gebruik jou gestoorde toegangsleutel vir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Gebruik jou gestoorde wagwoord vir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Gebruik jou skermslot om met <xliff:g id="USERNAME">%2$s</xliff:g> by <xliff:g id="APP_NAME">%1$s</xliff:g> aan te meld"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Gebruik jou aanmelding vir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Ontsluit aanmeldingopsies vir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Kies ’n gestoorde toegangsleutel vir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-am/strings.xml b/packages/CredentialManager/res/values-am/strings.xml
index fac267a..0554d81 100644
--- a/packages/CredentialManager/res/values-am/strings.xml
+++ b/packages/CredentialManager/res/values-am/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"ወደ የይለፍ ቃል የሌለው ወደፊት ስንሄድ የይለፍ ቃላት ከይለፍ ቁልፎች ጎን ለጎን ይገኛሉ።"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"የእርስዎን <xliff:g id="CREATETYPES">%1$s</xliff:g> የት እንደሚያስቀምጡ ይምረጡ"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"መረጃዎን ለማስቀመጥ እና በቀጣይ ጊዜ በፍጥነት በመለያ ለመግባት የሚስጥር ቁልፍ አስተዳዳሪን ይምረጡ"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"ወደ <xliff:g id="APP_NAME">%1$s</xliff:g> ለመግባት የይለፍ ቁልፍ ይፈጠር?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"ወደ <xliff:g id="APP_NAME">%1$s</xliff:g> ለመግባት የይለፍ ቃል ይቀመጥ?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"የ<xliff:g id="APP_NAME">%1$s</xliff:g> የመግቢያ መረጃ ይቀመጥ?"</string>
     <string name="passkey" msgid="632353688396759522">"የይለፍ ቁልፍ"</string>
     <string name="password" msgid="6738570945182936667">"የይለፍ ቃል"</string>
     <string name="passkeys" msgid="5733880786866559847">"የይለፍ ቁልፎች"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"አሰናብት"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"የተቀመጠ የይለፍ ቁልፍዎን ለ<xliff:g id="APP_NAME">%1$s</xliff:g> ይጠቀሙ?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"ለ<xliff:g id="APP_NAME">%1$s</xliff:g> የተቀመጠውን የይለፍ ቃልዎን ይጠቀሙ?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"በ<xliff:g id="USERNAME">%2$s</xliff:g> ወደ <xliff:g id="APP_NAME">%1$s</xliff:g> ለመግባት የማያ ገጽ መቆለፊያዎን ይጠቀሙ"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"ለ<xliff:g id="APP_NAME">%1$s</xliff:g> መግቢያዎ ጥቅም ላይ ይዋል?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"ለ<xliff:g id="APP_NAME">%1$s</xliff:g> የመግቢያ አማራጮች ይከፈቱ?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"ለ<xliff:g id="APP_NAME">%1$s</xliff:g> የተቀመጠ የይለፍ ቁልፍ ይምረጡ"</string>
diff --git a/packages/CredentialManager/res/values-ar/strings.xml b/packages/CredentialManager/res/values-ar/strings.xml
index 835eceb..5e089fe 100644
--- a/packages/CredentialManager/res/values-ar/strings.xml
+++ b/packages/CredentialManager/res/values-ar/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"بينما ننطلق نحو مستقبل بدون كلمات مرور، ستظل كلمات المرور متوفّرة إلى جانب مفاتيح المرور."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"اختيار المكان الذي تريد حفظ <xliff:g id="CREATETYPES">%1$s</xliff:g> فيه"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"اختَر مدير كلمات مرور لحفظ معلوماتك وتسجيل الدخول بشكل أسرع في المرة القادمة."</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"هل تريد إنشاء مفتاح مرور لتسجيل الدخول إلى \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"؟"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"هل تريد حفظ كلمة المرور لتسجيل الدخول إلى \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"؟"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"هل تريد حفظ معلومات تسجيل الدخول إلى \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"؟"</string>
     <string name="passkey" msgid="632353688396759522">"مفتاح المرور"</string>
     <string name="password" msgid="6738570945182936667">"كلمة المرور"</string>
     <string name="passkeys" msgid="5733880786866559847">"مفاتيح المرور"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"إغلاق"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"هل تريد استخدام مفتاح المرور المحفوظ لتطبيق \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"؟"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"هل تريد استخدام كلمة المرور المحفوظة لتطبيق \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"؟"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"استخدِم قفل الشاشة لتسجيل الدخول إلى \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" باستخدام <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"هل تريد استخدام معلومات تسجيل دخولك لتطبيق \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"؟"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"هل تريد فتح القفل لاستعادة خيارات تسجيل الدخول لتطبيق \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"؟"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"اختيار مفتاح مرور محفوظ لتطبيق \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
diff --git a/packages/CredentialManager/res/values-as/strings.xml b/packages/CredentialManager/res/values-as/strings.xml
index c65e734..95a0e1b 100644
--- a/packages/CredentialManager/res/values-as/strings.xml
+++ b/packages/CredentialManager/res/values-as/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"আমি পাছৱৰ্ডবিহীন ভৱিষ্যতৰ দিশে আগবঢ়াৰ লগে লগে পাছকীৰ লগতে পাছৱৰ্ডসমূহো উপলব্ধ হ’ব।"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"আপোনাৰ <xliff:g id="CREATETYPES">%1$s</xliff:g> ক’ত ছেভ কৰিব লাগে সেয়া বাছনি কৰক"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"আপোনাৰ তথ্য ছেভ কৰি পৰৱৰ্তী সময়ত দ্ৰুতভাৱে ছাইন ইন কৰিবলৈ এটা পাছৱৰ্ড পৰিচালক বাছনি কৰক"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g>ত ছাইন ইন কৰিবলৈ পাছকী সৃষ্টি কৰিবনে?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g>ত ছাইন ইন কৰিবলৈ পাছৱৰ্ড ছেভ কৰিবনে?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাবে ছাইন ইনৰ তথ্য ছেভ কৰিবনে?"</string>
     <string name="passkey" msgid="632353688396759522">"পাছকী"</string>
     <string name="password" msgid="6738570945182936667">"পাছৱৰ্ড"</string>
     <string name="passkeys" msgid="5733880786866559847">"পাছকী"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"অগ্ৰাহ্য কৰক"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাবে আপোনাৰ ছেভ হৈ থকা পাছকী ব্যৱহাৰ কৰিবনে?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাবে আপোনাৰ ছেভ কৰি থোৱা পাছৱৰ্ড ব্যৱহাৰ কৰিবনে?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="USERNAME">%2$s</xliff:g>ৰ জৰিয়তে <xliff:g id="APP_NAME">%1$s</xliff:g>ত ছাইন ইন কৰিবলৈ আপোনাৰ স্ক্ৰীন লক ব্যৱহাৰ কৰক"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাবে ছাইন ইন কৰিবলৈ আপোনাৰ ক্ৰিডেনশ্বিয়েল ব্যৱহাৰ কৰিবনে?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাবে ছাইন ইনৰ বিকল্পসমূহ আনলক কৰিবনে?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাবে ছেভ হৈ থকা এটা পাছকী বাছনি কৰক"</string>
diff --git a/packages/CredentialManager/res/values-az/strings.xml b/packages/CredentialManager/res/values-az/strings.xml
index 7df31b8..00a6718 100644
--- a/packages/CredentialManager/res/values-az/strings.xml
+++ b/packages/CredentialManager/res/values-az/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsuz gələcəyə doğru irəlilədikcə parollar hələ də açarlar ilə yanaşı əlçatan olacaq."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> elementinin saxlanacağı yeri seçin"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Məlumatlarınızı yadda saxlamaq və növbəti dəfə daha sürətli daxil olmaq üçün parol meneceri seçin"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinə daxil olmaq üçün giriş açarı yaradılsın?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinə daxil olmaq üçün parol yadda saxlansın?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün giriş məlumatları yadda saxlansın?"</string>
     <string name="passkey" msgid="632353688396759522">"açar"</string>
     <string name="password" msgid="6738570945182936667">"parol"</string>
     <string name="passkeys" msgid="5733880786866559847">"açarlar"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"İmtina edin"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün yadda saxlanmış giriş açarı istifadə edilsin?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün yadda saxlanmış parol istifadə edilsin?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinə <xliff:g id="USERNAME">%2$s</xliff:g> ilə daxil olmaq üçün ekran kilidindən istifadə edin"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün giriş istifadə edilsin?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün giriş seçimləri kiliddən çıxarılsın?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün yadda saxlanmış giriş açarı seçin"</string>
diff --git a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
index e1c92c3..390c774 100644
--- a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Kako se krećemo ka budućnosti bez lozinki, lozinke će i dalje biti dostupne uz pristupne kodove."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Odaberite gde ćete sačuvati: <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Izaberite menadžera lozinki da biste sačuvali podatke i brže se prijavili sledeći put"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Želite da napravite pristupni ključ da biste se prijavili u <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Želite da sačuvate lozinku da biste se prijavili u <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Želite da sačuvate podatke za prijavljivanje za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"pristupni kôd"</string>
     <string name="password" msgid="6738570945182936667">"lozinka"</string>
     <string name="passkeys" msgid="5733880786866559847">"pristupni kodovi"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Odbaci"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Želite da koristite sačuvani pristupni kôd za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Želite da koristite sačuvanu lozinku za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Koristite otključavanje ekrana da biste se prijavili u <xliff:g id="APP_NAME">%1$s</xliff:g> kao <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Želite li da koristite svoje podatke za prijavljivanje za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Želite da otključate opcije prijavljivanja za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Izaberite sačuvan pristupni ključ za: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-be/strings.xml b/packages/CredentialManager/res/values-be/strings.xml
index ef0c12d..6922e70 100644
--- a/packages/CredentialManager/res/values-be/strings.xml
+++ b/packages/CredentialManager/res/values-be/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Хоць мы ўжо рухаемся ў бок будучыні без выкарыстання пароляў, яны па-ранейшаму застануцца даступнымі нароўні з ключамі доступу."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Выберыце, куды захаваць <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Выберыце менеджар пароляў, каб захаваць свае даныя і забяспечыць хуткі ўваход у наступныя разы"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Стварыць ключ доступу для ўваходу ў праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Захаваць пароль для ўваходу ў праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Захаваць даныя для ўваходу ў праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
     <string name="passkey" msgid="632353688396759522">"ключ доступу"</string>
     <string name="password" msgid="6738570945182936667">"пароль"</string>
     <string name="passkeys" msgid="5733880786866559847">"ключы доступу"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Закрыць"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Скарыстаць захаваны ключ доступу для праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Выкарыстоўваць пароль, захаваны для праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Выкарыстайце сродак разблакіроўкі экрана для ўваходу ў праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" як <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Скарыстаць ваш спосаб уваходу для праграмы <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Разблакіраваць варыянты ўваходу для праграмы\"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Выберыце захаваны ключ доступу для праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
diff --git a/packages/CredentialManager/res/values-bg/strings.xml b/packages/CredentialManager/res/values-bg/strings.xml
index fc6932e..3d33c8f 100644
--- a/packages/CredentialManager/res/values-bg/strings.xml
+++ b/packages/CredentialManager/res/values-bg/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Паролите ще продължат да са налице заедно с ключовете за достъп по пътя ни към бъдеще без пароли."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Изберете къде да запазите своите <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Изберете мениджър на пароли, в който да се запазят данните ви, така че следващия път да влезете по-бързо в профила си"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Искате ли да създадете ключ за достъп, с който да влизате в(ъв) <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Искате ли да запазите паролата за влизане в(ъв) <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Искате ли да запазите данните за вход за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"код за достъп"</string>
     <string name="password" msgid="6738570945182936667">"парола"</string>
     <string name="passkeys" msgid="5733880786866559847">"ключове за достъп"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Отхвърляне"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Да се използва ли запазеният ви код за достъп за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Искате ли да използвате запазената си парола за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Използвайте опцията си за заключване на екрана, за да влизате в(ъв) <xliff:g id="APP_NAME">%1$s</xliff:g> с профила <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Да се използват ли вашите данни за вход за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Искате ли да отключите опциите за влизане в профила за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Изберете запазен ключ за достъп за <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-bn/strings.xml b/packages/CredentialManager/res/values-bn/strings.xml
index 329189e..fe42ed6 100644
--- a/packages/CredentialManager/res/values-bn/strings.xml
+++ b/packages/CredentialManager/res/values-bn/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"আমরা পাসওয়ার্ডবিহীন ভবিষ্যতের দিকে এগিয়ে গেলেও, এখনও \'পাসকী\'-এর পাশাপাশি পাসওয়ার্ড ব্যবহার করা যাবে।"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"আপনার <xliff:g id="CREATETYPES">%1$s</xliff:g> কোথায় সেভ করবেন তা বেছে নিন"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"আপনার তথ্য সেভ করতে একটি Password Manager বেছে নিন এবং পরের বার আরও দ্রুত সাইন-ইন করুন"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপে সাইন-ইন করার জন্য পাসকী তৈরি করবেন?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপে সাইন-ইন করার জন্য পাসওয়ার্ড সেভ করবেন?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপের জন্য সাইন-ইন সংক্রান্ত তথ্য সেভ করবেন?"</string>
     <string name="passkey" msgid="632353688396759522">"পাসকী"</string>
     <string name="password" msgid="6738570945182936667">"পাসওয়ার্ড"</string>
     <string name="passkeys" msgid="5733880786866559847">"পাসকী"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"বাতিল করুন"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এর জন্য আপনার সেভ করা পাসকী ব্যবহার করবেন?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"আপনার সেভ করা পাসওয়ার্ড <xliff:g id="APP_NAME">%1$s</xliff:g>-এর জন্য ব্যবহার করবেন?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"আপনার স্ক্রিন লক ব্যবহার করে <xliff:g id="USERNAME">%2$s</xliff:g>-এর মাধ্যমে <xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপে সাইন-ইন করুন"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এর জন্য আপনার সাইন-ইন ক্রেডেনশিয়াল ব্যবহার করবেন?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এর জন্য সাইন-ইন করার বিকল্প আনলক করতে চান?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এর জন্য সেভ করা পাসকী বেছে নিন"</string>
diff --git a/packages/CredentialManager/res/values-bs/strings.xml b/packages/CredentialManager/res/values-bs/strings.xml
index 05f0f1e..f6e6d811 100644
--- a/packages/CredentialManager/res/values-bs/strings.xml
+++ b/packages/CredentialManager/res/values-bs/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Kako se krećemo prema budućnosti bez lozinki, lozinke će i dalje biti dostupne uz pristupne ključeve."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Odaberite gdje će se pohranjivati <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Odaberite upravitelja lozinki da sačuvate svoje informacije i brže se prijavite sljedeći put"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Kreirati pristupni ključ da se prijavite u aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Sačuvati lozinku da se prijavite u aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Sačuvati podatke za prijavu u aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"pristupni ključ"</string>
     <string name="password" msgid="6738570945182936667">"lozinka"</string>
     <string name="passkeys" msgid="5733880786866559847">"pristupni ključevi"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Odbacivanje"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Koristiti sačuvani pristupni ključ za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Koristiti sačuvanu lozinku za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Koristite zaključavanje ekrana da se prijavite u aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> s korisničkim imenom <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Koristiti prijavu za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Otključati opcije prijave za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Odaberite sačuvani pristupni ključ za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-ca/strings.xml b/packages/CredentialManager/res/values-ca/strings.xml
index ba34d61..3809d92 100644
--- a/packages/CredentialManager/res/values-ca/strings.xml
+++ b/packages/CredentialManager/res/values-ca/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Tot i que avancem cap a un futur sense contrasenyes, continuaran estant disponibles juntament amb les claus d\'accés."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Tria on vols desar les <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un gestor de contrasenyes per desar la teva informació i iniciar la sessió més ràpidament la pròxima vegada"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Vols crear una clau d\'accés per iniciar la sessió a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Vols desar la contrasenya per iniciar la sessió a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Vols desar la informació d\'inici de sessió per a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"clau d\'accés"</string>
     <string name="password" msgid="6738570945182936667">"contrasenya"</string>
     <string name="passkeys" msgid="5733880786866559847">"claus d\'accés"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Ignora"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Vols utilitzar la clau d\'accés desada per a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Vols utilitzar la contrasenya desada per a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Utilitza el bloqueig de pantalla per iniciar sessió a <xliff:g id="APP_NAME">%1$s</xliff:g> amb <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Vols utilitzar el teu inici de sessió per a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Vols desbloquejar les opcions d\'inici de sessió per a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Tria una clau d\'accés desada per a <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-cs/strings.xml b/packages/CredentialManager/res/values-cs/strings.xml
index 2727737..6e6857c 100644
--- a/packages/CredentialManager/res/values-cs/strings.xml
+++ b/packages/CredentialManager/res/values-cs/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Ačkoliv směřujeme k budoucnosti bez hesel, vedle přístupových klíčů budou stále k dispozici i hesla."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Určete, kam ukládat <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Vyberte správce hesel k uložení svých údajů, abyste se příště mohli přihlásit rychleji"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Vytvořit přístupový klíč k přihlašování do aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Uložit heslo k přihlašování do aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Uložit přihlašovací údaje pro aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"přístupový klíč"</string>
     <string name="password" msgid="6738570945182936667">"heslo"</string>
     <string name="passkeys" msgid="5733880786866559847">"přístupové klíče"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Zavřít"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Použít uložený přístupový klíč pro aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Použít pro aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> uložené heslo?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Přihlašovat se do aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> uživatelským jménem <xliff:g id="USERNAME">%2$s</xliff:g> pomocí zámku obrazovky"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Použít přihlášení pro <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Odemknout možnosti přihlášení pro aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Vyberte uložený přístupový klíč pro aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-da/strings.xml b/packages/CredentialManager/res/values-da/strings.xml
index d3ff9e7..ae7c3cf 100644
--- a/packages/CredentialManager/res/values-da/strings.xml
+++ b/packages/CredentialManager/res/values-da/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Selvom vi nærmer os en fremtid, hvor adgangskoder er mindre fremtrædende, kan de stadig bruges i samspil med adgangsnøgler."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Vælg, hvor du vil gemme dine <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Vælg en adgangskodeadministrator for at gemme dine oplysninger, så du kan logge ind hurtigere næste gang"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Vil du oprette en adgangsnøgle for at logge ind på <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Vil du gemme adgangskoden for at logge ind på <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Vil du gemme loginoplysningerne til <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"adgangsnøgle"</string>
     <string name="password" msgid="6738570945182936667">"adgangskode"</string>
     <string name="passkeys" msgid="5733880786866559847">"adgangsnøgler"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Luk"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Vil du bruge din gemte adgangsnøgle til <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Vil du bruge din gemte adgangskode til <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Brug din skærmlås til at logge ind på <xliff:g id="APP_NAME">%1$s</xliff:g> med <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Vil du bruge dine loginoplysninger til <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Vil du låse enheden op for at se loginmetoder for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Vælg en gemt adgangsnøgle til <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-de/strings.xml b/packages/CredentialManager/res/values-de/strings.xml
index cb01139..4fa669b 100644
--- a/packages/CredentialManager/res/values-de/strings.xml
+++ b/packages/CredentialManager/res/values-de/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Auch wenn wir uns auf eine passwortlose Zukunft zubewegen, werden neben Passkeys weiter Passwörter verfügbar sein."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Wähle aus, wo deine <xliff:g id="CREATETYPES">%1$s</xliff:g> gespeichert werden sollen"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Du kannst einen Passwortmanager auswählen, um deine Anmeldedaten zu speichern, damit du dich nächstes Mal schneller anmelden kannst"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Passkey zur Anmeldung in <xliff:g id="APP_NAME">%1$s</xliff:g> erstellen?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Passwort zur Anmeldung in <xliff:g id="APP_NAME">%1$s</xliff:g> speichern?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Anmeldedaten für <xliff:g id="APP_NAME">%1$s</xliff:g> speichern?"</string>
     <string name="passkey" msgid="632353688396759522">"Passkey"</string>
     <string name="password" msgid="6738570945182936667">"Passwort"</string>
     <string name="passkeys" msgid="5733880786866559847">"Passkeys"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Schließen"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Gespeicherten Passkey für <xliff:g id="APP_NAME">%1$s</xliff:g> verwenden?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Soll dein gespeichertes Passwort für <xliff:g id="APP_NAME">%1$s</xliff:g> verwendet werden?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Du kannst die Displaysperre verwenden, um dich in <xliff:g id="APP_NAME">%1$s</xliff:g> als <xliff:g id="USERNAME">%2$s</xliff:g> anzumelden"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Anmeldedaten für <xliff:g id="APP_NAME">%1$s</xliff:g> verwenden?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Anmeldeoptionen für <xliff:g id="APP_NAME">%1$s</xliff:g> freischalten?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Einen gespeicherten Passkey für <xliff:g id="APP_NAME">%1$s</xliff:g> auswählen"</string>
diff --git a/packages/CredentialManager/res/values-el/strings.xml b/packages/CredentialManager/res/values-el/strings.xml
index c8e4099..b6b2728 100644
--- a/packages/CredentialManager/res/values-el/strings.xml
+++ b/packages/CredentialManager/res/values-el/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Καθώς κινούμαστε προς ένα μέλλον χωρίς κωδικούς πρόσβασης, οι κωδικοί πρόσβασης θα εξακολουθούν να είναι διαθέσιμοι μαζί με τα κλειδιά πρόσβασης."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Επιλέξτε πού θα αποθηκεύονται τα <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Επιλέξτε ένα πρόγραμμα διαχείρισης κωδικών πρόσβασης για να αποθηκεύσετε τα στοιχεία σας και να συνδεθείτε πιο γρήγορα την επόμενη φορά."</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Δημιουργία κλειδιού πρόσβασης για σύνδεση στην εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Αποθήκευση κωδικού πρόσβασης για σύνδεση στην εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Αποθήκευση πληροφοριών σύνδεσης για την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
     <string name="passkey" msgid="632353688396759522">"κλειδί πρόσβασης"</string>
     <string name="password" msgid="6738570945182936667">"κωδικός πρόσβασης"</string>
     <string name="passkeys" msgid="5733880786866559847">"κλειδιά πρόσβασης"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Παράβλεψη"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Να χρησιμοποιηθεί το αποθηκευμένο κλειδί πρόσβασης για την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Χρήση του αποθηκευμένου κωδικού πρόσβασης για την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Χρησιμοποιήστε το κλείδωμα οθόνης για να συνδεθείτε στην εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> με το όνομα χρήστη <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Χρήση της σύνδεσής σας για την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Ξεκλείδωμα των επιλογών σύνδεσης για την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Επιλογή αποθηκευμένου κλειδιού πρόσβασης για την εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-en-rAU/strings.xml b/packages/CredentialManager/res/values-en-rAU/strings.xml
index f30b856..f177cf9 100644
--- a/packages/CredentialManager/res/values-en-rAU/strings.xml
+++ b/packages/CredentialManager/res/values-en-rAU/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"As we move towards a passwordless future, passwords will still be available alongside passkeys."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Choose where to save your <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Select a password manager to save your info and sign in faster next time"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Create passkey to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Save password to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Save sign-in info for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"passkey"</string>
     <string name="password" msgid="6738570945182936667">"password"</string>
     <string name="passkeys" msgid="5733880786866559847">"passkeys"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Dismiss"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Use your saved passkey for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Use your saved password for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Use your screen lock to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g> with <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Use your sign-in for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Unlock sign-in options for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Choose a saved passkey for <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-en-rCA/strings.xml b/packages/CredentialManager/res/values-en-rCA/strings.xml
index 5eb63c6..df4cd86 100644
--- a/packages/CredentialManager/res/values-en-rCA/strings.xml
+++ b/packages/CredentialManager/res/values-en-rCA/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"As we move towards a passwordless future, passwords will still be available alongside passkeys."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Choose where to save your <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Select a password manager to save your info and sign in faster next time"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Create passkey to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Save password to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Save sign-in info for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"passkey"</string>
     <string name="password" msgid="6738570945182936667">"password"</string>
     <string name="passkeys" msgid="5733880786866559847">"passkeys"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Dismiss"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Use your saved passkey for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Use your saved password for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Use your screen lock to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g> with <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Use your sign-in for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Unlock sign-in options for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Choose a saved passkey for <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-en-rGB/strings.xml b/packages/CredentialManager/res/values-en-rGB/strings.xml
index f30b856..f177cf9 100644
--- a/packages/CredentialManager/res/values-en-rGB/strings.xml
+++ b/packages/CredentialManager/res/values-en-rGB/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"As we move towards a passwordless future, passwords will still be available alongside passkeys."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Choose where to save your <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Select a password manager to save your info and sign in faster next time"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Create passkey to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Save password to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Save sign-in info for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"passkey"</string>
     <string name="password" msgid="6738570945182936667">"password"</string>
     <string name="passkeys" msgid="5733880786866559847">"passkeys"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Dismiss"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Use your saved passkey for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Use your saved password for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Use your screen lock to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g> with <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Use your sign-in for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Unlock sign-in options for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Choose a saved passkey for <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-en-rIN/strings.xml b/packages/CredentialManager/res/values-en-rIN/strings.xml
index f30b856..f177cf9 100644
--- a/packages/CredentialManager/res/values-en-rIN/strings.xml
+++ b/packages/CredentialManager/res/values-en-rIN/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"As we move towards a passwordless future, passwords will still be available alongside passkeys."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Choose where to save your <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Select a password manager to save your info and sign in faster next time"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Create passkey to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Save password to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Save sign-in info for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"passkey"</string>
     <string name="password" msgid="6738570945182936667">"password"</string>
     <string name="passkeys" msgid="5733880786866559847">"passkeys"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Dismiss"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Use your saved passkey for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Use your saved password for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Use your screen lock to sign in to <xliff:g id="APP_NAME">%1$s</xliff:g> with <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Use your sign-in for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Unlock sign-in options for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Choose a saved passkey for <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-en-rXC/strings.xml b/packages/CredentialManager/res/values-en-rXC/strings.xml
index 067d106..77ae53a 100644
--- a/packages/CredentialManager/res/values-en-rXC/strings.xml
+++ b/packages/CredentialManager/res/values-en-rXC/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‎‎‎‏‏‎As we move towards a passwordless future, passwords will still be available alongside passkeys.‎‏‎‎‏‎"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‎‎‏‏‎‏‎‎‎‎‏‎‎‎‏‏‎‏‎‏‎‏‏‏‎‎‎‎‏‏‎‎‎Choose where to save your ‎‏‎‎‏‏‎<xliff:g id="CREATETYPES">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‎‏‏‎‎‏‎‏‎‏‎‎Select a password manager to save your info and sign in faster next time‎‏‎‎‏‎"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‎‏‏‏‏‏‎Create passkey to sign in to ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‎‎‎‏‎‎‎‎‎‎‏‏‏‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‎‎‎Save password to sign in to ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‏‏‏‏‏‎Save sign-in info for ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
     <string name="passkey" msgid="632353688396759522">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‎‎‎‎‏‏‏‏‎‎‎‏‎‎passkey‎‏‎‎‏‎"</string>
     <string name="password" msgid="6738570945182936667">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎password‎‏‎‎‏‎"</string>
     <string name="passkeys" msgid="5733880786866559847">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‏‏‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‎‏‏‏‎passkeys‎‏‎‎‏‎"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‎Dismiss‎‏‎‎‏‎"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‎‎‏‏‏‎Use your saved passkey for ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‎‏‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‎‎Use your saved password for ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‎‏‏‏‏‎‏‎‎‏‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‎‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‏‎‏‏‎Use your screen lock to sign in to ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ with ‎‏‎‎‏‏‎<xliff:g id="USERNAME">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‎‏‏‎‎‏‎‎‎‎‎‏‏‎‎‎‏‎‎‏‎Use your sign-in for ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎Unlock sign-in options for ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‎‏‏‎‎‎‏‎‏‎‎‎‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‏‏‎‏‎‎Choose a saved passkey for ‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
diff --git a/packages/CredentialManager/res/values-es-rUS/strings.xml b/packages/CredentialManager/res/values-es-rUS/strings.xml
index 41918f2..6ccfec3 100644
--- a/packages/CredentialManager/res/values-es-rUS/strings.xml
+++ b/packages/CredentialManager/res/values-es-rUS/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"A medida que avanzamos hacia un futuro sin contraseñas, estas seguirán estando disponibles junto a las llaves de acceso."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Elige dónde guardar tus <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un administrador de contraseñas para guardar tu información y acceder más rápido la próxima vez"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"¿Quieres crear una llave de acceso para acceder a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"¿Quieres guardar la contraseña para acceder a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"¿Quieres guardar la información de acceso para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"llave de acceso"</string>
     <string name="password" msgid="6738570945182936667">"contraseña"</string>
     <string name="passkeys" msgid="5733880786866559847">"llaves de acceso"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Descartar"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"¿Quieres usar tu llave de acceso guardada para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"¿Quieres usar la contraseña guardada para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Usar el bloqueo de pantalla para acceder a <xliff:g id="APP_NAME">%1$s</xliff:g> con <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"¿Quieres usar tu acceso para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"¿Quieres desbloquear las opciones de acceso para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Elige una llave de acceso guardada para <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-es/strings.xml b/packages/CredentialManager/res/values-es/strings.xml
index 35f9cad..b2c1c6f 100644
--- a/packages/CredentialManager/res/values-es/strings.xml
+++ b/packages/CredentialManager/res/values-es/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Aunque nos dirigimos hacia un mundo sin contraseñas, estas seguirán estando disponibles junto con las llaves de acceso."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Elige dónde guardar tus <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un gestor de contraseñas para guardar tu información e iniciar sesión más rápido la próxima vez"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"¿Crear llave de acceso para iniciar sesión en <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"¿Guardar contraseña para iniciar sesión en <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"¿Guardar la información de inicio de sesión de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"llave de acceso"</string>
     <string name="password" msgid="6738570945182936667">"contraseña"</string>
     <string name="passkeys" msgid="5733880786866559847">"llaves de acceso"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Cerrar"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"¿Usar la llave de acceso guardada para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"¿Usar la contraseña que tienes guardada para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Usa tu bloqueo de pantalla para iniciar sesión en <xliff:g id="APP_NAME">%1$s</xliff:g> con el usuario <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"¿Usar tu inicio de sesión en <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"¿Desbloquear las opciones de inicio de sesión de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Elige una llave de acceso guardada para <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-et/strings.xml b/packages/CredentialManager/res/values-et/strings.xml
index d9581bd..823a016 100644
--- a/packages/CredentialManager/res/values-et/strings.xml
+++ b/packages/CredentialManager/res/values-et/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Liikudes paroolivaba tuleviku poole, jäävad paroolid pääsuvõtmete kõrval siiski kättesaadavaks."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Valige, kuhu soovite oma <xliff:g id="CREATETYPES">%1$s</xliff:g> salvestada"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Valige paroolihaldur, et salvestada oma teave ja järgmisel korral kiiremini sisse logida"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Kas luua rakendusse <xliff:g id="APP_NAME">%1$s</xliff:g> sisselogimiseks pääsuvõti?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Kas salvestada rakendusse <xliff:g id="APP_NAME">%1$s</xliff:g> sisselogimiseks parool?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Kas salvestada rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> jaoks sisselogimisteave?"</string>
     <string name="passkey" msgid="632353688396759522">"pääsuvõti"</string>
     <string name="password" msgid="6738570945182936667">"parool"</string>
     <string name="passkeys" msgid="5733880786866559847">"pääsuvõtmed"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Loobu"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Kas kasutada rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> jaoks salvestatud pääsuvõtit?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Kas kasutada rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> puhul salvestatud parooli?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Kasutage rakendusse <xliff:g id="APP_NAME">%1$s</xliff:g> kasutajanimega <xliff:g id="USERNAME">%2$s</xliff:g> sisselogimiseks ekraanilukku"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Kas soovite rakendusse <xliff:g id="APP_NAME">%1$s</xliff:g> sisselogimiseks kasutada oma mandaati?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Kas avada rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> jaoks sisselogimisvalikud?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Valige rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> jaoks salvestatud pääsuvõti"</string>
diff --git a/packages/CredentialManager/res/values-eu/strings.xml b/packages/CredentialManager/res/values-eu/strings.xml
index ffe2091..8507b3f 100644
--- a/packages/CredentialManager/res/values-eu/strings.xml
+++ b/packages/CredentialManager/res/values-eu/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Pasahitzik gabeko etorkizun baterantz goazen arren, pasahitzek sarbide-gakoen bizikide izaten jarraituko dute."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Aukeratu non gorde <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Hautatu informazioa gordetzeko pasahitz-kudeatzaile bat eta hasi saioa bizkorrago hurrengoan"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioan saioa hasteko sarbide-gako bat sortu nahi duzu?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioan saioa hasteko pasahitza gorde nahi duzu?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioan saioa hasteko informazioa gorde nahi duzu?"</string>
     <string name="passkey" msgid="632353688396759522">"sarbide-gakoa"</string>
     <string name="password" msgid="6738570945182936667">"pasahitza"</string>
     <string name="passkeys" msgid="5733880786866559847">"sarbide-gakoak"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Baztertu"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikaziorako gorde duzun sarbide-gakoa erabili nahi duzu?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikaziorako gordetako pasahitza erabili nahi duzu?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Erabili pantailaren blokeoa <xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioan <xliff:g id="USERNAME">%2$s</xliff:g> kontuarekin saioa hasteko"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> zerbitzuan saioa hasteko kredentzialak erabili nahi dituzu?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioan saioa hasteko aukerak desblokeatu nahi dituzu?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Aukeratu <xliff:g id="APP_NAME">%1$s</xliff:g> aplikaziorako gordetako sarbide-gakoa"</string>
diff --git a/packages/CredentialManager/res/values-fa/strings.xml b/packages/CredentialManager/res/values-fa/strings.xml
index 5d3198c..656c789 100644
--- a/packages/CredentialManager/res/values-fa/strings.xml
+++ b/packages/CredentialManager/res/values-fa/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"درحالی‌که به‌سوی آینده‌ای بی‌گذرواژه حرکت می‌کنیم، گذرواژه‌ها همچنان در کنار گذرکلیدها دردسترس خواهند بود"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"جایی را برای ذخیره کردن <xliff:g id="CREATETYPES">%1$s</xliff:g> انتخاب کنید"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"مدیر گذرواژه‌ای انتخاب کنید تا اطلاعاتتان را ذخیره کنید و دفعه بعد سریع‌تر به سیستم وارد شوید"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"برای ورود به سیستم <xliff:g id="APP_NAME">%1$s</xliff:g>، گذرکلید ایجاد شود؟"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"برای ورود به سیستم <xliff:g id="APP_NAME">%1$s</xliff:g>، گذرواژه ذخیره شود؟"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"اطلاعات ورود به سیستم <xliff:g id="APP_NAME">%1$s</xliff:g> ذخیره شود؟"</string>
     <string name="passkey" msgid="632353688396759522">"گذرکلید"</string>
     <string name="password" msgid="6738570945182936667">"گذرواژه"</string>
     <string name="passkeys" msgid="5733880786866559847">"گذرکلیدها"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"بستن"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"از گذرکلید ذخیره‌شده برای «<xliff:g id="APP_NAME">%1$s</xliff:g>» استفاده شود؟"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"از گذرواژه ذخیره‌شده‌تان برای <xliff:g id="APP_NAME">%1$s</xliff:g> استفاده شود؟"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"برای ورود به سیستم <xliff:g id="APP_NAME">%1$s</xliff:g> با <xliff:g id="USERNAME">%2$s</xliff:g> از قفل صفحه استفاده کنید"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"از روش ورود به سیستم شما برای <xliff:g id="APP_NAME">%1$s</xliff:g> استفاده شود؟"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"گزینه‌های ورود به سیستم برای <xliff:g id="APP_NAME">%1$s</xliff:g> باز شود؟"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"گذرکلید ذخیره‌شده‌ای را برای <xliff:g id="APP_NAME">%1$s</xliff:g> انتخاب کنید"</string>
diff --git a/packages/CredentialManager/res/values-fi/strings.xml b/packages/CredentialManager/res/values-fi/strings.xml
index 7091da8..f2f1bfb 100644
--- a/packages/CredentialManager/res/values-fi/strings.xml
+++ b/packages/CredentialManager/res/values-fi/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Kehitys kulkee kohti salasanatonta tulevaisuutta, mutta salasanat ovat edelleen käytettävissä avainkoodien ohella."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Valitse, minne <xliff:g id="CREATETYPES">%1$s</xliff:g> tallennetaan"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Valitse salasanojen ylläpitotyökalu, niin voit tallentaa tietosi ja kirjautua ensi kerralla nopeammin sisään"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Luodaanko avainkoodi sisäänkirjautumista (<xliff:g id="APP_NAME">%1$s</xliff:g>) varten?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Tallennetaanko salasana sisäänkirjautumista (<xliff:g id="APP_NAME">%1$s</xliff:g>) varten?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Tallennetaanko kirjautumistiedot (<xliff:g id="APP_NAME">%1$s</xliff:g>)?"</string>
     <string name="passkey" msgid="632353688396759522">"avainkoodi"</string>
     <string name="password" msgid="6738570945182936667">"salasana"</string>
     <string name="passkeys" msgid="5733880786866559847">"avainkoodit"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Sulje"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Käytetäänkö tallennettua avainkoodiasi täällä: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Käytetäänkö tallennettua salasanaasi sovelluksessa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Kirjaudu sisään (<xliff:g id="APP_NAME">%1$s</xliff:g>) käyttämällä näytön lukitusta tilillä <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Käytetäänkö kirjautumistapaa: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Avataanko kirjautumisvaihtoehdot (<xliff:g id="APP_NAME">%1$s</xliff:g>)?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g>: valitse tallennettu avainkoodi"</string>
diff --git a/packages/CredentialManager/res/values-fr-rCA/strings.xml b/packages/CredentialManager/res/values-fr-rCA/strings.xml
index ac7b77c..891e987 100644
--- a/packages/CredentialManager/res/values-fr-rCA/strings.xml
+++ b/packages/CredentialManager/res/values-fr-rCA/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"À mesure que nous nous dirigeons vers un avenir sans mot de passe, ils resteront toujours utilisés parallèlement aux clés d\'accès."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Choisir où enregistrer vos <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Sélectionnez un gestionnaire de mots de passe pour enregistrer vos renseignements et vous connecter plus rapidement la prochaine fois"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Créer une clé d\'accès pour se connecter à <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Enregistrer un mot de passe pour se connecter à <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Enregistrer les renseignements de connexion pour <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"clé d\'accès"</string>
     <string name="password" msgid="6738570945182936667">"mot de passe"</string>
     <string name="passkeys" msgid="5733880786866559847">"clés d\'accès"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Fermer"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Utiliser votre clé d\'accès enregistrée pour <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Utiliser votre mot de passe enregistré pour <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Utilisez votre verrouillage d\'écran pour vous connecter à <xliff:g id="APP_NAME">%1$s</xliff:g> avec <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Utiliser votre identifiant de connexion pour <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Déverrouiller les options de connexion pour <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Choisissez une clé d\'accès enregistrée pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-fr/strings.xml b/packages/CredentialManager/res/values-fr/strings.xml
index a6b2fe2..f2ca1fc 100644
--- a/packages/CredentialManager/res/values-fr/strings.xml
+++ b/packages/CredentialManager/res/values-fr/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Nous nous dirigeons vers un futur sans mots de passe, mais ceux-ci resteront disponibles en plus des clés d\'accès."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Choisissez où enregistrer vos <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Sélectionnez un gestionnaire de mots de passe pour enregistrer vos informations et vous connecter plus rapidement la prochaine fois"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Créer une clé d\'accès pour se connecter à <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Enregistrer un mot de passe pour se connecter à <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Enregistrer les informations de connexion pour <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
     <string name="passkey" msgid="632353688396759522">"clé d\'accès"</string>
     <string name="password" msgid="6738570945182936667">"mot de passe"</string>
     <string name="passkeys" msgid="5733880786866559847">"clés d\'accès"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Fermer"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Utiliser votre clé d\'accès enregistrée pour <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Utiliser votre mot de passe enregistré pour <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Utiliser le verrouillage de l\'écran pour se connecter à <xliff:g id="APP_NAME">%1$s</xliff:g> avec <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Utiliser vos infos de connexion pour <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Déverrouiller les options de connexion pour <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Choisir une clé d\'accès enregistrée pour <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-gl/strings.xml b/packages/CredentialManager/res/values-gl/strings.xml
index 76a9d4b..7117e1c 100644
--- a/packages/CredentialManager/res/values-gl/strings.xml
+++ b/packages/CredentialManager/res/values-gl/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Durante este percorrido cara a un futuro sen contrasinais, estes seguirán estando dispoñibles a canda as claves de acceso."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Escolle onde queres gardar: <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Selecciona un xestor de contrasinais para gardar a túa información e iniciar sesión máis rápido a próxima vez"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Queres crear unha clave de acceso para iniciar sesión en <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Queres gardar o contrasinal para iniciar sesión en <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Queres gardar a información de inicio de sesión de <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"clave de acceso"</string>
     <string name="password" msgid="6738570945182936667">"contrasinal"</string>
     <string name="passkeys" msgid="5733880786866559847">"claves de acceso"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Pechar"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Queres usar a clave de acceso gardada para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Queres usar o contrasinal gardado para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Usa o bloqueo de pantalla para iniciar sesión en <xliff:g id="APP_NAME">%1$s</xliff:g> con <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Queres usar o teu inicio de sesión para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Queres desbloquear as opcións de inicio de sesión para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Escolle unha clave de acceso gardada para <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-gu/strings.xml b/packages/CredentialManager/res/values-gu/strings.xml
index 11d1df6..98b4686 100644
--- a/packages/CredentialManager/res/values-gu/strings.xml
+++ b/packages/CredentialManager/res/values-gu/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"આપણે પાસવર્ડ રહિત ભવિષ્ય તરફ આગળ વધી રહ્યાં છીએ, છતાં પાસકીની સાથોસાથ હજી પણ પાસવર્ડ ઉપલબ્ધ રહેશે."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"તમારી <xliff:g id="CREATETYPES">%1$s</xliff:g> ક્યાં સાચવવી તે પસંદ કરો"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"તમારી માહિતી સાચવવા માટે પાસવર્ડ મેનેજર પસંદ કરો અને આગલી વખતે વધુ ઝડપથી સાઇન ઇન કરો"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g>માં સાઇન ઇન કરવા માટે પાસકી બનાવીએ?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g>માં સાઇન ઇન કરવા માટે પાસવર્ડ સાચવીએ?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> માટે સાઇન-ઇન કરવાની માહિતી સાચવીએ?"</string>
     <string name="passkey" msgid="632353688396759522">"પાસકી"</string>
     <string name="password" msgid="6738570945182936667">"પાસવર્ડ"</string>
     <string name="passkeys" msgid="5733880786866559847">"પાસકી"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"છોડી દો"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> માટે શું તમારી સાચવેલી પાસકીનો ઉપયોગ કરીએ?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"શું <xliff:g id="APP_NAME">%1$s</xliff:g> માટે તમારા સાચવેલા પાસવર્ડનો ઉપયોગ કરીએ?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="USERNAME">%2$s</xliff:g> વડે <xliff:g id="APP_NAME">%1$s</xliff:g>માં સાઇન ઇન કરવા માટે તમારા સ્ક્રીન લૉકનો ઉપયોગ કરો"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"શું <xliff:g id="APP_NAME">%1$s</xliff:g>માં સાઇન ઇન કરવા માટે તમારી આ લૉગ ઇન વિગતોનો ઉપયોગ કરીએ?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> માટે સાઇન ઇન વિકલ્પો અનલૉક કરીએ?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> માટે કોઈ સાચવેલી પાસકી પસંદ કરો"</string>
diff --git a/packages/CredentialManager/res/values-hi/strings.xml b/packages/CredentialManager/res/values-hi/strings.xml
index 0e9e106..9bc5feb 100644
--- a/packages/CredentialManager/res/values-hi/strings.xml
+++ b/packages/CredentialManager/res/values-hi/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"आने वाले समय में बिना पासवर्ड वाली टेक्नोलॉजी यानी पासकी का इस्तेमाल बढ़ेगा, हालांकि इसके साथ-साथ पासवर्ड भी इस्तेमाल किए जा सकेंगे."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"चुनें कि अपनी <xliff:g id="CREATETYPES">%1$s</xliff:g> कहां सेव करनी हैं"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"अपनी जानकारी सेव करने के लिए, पासवर्ड मैनेजर चुनें और अगली बार ज़्यादा तेज़ी से साइन इन करें"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"क्या आपको <xliff:g id="APP_NAME">%1$s</xliff:g> में साइन इन करने के लिए पासकी बनानी है?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"क्या आपको <xliff:g id="APP_NAME">%1$s</xliff:g> में साइन इन करने के लिए पासवर्ड सेव करना है?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"क्या आपको <xliff:g id="APP_NAME">%1$s</xliff:g> के लिए साइन-इन की जानकारी सेव करनी है?"</string>
     <string name="passkey" msgid="632353688396759522">"पासकी"</string>
     <string name="password" msgid="6738570945182936667">"पासवर्ड"</string>
     <string name="passkeys" msgid="5733880786866559847">"पासकी"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"खारिज करें"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"क्या आपको <xliff:g id="APP_NAME">%1$s</xliff:g> पर साइन इन करने के लिए, सेव की गई पासकी का इस्तेमाल करना है?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"क्या आपको <xliff:g id="APP_NAME">%1$s</xliff:g> के लिए सेव किया हुआ पासवर्ड इस्तेमाल करना है?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="USERNAME">%2$s</xliff:g> से <xliff:g id="APP_NAME">%1$s</xliff:g> में साइन इन करने के लिए, स्क्रीन लॉक का इस्तेमाल करें"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"क्या आपको <xliff:g id="APP_NAME">%1$s</xliff:g> के लिए अपने साइन-इन क्रेडेंशियल का इस्तेमाल करना है?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"क्या आपको <xliff:g id="APP_NAME">%1$s</xliff:g> में साइन इन करने के विकल्पों को अनलॉक करना है?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> के लिए सेव की गई पासकी चुनें"</string>
diff --git a/packages/CredentialManager/res/values-hr/strings.xml b/packages/CredentialManager/res/values-hr/strings.xml
index 61a16b7..968a747 100644
--- a/packages/CredentialManager/res/values-hr/strings.xml
+++ b/packages/CredentialManager/res/values-hr/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Kako idemo u smjeru budućnosti bez zaporki, one će i dalje biti dostupne uz pristupne ključeve."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Odaberite gdje će se spremati <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Odaberite upravitelja zaporki kako biste spremili svoje informacije i drugi se put brže prijavili"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Želite li izraditi pristupni ključ za prijavu u aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Želite li spremiti zaporku za prijavu u aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Želite li spremiti informacije o prijavi za <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"pristupni ključ"</string>
     <string name="password" msgid="6738570945182936667">"zaporka"</string>
     <string name="passkeys" msgid="5733880786866559847">"pristupni ključevi"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Odbaci"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Želite li upotrijebiti spremljeni pristupni ključ za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Želite li upotrijebiti spremljenu zaporku za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Upotrijebite zaključavanje zaslona da biste se prijavili u aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> korisničkim imenom <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Želite li upotrijebiti prijavu za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Želite li otključati opcije za prijavu za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Odaberite spremljeni pristupni ključ za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-hu/strings.xml b/packages/CredentialManager/res/values-hu/strings.xml
index f9c5861..e601da6 100644
--- a/packages/CredentialManager/res/values-hu/strings.xml
+++ b/packages/CredentialManager/res/values-hu/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Miközben a jelszó nélküli jövő felé haladunk, a jelszavak továbbra is rendelkezésre állnak majd az azonosítókulcsok mellett."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Válassza ki, hogy hova szeretné menteni <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Válasszon jelszókezelőt, hogy menthesse az adatait, és gyorsabban jelentkezhessen be a következő alkalommal."</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Létrehoz azonosítókulcsot a következőbe való bejelentkezéshez: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Menti a jelszót a következőbe való bejelentkezéshez: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Menti a bejelentkezési adatokat a következőhöz: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"azonosítókulcs"</string>
     <string name="password" msgid="6738570945182936667">"jelszó"</string>
     <string name="passkeys" msgid="5733880786866559847">"azonosítókulcsait"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Elvetés"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Szeretné a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazáshoz mentett azonosítókulcsot használni?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Szeretné az elmentett jelszavát használni a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazáshoz?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"A képernyőzár használata a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazásba való bejelentkezéshez a következő felhasználónévvel: <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Szeretné használni bejelentkezési adatait a következőhöz: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Feloldja a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> bejelentkezési lehetőségeit?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Mentett azonosítókulcs kiválasztása a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazáshoz"</string>
diff --git a/packages/CredentialManager/res/values-hy/strings.xml b/packages/CredentialManager/res/values-hy/strings.xml
index 2159840..79a2624 100644
--- a/packages/CredentialManager/res/values-hy/strings.xml
+++ b/packages/CredentialManager/res/values-hy/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Թեև մենք առանց գաղտնաբառերի ապագայի ճանապարհին ենք, դրանք դեռ հասանելի կլինեն անցաբառերի հետ մեկտեղ։"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Նշեք, թե որտեղ եք ուզում պահել ձեր <xliff:g id="CREATETYPES">%1$s</xliff:g>ը"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Ընտրեք գաղտնաբառերի կառավարիչ՝ ձեր տեղեկությունները պահելու և հաջորդ անգամ ավելի արագ մուտք գործելու համար"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Ստեղծե՞լ անցաբառ՝ <xliff:g id="APP_NAME">%1$s</xliff:g> հավելված մուտք գործելու համար"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Պահե՞լ գաղտնաբառը՝ <xliff:g id="APP_NAME">%1$s</xliff:g> հավելված մուտք գործելու համար"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Պահե՞լ «<xliff:g id="APP_NAME">%1$s</xliff:g>» հավելվածի մուտքի տվյալները"</string>
     <string name="passkey" msgid="632353688396759522">"անցաբառ"</string>
     <string name="password" msgid="6738570945182936667">"գաղտնաբառ"</string>
     <string name="passkeys" msgid="5733880786866559847">"անցաբառեր"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Փակել"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Օգտագործե՞լ պահված անցաբառը <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի համար"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Օգտագործե՞լ <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի համար պահված ձեր գաղտնաբառը"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Օգտագործեք ձեր էկրանի կողպումը՝ <xliff:g id="USERNAME">%2$s</xliff:g> հաշվի միջոցով <xliff:g id="APP_NAME">%1$s</xliff:g> հավելված մուտք գործելու համար"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Օգտագործե՞լ այս տվյալները <xliff:g id="APP_NAME">%1$s</xliff:g> հավելված մուտք գործելու համար"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Ապակողպե՞լ մուտքի տարբերակներ <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի համար"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Ընտրեք պահված անցաբառ <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածի համար"</string>
diff --git a/packages/CredentialManager/res/values-in/strings.xml b/packages/CredentialManager/res/values-in/strings.xml
index 77b2e43..e7556b0 100644
--- a/packages/CredentialManager/res/values-in/strings.xml
+++ b/packages/CredentialManager/res/values-in/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Sandi akan tetap tersedia bersama kunci sandi seiring perjalanan menuju era di mana sandi tidak diperlukan lagi."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Pilih tempat penyimpanan <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Pilih pengelola sandi untuk menyimpan info Anda dan login lebih cepat lain kali"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Buat kunci sandi untuk login ke <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Simpan sandi untuk login ke <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Simpan info login untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"kunci sandi"</string>
     <string name="password" msgid="6738570945182936667">"sandi"</string>
     <string name="passkeys" msgid="5733880786866559847">"kunci sandi"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Tutup"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Gunakan kunci sandi tersimpan untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Gunakan sandi tersimpan untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Gunakan kunci layar untuk login ke <xliff:g id="APP_NAME">%1$s</xliff:g> dengan <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Gunakan login Anda untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Autentikasi opsi login untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Pilih kunci sandi tersimpan untuk <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-is/strings.xml b/packages/CredentialManager/res/values-is/strings.xml
index fd8c7fd..970a2e6 100644
--- a/packages/CredentialManager/res/values-is/strings.xml
+++ b/packages/CredentialManager/res/values-is/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Við stefnum að framtíð án aðgangsorða en aðgangsorð verða áfram í boði samhliða aðgangslyklum."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Veldu hvar þú vilt vista <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Veldu aðgangsorðastjórnun til að vista upplýsingarnar og vera fljótari að skrá þig inn næst"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Búa til aðgangslykil til að skrá þig inn á <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Vista aðgangsorð til að skrá þig inn á <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Viltu vista innskráningarupplýsingar fyrir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"aðgangslykill"</string>
     <string name="password" msgid="6738570945182936667">"aðgangsorð"</string>
     <string name="passkeys" msgid="5733880786866559847">"aðgangslykla"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Hunsa"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Nota vistaðan aðgangslykil fyrir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Nota vistaða aðgangsorðið þitt fyrir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Notaðu skjálásinn þinn til að skrá þig inn á <xliff:g id="APP_NAME">%1$s</xliff:g> með <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Nota innskráningu fyrir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Opna fyrir innskráningarvalkosti fyrir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Veldu vistaðan aðgangslykil fyrir <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-it/strings.xml b/packages/CredentialManager/res/values-it/strings.xml
index 515e860..a04a840 100644
--- a/packages/CredentialManager/res/values-it/strings.xml
+++ b/packages/CredentialManager/res/values-it/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Il futuro sarà senza password, ma per ora saranno ancora disponibili insieme alle passkey."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Scegli dove salvare le <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Seleziona un gestore delle password per salvare i tuoi dati e accedere più velocemente la prossima volta"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Creare passkey per accedere all\'app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Salvare password per accedere all\'app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Vuoi salvare i dati di accesso di <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"passkey"</string>
     <string name="password" msgid="6738570945182936667">"password"</string>
     <string name="passkeys" msgid="5733880786866559847">"passkey"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Chiudi"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Vuoi usare la passkey salvata per <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Vuoi usare la password salvata per <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Usa il blocco schermo per accedere a <xliff:g id="APP_NAME">%1$s</xliff:g> con <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Vuoi usare il tuo accesso per <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Vuoi sbloccare le opzioni di accesso per <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Scegli una passkey salvata per <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-iw/strings.xml b/packages/CredentialManager/res/values-iw/strings.xml
index 8016afc..87dee5f 100644
--- a/packages/CredentialManager/res/values-iw/strings.xml
+++ b/packages/CredentialManager/res/values-iw/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"אנחנו מתקדמים לעבר עתיד ללא סיסמאות, אבל עדיין אפשר יהיה להשתמש בסיסמאות וגם במפתחות גישה."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"בחירת המקום לשמירה של <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"אפשר לבחור באחד משירותי ניהול הסיסמאות כדי לשמור את הפרטים ולהיכנס לחשבון מהר יותר בפעם הבאה"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"ליצור מפתח גישה כדי להיכנס לחשבון ב-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"לשמור את הסיסמה כדי להיכנס לחשבון ב-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"לשמור את פרטי הכניסה של <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"מפתח גישה"</string>
     <string name="password" msgid="6738570945182936667">"סיסמה"</string>
     <string name="passkeys" msgid="5733880786866559847">"מפתחות גישה"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"סגירה"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"להשתמש במפתח גישה שנשמר עבור <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"להשתמש בסיסמה השמורה של <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"שימוש בשיטה לביטול נעילת המסך כדי להיכנס לחשבון של <xliff:g id="USERNAME">%2$s</xliff:g> ב-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"להשתמש בחשבון שלך כדי להיכנס אל <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"לבטל את הנעילה של אפשרויות הכניסה אל <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"בחירת מפתח גישה שמור ל-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-ja/strings.xml b/packages/CredentialManager/res/values-ja/strings.xml
index 72dc156..71746dc 100644
--- a/packages/CredentialManager/res/values-ja/strings.xml
+++ b/packages/CredentialManager/res/values-ja/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"将来的にパスワードレスに移行するにあたり、パスワードもパスキーと並行して引き続きご利用いただけます。"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g>の保存先を選択"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"パスワード マネージャーを選択して情報を保存しておくと、次回からすばやくログインできます"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> にログインするためにパスキーを作成しますか?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> にログインするためにパスワードを保存しますか?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> のログイン情報を保存しますか?"</string>
     <string name="passkey" msgid="632353688396759522">"パスキー"</string>
     <string name="password" msgid="6738570945182936667">"パスワード"</string>
     <string name="passkeys" msgid="5733880786866559847">"パスキー"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"閉じる"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> の保存したパスキーを使用しますか?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> の保存したパスワードを使用しますか?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"画面ロックを使用して <xliff:g id="USERNAME">%2$s</xliff:g> で <xliff:g id="APP_NAME">%1$s</xliff:g> にログインできます"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"この認証情報を使用して <xliff:g id="APP_NAME">%1$s</xliff:g> にログインしますか?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> がログイン方法を使用できるようにしますか?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> に使用するパスキーを選択してください"</string>
diff --git a/packages/CredentialManager/res/values-ka/strings.xml b/packages/CredentialManager/res/values-ka/strings.xml
index 0ba8d2d..51f1332 100644
--- a/packages/CredentialManager/res/values-ka/strings.xml
+++ b/packages/CredentialManager/res/values-ka/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"უპაროლო მომავალში პაროლები კვლავ ხელმისაწვდომი იქნება, წვდომის გასაღებებთან ერთად."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"აირჩიეთ სად შეინახოთ თქვენი <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"აირჩიეთ პაროლების მმართველი თქვენი ინფორმაციის შესანახად, რომ მომავალში უფრო სწრაფად შეხვიდეთ."</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"შესასვლელად წვდომის გასაღების შექმნა: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"შესასვლელი პაროლის შენახვა: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"აპში შესვლის ინფორმაციის შენახვა: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="passkey" msgid="632353688396759522">"წვდომის გასაღები"</string>
     <string name="password" msgid="6738570945182936667">"პაროლი"</string>
     <string name="passkeys" msgid="5733880786866559847">"წვდომის გასაღები"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"დახურვა"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"გსურთ თქვენი დამახსოვრებული წვდომის გასაღების გამოყენება აპისთვის: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"გამოიყენებთ შენახულ პაროლს <xliff:g id="APP_NAME">%1$s</xliff:g>-სთვის?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"გამოიყენეთ თქვენი ეკრანის დაბლოკვის ფუნქცია <xliff:g id="APP_NAME">%1$s</xliff:g>-ში <xliff:g id="USERNAME">%2$s</xliff:g>-ით შესასვლელად"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"გსურთ შესვლის <xliff:g id="APP_NAME">%1$s</xliff:g>-ისთვის გამოყენება?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"გსურთ შესვლის ვარიანტების განბლოკვა <xliff:g id="APP_NAME">%1$s</xliff:g>-სთვის?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"აირჩიეთ შენახული წვდომის გასაღები <xliff:g id="APP_NAME">%1$s</xliff:g>-სთვის"</string>
diff --git a/packages/CredentialManager/res/values-kk/strings.xml b/packages/CredentialManager/res/values-kk/strings.xml
index e45d34c..7393ca0 100644
--- a/packages/CredentialManager/res/values-kk/strings.xml
+++ b/packages/CredentialManager/res/values-kk/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Құпия сөзсіз болашақ жақын болғанына қарамастан, келешекте құпия сөздерді кіру кілттерімен қатар қолдана беруге болады."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> қайда сақталатынын таңдаңыз"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Мәліметіңізді сақтап, келесіде жылдам кіру үшін құпия сөз менеджерін таңдаңыз."</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасына кіру үшін кіру кілті жасалсын ба?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасына кіру үшін құпия сөз сақталсын ба?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін кіру мәліметін сақтау керек пе?"</string>
     <string name="passkey" msgid="632353688396759522">"Кіру кілті"</string>
     <string name="password" msgid="6738570945182936667">"құпия сөз"</string>
     <string name="passkeys" msgid="5733880786866559847">"кіру кілттері"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Жабу"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін сақталған кіру кілті пайдаланылсын ба?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін сақталған құпия сөзіңізді пайдаланасыз ба?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасына <xliff:g id="USERNAME">%2$s</xliff:g> аккаунтымен кіру үшін экран құлпын қолданыңыз."</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасына кіру деректерін пайдаланасыз ба?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін кіру опциялары ашылсын ба?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін сақталған кіру кілтін таңдаңыз"</string>
diff --git a/packages/CredentialManager/res/values-km/strings.xml b/packages/CredentialManager/res/values-km/strings.xml
index b004c56..ac0d427 100644
--- a/packages/CredentialManager/res/values-km/strings.xml
+++ b/packages/CredentialManager/res/values-km/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"នៅពេលដែលយើងឈានទៅរកអនាគតដែលគ្មានពាក្យសម្ងាត់ ពាក្យសម្ងាត់នៅតែអាចប្រើបានរួមជាមួយកូដសម្ងាត់។"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"ជ្រើសរើសកន្លែង​ដែលត្រូវរក្សាទុក<xliff:g id="CREATETYPES">%1$s</xliff:g>របស់អ្នក"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"ជ្រើសរើស​កម្មវិធីគ្រប់គ្រងពាក្យសម្ងាត់ ដើម្បីរក្សាទុក​ព័ត៌មានរបស់អ្នក និងចូលគណនី​បានកាន់តែរហ័ស​នៅពេលលើកក្រោយ"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"បង្កើតកូដសម្ងាត់ ដើម្បីចូលគណនី <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"រក្សាទុកពាក្យសម្ងាត់ ដើម្បីចូលគណនី <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"រក្សាទុក​ព័ត៌មានចូលគណនីសម្រាប់ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string>
     <string name="passkey" msgid="632353688396759522">"កូដសម្ងាត់"</string>
     <string name="password" msgid="6738570945182936667">"ពាក្យសម្ងាត់"</string>
     <string name="passkeys" msgid="5733880786866559847">"កូដសម្ងាត់"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"ច្រានចោល"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"ប្រើកូដសម្ងាត់ដែលបានរក្សាទុករបស់អ្នកសម្រាប់ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"ប្រើពាក្យសម្ងាត់​ដែលអ្នកបាន​រក្សាទុកសម្រាប់ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"ប្រើមុខងារចាក់សោអេក្រង់របស់អ្នក ដើម្បីចូល <xliff:g id="APP_NAME">%1$s</xliff:g> ដោយប្រើ <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"ប្រើការចូលគណនីរបស់អ្នកសម្រាប់ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"ដោះ​សោជម្រើសចូល​គណនីសម្រាប់ <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"ជ្រើសរើសកូដសម្ងាត់ដែលបានរក្សាទុកសម្រាប់ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-kn/strings.xml b/packages/CredentialManager/res/values-kn/strings.xml
index b6f5340..031fa65 100644
--- a/packages/CredentialManager/res/values-kn/strings.xml
+++ b/packages/CredentialManager/res/values-kn/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"ನಾವು ಪಾಸ್‌ವರ್ಡ್ ರಹಿತ ತಂತ್ರಜ್ಞಾನದ ಕಡೆಗೆ ಸಾಗುತ್ತಿರುವಾಗ, ಪಾಸ್‌ಕೀಗಳ ಜೊತೆಗೆ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು ಇನ್ನೂ ಲಭ್ಯವಿರುತ್ತವೆ."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"ನಿಮ್ಮ <xliff:g id="CREATETYPES">%1$s</xliff:g> ಎಲ್ಲಿ ಸೇವ್‌ ಆಗಬೇಕು ಎಂಬುದನ್ನು ಆರಿಸಿ"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"ನಿಮ್ಮ ಮಾಹಿತಿಯನ್ನು ಉಳಿಸಲು ಪಾಸ್‌ವರ್ಡ್ ನಿರ್ವಾಹಕವನ್ನು ಆಯ್ಕೆಮಾಡಿ ಹಾಗೂ ಮುಂದಿನ ಬಾರಿ ವೇಗವಾಗಿ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಲು ಪಾಸ್‌ಕೀ ಯನ್ನು ರಚಿಸಬೇಕೇ?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಲು ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ಸೇವ್ ಮಾಡಬೇಕೇ?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗಾಗಿ ಸೈನ್-ಇನ್ ಮಾಹಿತಿಯನ್ನು ಸೇವ್ ಮಾಡಬೇಕೇ?"</string>
     <string name="passkey" msgid="632353688396759522">"ಪಾಸ್‌ಕೀ"</string>
     <string name="password" msgid="6738570945182936667">"ಪಾಸ್‌ವರ್ಡ್"</string>
     <string name="passkeys" msgid="5733880786866559847">"ಪಾಸ್‌ಕೀಗಳು"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"ವಜಾಗೊಳಿಸಿ"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗಾಗಿ ಉಳಿಸಲಾದ ನಿಮ್ಮ ಪಾಸ್‌ಕೀ ಅನ್ನು ಬಳಸಬೇಕೆ?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗಾಗಿ ನಿಮ್ಮ ಉಳಿಸಲಾದ ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ಬಳಸಬೇಕೇ?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗೆ <xliff:g id="USERNAME">%2$s</xliff:g> ಮೂಲಕ ಸೈನ್ ಇನ್ ಮಾಡಲು ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ಬಳಸಿ"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗಾಗಿ ನಿಮ್ಮ ಸೈನ್ ಇನ್ ಅನ್ನು ಬಳಸಬೇಕೇ?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗಾಗಿ ಸೈನ್-ಇನ್ ಆಯ್ಕೆಗಳನ್ನು ಅನ್‌ಲಾಕ್ ಮಾಡಬೇಕೇ?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗಾಗಿ ಉಳಿಸಲಾದ ಪಾಸ್‌ಕೀ ಅನ್ನು ಆರಿಸಿ"</string>
diff --git a/packages/CredentialManager/res/values-ko/strings.xml b/packages/CredentialManager/res/values-ko/strings.xml
index 8e2c333..e29ae68 100644
--- a/packages/CredentialManager/res/values-ko/strings.xml
+++ b/packages/CredentialManager/res/values-ko/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"비밀번호 없는 미래로 나아가는 과정에서 비밀번호는 여전히 패스키와 함께 사용될 것입니다."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> 저장 위치 선택"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"정보를 저장해서 다음에 더 빠르게 로그인하려면 비밀번호 관리자를 선택하세요."</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"패스키를 생성하여 <xliff:g id="APP_NAME">%1$s</xliff:g>에 로그인하시겠습니까?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"비밀번호를 저장하여 <xliff:g id="APP_NAME">%1$s</xliff:g>에 로그인하시겠습니까?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g>의 로그인 정보를 저장하시겠습니까?"</string>
     <string name="passkey" msgid="632353688396759522">"패스키"</string>
     <string name="password" msgid="6738570945182936667">"비밀번호"</string>
     <string name="passkeys" msgid="5733880786866559847">"패스키"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"닫기"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱용으로 저장된 패스키를 사용하시겠습니까?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"저장된 비밀번호를 <xliff:g id="APP_NAME">%1$s</xliff:g>에 사용할까요?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"화면 잠금을 사용하여 <xliff:g id="USERNAME">%2$s</xliff:g> 계정으로 <xliff:g id="APP_NAME">%1$s</xliff:g>에 로그인합니다."</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g>에 로그인을 사용하시겠습니까?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g>에 대해 로그인 옵션을 잠금 해제하시겠습니까?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g>에 대해 저장된 패스키 선택"</string>
diff --git a/packages/CredentialManager/res/values-ky/strings.xml b/packages/CredentialManager/res/values-ky/strings.xml
index d65e5d2..5e48ae5 100644
--- a/packages/CredentialManager/res/values-ky/strings.xml
+++ b/packages/CredentialManager/res/values-ky/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Сырсөзсүз келечекти көздөй баратсак да, аларды киргизүүчү ачкычтар менен бирге колдоно берүүгө болот."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> кайда сакталарын тандаңыз"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Маалыматыңызды сактоо жана кийинки жолу тезирээк кирүү үчүн сырсөздөрдү башкаргычты тандаңыз"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосуна кирүү үчүн киргизүүчү ачкычты түзөсүзбү?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосуна кирүү үчүн сырсөздү сактайсызбы?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> үчүн кирүү маалыматы сакталсынбы?"</string>
     <string name="passkey" msgid="632353688396759522">"киргизүүчү ачкыч"</string>
     <string name="password" msgid="6738570945182936667">"сырсөз"</string>
     <string name="passkeys" msgid="5733880786866559847">"киргизүүчү ачкычтар"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Жабуу"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосуна кирүү үчүн сакталган ачкычты колдоносузбу?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> үчүн сакталган сырсөздү колдоносузбу?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосуна <xliff:g id="USERNAME">%2$s</xliff:g> аккаунту менен кирүү үчүн экрандын кулпусун колдонуңуз"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосуна төмөнкү аккаунт менен киресизби?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> үчүн кирүү параметрлеринин кулпусу ачылсынбы?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> үчүн сакталган киргизүүчү ачкычты тандаңыз"</string>
diff --git a/packages/CredentialManager/res/values-lo/strings.xml b/packages/CredentialManager/res/values-lo/strings.xml
index 594bac3..c3733a3 100644
--- a/packages/CredentialManager/res/values-lo/strings.xml
+++ b/packages/CredentialManager/res/values-lo/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"ໃນຂະນະທີ່ພວກເຮົາກ້າວໄປສູ່ອະນາຄົດທີ່ບໍ່ຕ້ອງໃຊ້ລະຫັດຜ່ານ, ລະຫັດຜ່ານຈະຍັງຄົງໃຊ້ໄດ້ຄວບຄູ່ໄປກັບກະແຈຜ່ານ."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"ເລືອກບ່ອນທີ່ຈະບັນທຶກ <xliff:g id="CREATETYPES">%1$s</xliff:g> ຂອງທ່ານ"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"ເລືອກຕົວຈັດການລະຫັດຜ່ານເພື່ອບັນທຶກຂໍ້ມູນຂອງທ່ານ ແລະ ເຂົ້າສູ່ລະບົບໄວຂຶ້ນໃນເທື່ອຕໍ່ໄປ"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"ສ້າງກະແຈຜ່ານເພື່ອເຂົ້າສູ່ລະບົບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"ບັນທຶກລະຫັດຜ່ານເພື່ອເຂົ້າສູ່ລະບົບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"ບັນທຶກຂໍ້ມູນການເຂົ້າສູ່ລະບົບສຳລັບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string>
     <string name="passkey" msgid="632353688396759522">"ກະແຈຜ່ານ"</string>
     <string name="password" msgid="6738570945182936667">"ລະຫັດຜ່ານ"</string>
     <string name="passkeys" msgid="5733880786866559847">"ກະແຈຜ່ານ"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"ປິດໄວ້"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"ໃຊ້ກະແຈຜ່ານທີ່ບັນທຶກໄວ້ຂອງທ່ານສຳລັບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"ໃຊ້ລະຫັດຜ່ານທີ່ບັນທຶກໄວ້ຂອງທ່ານສຳລັບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"ໃຊ້ການລັອກໜ້າຈໍຂອງທ່ານເພື່ອເຂົ້າສູ່ລະບົບ <xliff:g id="APP_NAME">%1$s</xliff:g> ດ້ວຍ <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"ເລືອກການເຂົ້າສູ່ລະບົບຂອງທ່ານສຳລັບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"ປົດລັອກຕົວເລືອກການເຂົ້າສູ່ລະບົບສຳລັບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"ເລືອກກະແຈຜ່ານທີ່ບັນທຶກໄວ້ສຳລັບ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-lt/strings.xml b/packages/CredentialManager/res/values-lt/strings.xml
index 4d4a259..453a0e0 100644
--- a/packages/CredentialManager/res/values-lt/strings.xml
+++ b/packages/CredentialManager/res/values-lt/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Kol stengiamės padaryti, kad ateityje nereikėtų naudoti slaptažodžių, jie vis dar bus pasiekiami kartu su prieigos raktais."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Pasirinkite, kur išsaugoti „<xliff:g id="CREATETYPES">%1$s</xliff:g>“"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Pasirinkite slaptažodžių tvarkyklę, kurią naudodami galėsite išsaugoti informaciją ir kitą kartą prisijungti greičiau"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Sukurti prieigos raktą, skirtą prisijungti prie „<xliff:g id="APP_NAME">%1$s</xliff:g>“?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Sukurti slaptažodį, skirtą prisijungti prie „<xliff:g id="APP_NAME">%1$s</xliff:g>“?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Išsaugoti prisijungimo prie „<xliff:g id="APP_NAME">%1$s</xliff:g>“ informaciją?"</string>
     <string name="passkey" msgid="632353688396759522">"„passkey“"</string>
     <string name="password" msgid="6738570945182936667">"slaptažodis"</string>
     <string name="passkeys" msgid="5733880786866559847">"prieigos raktas"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Atsisakyti"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Naudoti išsaugotą „passkey“ programai „<xliff:g id="APP_NAME">%1$s</xliff:g>“?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Naudoti išsaugotą slaptažodį programai „<xliff:g id="APP_NAME">%1$s</xliff:g>“?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Naudodami ekrano užraktą prisijunkite prie „<xliff:g id="APP_NAME">%1$s</xliff:g>“ kaip <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Naudoti prisijungimo informaciją programai „<xliff:g id="APP_NAME">%1$s</xliff:g>“?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Atrakinti prisijungimo prie „<xliff:g id="APP_NAME">%1$s</xliff:g>“ parinktis?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Išsaugoto prieigos rakto, skirto „<xliff:g id="APP_NAME">%1$s</xliff:g>“, pasirinkimas"</string>
diff --git a/packages/CredentialManager/res/values-lv/strings.xml b/packages/CredentialManager/res/values-lv/strings.xml
index f76d120..4da1051 100644
--- a/packages/CredentialManager/res/values-lv/strings.xml
+++ b/packages/CredentialManager/res/values-lv/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Lai arī pamazām notiek pāreja uz darbu bez parolēm, tās joprojām būs pieejamas līdzās piekļuves atslēgām."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Izvēlieties, kur saglabāt savas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Lai saglabātu informāciju un nākamreiz varētu pierakstīties ātrāk, atlasiet paroļu pārvaldnieku."</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Vai izveidot piekļuves atslēgu, lai pierakstītos lietotnē <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Vai saglabāt paroli, lai pierakstītos lietotnē <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Vai saglabāt pierakstīšanās informāciju lietotnei <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"piekļuves atslēga"</string>
     <string name="password" msgid="6738570945182936667">"parole"</string>
     <string name="passkeys" msgid="5733880786866559847">"piekļuves atslēgas"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Nerādīt"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Vai izmantot saglabāto piekļuves atslēgu lietotnei <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Vai izmantot jūsu saglabāto paroli lietotnei <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Izmantot ekrāna bloķēšanu, lai lietotnē <xliff:g id="APP_NAME">%1$s</xliff:g> pierakstītos ar kontu <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Vai izmantot jūsu pierakstīšanās informāciju lietotnei <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Vai vēlaties atbloķēt lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> pierakstīšanās opcijas?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Saglabātas piekļuves atslēgas izvēle lietotnei <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-mk/strings.xml b/packages/CredentialManager/res/values-mk/strings.xml
index 428878a..95554a2 100644
--- a/packages/CredentialManager/res/values-mk/strings.xml
+++ b/packages/CredentialManager/res/values-mk/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Како што се движиме кон иднина без лозинки, лозинките сепак ќе бидат достапни покрај криптографските клучеви."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Изберете каде да ги зачувате вашите <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Изберете управник со лозинки за да ги зачувате вашите податоци и да се најавите побрзо следниот пат"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Да се создаде криптографски клуч за најавување на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Да се зачува лозинката за најавување на <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Да се зачуваат податоците за најавување за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"криптографски клуч"</string>
     <string name="password" msgid="6738570945182936667">"лозинка"</string>
     <string name="passkeys" msgid="5733880786866559847">"криптографски клучеви"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Отфрли"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Да се користи вашиот зачуван криптографски клуч за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Да се користат зачуваните лозинки за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Користете го заклучувањето екран за да се најавувате на <xliff:g id="APP_NAME">%1$s</xliff:g> со <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Да се користи вашето најавување за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Да се отклучат опциите за најавување за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Изберете зачуван криптографски клуч за <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-ml/strings.xml b/packages/CredentialManager/res/values-ml/strings.xml
index e686117..eccfb51 100644
--- a/packages/CredentialManager/res/values-ml/strings.xml
+++ b/packages/CredentialManager/res/values-ml/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"നമ്മൾ പാസ്‍വേഡ് രഹിത ഭാവിയിലേക്ക് ചുവടുവെച്ചുകൊണ്ടിരിക്കുകയാണ് എങ്കിലും, പാസ്‌കീകൾക്കൊപ്പം പാസ്‍വേഡുകൾ തുടർന്നും ലഭ്യമായിരിക്കും."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"നിങ്ങളുടെ <xliff:g id="CREATETYPES">%1$s</xliff:g> എവിടെയാണ് സംരക്ഷിക്കേണ്ടതെന്ന് തിരഞ്ഞെടുക്കുക"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"നിങ്ങളുടെ വിവരങ്ങൾ സംരക്ഷിക്കാനും അടുത്ത തവണ വേഗത്തിൽ സൈൻ ഇൻ ചെയ്യാനും ഒരു പാസ്‌വേഡ് മാനേജർ തിരഞ്ഞെടുക്കുക"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിലേക്ക് സൈൻ ഇൻ ചെയ്യാൻ പാസ്‌കീ സൃഷ്ടിക്കണോ?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിലേക്ക് സൈൻ ഇൻ ചെയ്യാൻ പാസ്‌വേഡ് സംരക്ഷിക്കണോ?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിനായി സൈൻ ഇൻ വിവരങ്ങൾ സംരക്ഷിക്കണോ?"</string>
     <string name="passkey" msgid="632353688396759522">"പാസ്‌കീ"</string>
     <string name="password" msgid="6738570945182936667">"പാസ്‌വേഡ്"</string>
     <string name="passkeys" msgid="5733880786866559847">"പാസ്‌കീകൾ"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"ഡിസ്‌മിസ് ചെയ്യുക"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിനായി നിങ്ങൾ സംരക്ഷിച്ച പാസ്‌കീ ഉപയോഗിക്കണോ?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിനായി നിങ്ങളുടെ സംരക്ഷിച്ച പാസ്‌വേഡ് ഉപയോഗിക്കണോ?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="USERNAME">%2$s</xliff:g> എന്നയാളായി <xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിലേക്ക് സൈൻ ഇൻ ചെയ്യാൻ നിങ്ങളുടെ സ്‌ക്രീൻ ലോക്ക് ഉപയോഗിക്കുക"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> ആപ്പിനുള്ള നിങ്ങളുടെ സൈൻ ഇൻ ക്രെഡൻഷ്യലുകൾ ഉപയോഗിക്കണോ?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിനായി സൈൻ ഇൻ ഓപ്‌ഷനുകൾ അൺലോക്ക് ചെയ്യണോ?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിനായി ഒരു സംരക്ഷിച്ച പാസ്‌കീ തിരഞ്ഞെടുക്കുക"</string>
diff --git a/packages/CredentialManager/res/values-mn/strings.xml b/packages/CredentialManager/res/values-mn/strings.xml
index 72cda9f..5b1cbe9 100644
--- a/packages/CredentialManager/res/values-mn/strings.xml
+++ b/packages/CredentialManager/res/values-mn/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Бид нууц үггүй ирээдүй рүү урагшлахын хэрээр нууц үг нь нэвтрэх түлхүүрийн хамтаар боломжтой хэвээр байх болно."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g>-г хаана хадгалахаа сонгоно уу"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Мэдээллээ хадгалж, дараагийн удаа илүү хурдан нэвтрэхийн тулд нууц үгний менежерийг сонгоно уу"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g>-д нэвтрэхийн тулд нэвтрэх түлхүүр үүсгэх үү?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g>-д нэвтрэхийн тулд нууц үгийг хадгалах уу?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g>-н нэвтрэх мэдээллийг хадгалах уу?"</string>
     <string name="passkey" msgid="632353688396759522">"passkey"</string>
     <string name="password" msgid="6738570945182936667">"нууц үг"</string>
     <string name="passkeys" msgid="5733880786866559847">"нэвтрэх түлхүүрүүд"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Хаах"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g>-д өөрийн хадгалсан passkey-г ашиглах уу?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g>-д хадгалсан нууц үгээ ашиглах уу?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="APP_NAME">%1$s</xliff:g>-д <xliff:g id="USERNAME">%2$s</xliff:g>-р нэвтрэхийн тулд дэлгэцийн түгжээгээ ашиглана уу"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g>-н нэвтрэлтээ ашиглах уу?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g>-д нэвтрэлтийн сонголтын түгжээг тайлах уу?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g>-д хадгалсан нэвтрэх түлхүүр сонгоно уу"</string>
diff --git a/packages/CredentialManager/res/values-mr/strings.xml b/packages/CredentialManager/res/values-mr/strings.xml
index 2d72bc0..a0a4a7d 100644
--- a/packages/CredentialManager/res/values-mr/strings.xml
+++ b/packages/CredentialManager/res/values-mr/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"पासवर्ड न वापरणाऱ्या भविष्यात पुढे जाताना, पासवर्ड तरीही पासकीच्या बरोबरीने उपलब्ध असतील."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"तुमची <xliff:g id="CREATETYPES">%1$s</xliff:g> कुठे सेव्ह करायची ते निवडा"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"तुमची माहिती सेव्ह करण्यासाठी आणि पुढच्या वेळी जलद साइन इन करण्याकरिता Password Manager निवडा"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> मध्ये साइन इन करण्यासाठी पासकी तयार करायची आहे का?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> मध्ये साइन इन करण्यासाठी पासवर्ड सेव्ह करायचा आहे का?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> साठी साइन-इनसंबंधित माहिती सेव्ह करायची का?"</string>
     <string name="passkey" msgid="632353688396759522">"पासकी"</string>
     <string name="password" msgid="6738570945182936667">"पासवर्ड"</string>
     <string name="passkeys" msgid="5733880786866559847">"पासकी"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"डिसमिस करा"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> साठी तुमची सेव्ह केलेली पासकी वापरायची का?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"तुमचा सेव्ह केलेला पासवर्ड <xliff:g id="APP_NAME">%1$s</xliff:g> साठी वापरायचा आहे का?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="USERNAME">%2$s</xliff:g> सह <xliff:g id="APP_NAME">%1$s</xliff:g> मध्ये साइन इन करण्यासाठी तुमचे स्क्रीन लॉक वापरा"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> साठी तुमचे साइन-इन वापरायचे आहे का?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> साठी साइन-इन पर्याय अनलॉक करायचे आहेत का?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> साठी सेव्ह केलेली पासकी निवडा"</string>
diff --git a/packages/CredentialManager/res/values-ms/strings.xml b/packages/CredentialManager/res/values-ms/strings.xml
index 2a42b87..c866013 100644
--- a/packages/CredentialManager/res/values-ms/strings.xml
+++ b/packages/CredentialManager/res/values-ms/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Meskipun masa depan kita nanti tidak memerlukan kata laluan, kata laluan masih akan tersedia bersama dengan kunci laluan."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Pilih tempat untuk menyimpan <xliff:g id="CREATETYPES">%1$s</xliff:g> anda"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Pilih Password Manager untuk menyimpan maklumat anda dan log masuk lebih pantas pada kali seterusnya"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Buat kunci laluan untuk log masuk ke <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Simpan kata laluan untuk log masuk ke <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Simpan maklumat log masuk untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"kunci laluan"</string>
     <string name="password" msgid="6738570945182936667">"kata laluan"</string>
     <string name="passkeys" msgid="5733880786866559847">"kunci laluan"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Ketepikan"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Gunakan kunci laluan anda yang telah disimpan untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Gunakan kata laluan anda yang disimpan untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Gunakan kunci skrin anda untuk log masuk ke <xliff:g id="APP_NAME">%1$s</xliff:g> dengan <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Gunakan log masuk anda untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Buka kunci pilihan log masuk untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Pilih kunci laluan yang disimpan untuk <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-my/strings.xml b/packages/CredentialManager/res/values-my/strings.xml
index a40d973..a66e7b6 100644
--- a/packages/CredentialManager/res/values-my/strings.xml
+++ b/packages/CredentialManager/res/values-my/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"စကားဝှက်မသုံးခြင်း အနာဂတ်ဆီသို့ ရှေ့ဆက်ရာတွင် လျှို့ဝှက်ကီးများနှင့်အတူ စကားဝှက်များကို ဆက်လက်အသုံးပြုနိုင်ပါမည်။"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"သင်၏ <xliff:g id="CREATETYPES">%1$s</xliff:g> သိမ်းရန်နေရာ ရွေးခြင်း"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"သင့်အချက်အလက်သိမ်းပြီး နောက်တစ်ကြိမ်၌ ပိုမိုမြန်ဆန်စွာ လက်မှတ်ထိုးဝင်ရန် စကားဝှက်မန်နေဂျာကို ရွေးပါ"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> သို့ လက်မှတ်ထိုးဝင်ရန် လျှို့ဝှက်ကီး ပြုလုပ်မလား။"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> သို့ လက်မှတ်ထိုးဝင်ရန် စကားဝှက်ကို သိမ်းမလား။"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> အတွက် လက်မှတ်ထိုးဝင်ရန် အချက်အလက်ကို သိမ်းမလား။"</string>
     <string name="passkey" msgid="632353688396759522">"လျှို့ဝှက်ကီး"</string>
     <string name="password" msgid="6738570945182936667">"စကားဝှက်"</string>
     <string name="passkeys" msgid="5733880786866559847">"လျှို့ဝှက်ကီးများ"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"ပယ်ရန်"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"သိမ်းထားသောလျှို့ဝှက်ကီးကို <xliff:g id="APP_NAME">%1$s</xliff:g> အတွက် သုံးမလား။"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> အတွက် သိမ်းထားသောစကားဝှက် သုံးမလား။"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="APP_NAME">%1$s</xliff:g> သို့ <xliff:g id="USERNAME">%2$s</xliff:g> ဖြင့် လက်မှတ်ထိုးဝင်ရန် သင့်ဖန်သားပြင်လော့ခ်ကို သုံးနိုင်သည်"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> အတွက် သင့်လက်မှတ်ထိုးဝင်မှုကို သုံးမလား။"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> အတွက် လက်မှတ်ထိုးဝင်မှု ရွေးစရာကို ဖွင့်မလား။"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> အတွက် သိမ်းထားသော လျှို့ဝှက်ကီး ရွေးပါ"</string>
diff --git a/packages/CredentialManager/res/values-nb/strings.xml b/packages/CredentialManager/res/values-nb/strings.xml
index 09157bd..7f4fa6b 100644
--- a/packages/CredentialManager/res/values-nb/strings.xml
+++ b/packages/CredentialManager/res/values-nb/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Vi går mot en fremtid uten passord, men passord fortsetter å være tilgjengelige ved siden av passnøkler."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Velg hvor du vil lagre <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Velg et verktøy for passordlagring for å lagre informasjonen din og logge på raskere neste gang"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Vil du opprette en passnøkkel for å logge på <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Vil du lagre passordet for å logge på <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Vil du lagre påloggingsinformasjon for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"passnøkkel"</string>
     <string name="password" msgid="6738570945182936667">"passord"</string>
     <string name="passkeys" msgid="5733880786866559847">"passnøkler"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Lukk"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Vil du bruke den lagrede tilgangsnøkkelen for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Vil du bruke det lagrede passordet ditt for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Bruk skjermlåsen til å logge på <xliff:g id="APP_NAME">%1$s</xliff:g> med <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Vil du bruke påloggingen for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Vil du låse opp påloggingsalternativene for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Velg en lagret passnøkkel for <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-ne/strings.xml b/packages/CredentialManager/res/values-ne/strings.xml
index 813ecad..6e69476 100644
--- a/packages/CredentialManager/res/values-ne/strings.xml
+++ b/packages/CredentialManager/res/values-ne/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"हामी पासवर्डरहित भविष्यतर्फ बढ्दै गर्दा पासकीका साथसाथै पासवर्ड पनि उपलब्ध हुने छ।"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"तपाईं आफ्ना <xliff:g id="CREATETYPES">%1$s</xliff:g> कहाँ सेभ गर्न चाहनुहुन्छ भन्ने कुरा छनौट गर्नुहोस्"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"कुनै पासवर्ड म्यानेजरमा आफ्नो जानकारी सेभ गरी अर्को पटक अझ छिटो साइन इन गर्नुहोस्"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा साइन इन गर्न पासकी बनाउने हो?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा साइन इन गर्न पासवर्ड सेभ गर्ने हो?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा साइन गर्न प्रयोग गरिने जानकारी सेभ गर्ने हो?"</string>
     <string name="passkey" msgid="632353688396759522">"पासकी"</string>
     <string name="password" msgid="6738570945182936667">"पासवर्ड"</string>
     <string name="passkeys" msgid="5733880786866559847">"पासकीहरू"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"हटाउनुहोस्"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"आफूले सेभ गरेको पासकी प्रयोग गरी <xliff:g id="APP_NAME">%1$s</xliff:g> मा साइन इन गर्ने हो?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा साइन इन गर्न सेभ गरिएको पासवर्ड प्रयोग गर्ने हो?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="USERNAME">%2$s</xliff:g> प्रयोग गरी <xliff:g id="APP_NAME">%1$s</xliff:g> मा साइन इन गर्न आफ्नो स्क्रिन लक प्रयोग गर्नुहोस्"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा साइन इन गर्नका लागि तपाईंका क्रिडेन्सियलहरू प्रयोग गर्ने हो?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> का साइन इनसम्बन्धी विकल्पहरू अनलक गर्ने हो?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> मा साइन इन गर्न सेभ गरिएको पासकी छनौट गर्नुहोस्"</string>
diff --git a/packages/CredentialManager/res/values-nl/strings.xml b/packages/CredentialManager/res/values-nl/strings.xml
index 3e46cc9..50eefc7 100644
--- a/packages/CredentialManager/res/values-nl/strings.xml
+++ b/packages/CredentialManager/res/values-nl/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"We zijn op weg naar een wachtwoordloze toekomst, maar naast toegangssleutels kun je nog steeds gebruikmaken van wachtwoorden."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Kiezen waar je je <xliff:g id="CREATETYPES">%1$s</xliff:g> wilt opslaan"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Selecteer een wachtwoordmanager om je informatie op te slaan en de volgende keer sneller in te loggen"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Toegangssleutel maken om in te loggen bij <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Wachtwoord opslaan om in te loggen bij <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Inloggegevens opslaan voor <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"Toegangssleutel"</string>
     <string name="password" msgid="6738570945182936667">"wachtwoord"</string>
     <string name="passkeys" msgid="5733880786866559847">"toegangssleutels"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Sluiten"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Je opgeslagen toegangssleutel gebruiken voor <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Je opgeslagen wachtwoord voor <xliff:g id="APP_NAME">%1$s</xliff:g> gebruiken?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Gebruik je schermvergrendeling om in te loggen bij <xliff:g id="APP_NAME">%1$s</xliff:g> met <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Je login voor <xliff:g id="APP_NAME">%1$s</xliff:g> gebruiken?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Inlogopties voor <xliff:g id="APP_NAME">%1$s</xliff:g> ontgrendelen?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Opgeslagen toegangssleutel kiezen voor <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-or/strings.xml b/packages/CredentialManager/res/values-or/strings.xml
index 5bf4627..56e585d 100644
--- a/packages/CredentialManager/res/values-or/strings.xml
+++ b/packages/CredentialManager/res/values-or/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"ଆମେ ଏକ ପାସୱାର୍ଡବିହୀନ ଭବିଷ୍ୟତ ଆଡ଼କୁ ମୁଭ କରୁଥିବା ଯୋଗୁଁ ଏବେ ବି ପାସକୀଗୁଡ଼ିକ ସହିତ ପାସୱାର୍ଡ ଉପଲବ୍ଧ ହେବ।"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"ଆପଣଙ୍କ <xliff:g id="CREATETYPES">%1$s</xliff:g> କେଉଁଠାରେ ସେଭ କରିବେ ତାହା ବାଛନ୍ତୁ"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"ଆପଣଙ୍କ ସୂଚନା ସେଭ କରି ପରବର୍ତ୍ତୀ ସମୟରେ ଶୀଘ୍ର ସାଇନ ଇନ କରିବା ପାଇଁ ଏକ Password Manager ଚୟନ କରନ୍ତୁ"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g>ରେ ସାଇନ ଇନ କରିବାକୁ ପାସକୀ ତିଆରି କରିବେ?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g>ରେ ସାଇନ ଇନ କରିବାକୁ ପାସୱାର୍ଡ ସେଭ କରିବେ?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ସାଇନ-ଇନର ସୂଚନା ସେଭ କରିବେ?"</string>
     <string name="passkey" msgid="632353688396759522">"ପାସକୀ"</string>
     <string name="password" msgid="6738570945182936667">"ପାସୱାର୍ଡ"</string>
     <string name="passkeys" msgid="5733880786866559847">"ପାସକୀଗୁଡ଼ିକ"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"ଖାରଜ କରନ୍ତୁ"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ସେଭ କରାଯାଇଥିବା ଆପଣଙ୍କ ପାସକୀ ବ୍ୟବହାର କରିବେ?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ଆପଣଙ୍କ ସେଭ କରାଯାଇଥିବା ପାସୱାର୍ଡକୁ ବ୍ୟବହାର କରିବେ?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="USERNAME">%2$s</xliff:g> ମାଧ୍ୟମରେ <xliff:g id="APP_NAME">%1$s</xliff:g>ରେ ସାଇନ ଇନ କରିବା ପାଇଁ ଆପଣଙ୍କ ସ୍କ୍ରିନ ଲକ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ଆପଣଙ୍କ ସାଇନ-ଇନ ବ୍ୟବହାର କରିବେ?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ସାଇନ-ଇନ ବିକଳ୍ପଗୁଡ଼ିକୁ ଅନଲକ କରିବେ?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ସେଭ କରାଯାଇଥିବା ଏକ ପାସକୀ ବାଛନ୍ତୁ"</string>
diff --git a/packages/CredentialManager/res/values-pa/strings.xml b/packages/CredentialManager/res/values-pa/strings.xml
index aba05c4..d23d209 100644
--- a/packages/CredentialManager/res/values-pa/strings.xml
+++ b/packages/CredentialManager/res/values-pa/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"ਹਾਲਾਂਕਿ, ਅਸੀਂ ਪਾਸਵਰਡ ਰਹਿਤ ਭਵਿੱਖ ਵੱਲ ਵਧ ਰਹੇ ਹਾਂ, ਪਰ ਪਾਸਕੀਆਂ ਦੇ ਨਾਲ ਪਾਸਵਰਡ ਹਾਲੇ ਵੀ ਉਪਲਬਧ ਹੋਣਗੇ।"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"ਚੁਣੋ ਕਿ ਆਪਣੀਆਂ <xliff:g id="CREATETYPES">%1$s</xliff:g> ਨੂੰ ਕਿੱਥੇ ਰੱਖਿਅਤ ਕਰਨਾ ਹੈ"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"ਆਪਣੀ ਜਾਣਕਾਰੀ ਨੂੰ ਰੱਖਿਅਤ ਕਰਨ ਅਤੇ ਅਗਲੀ ਵਾਰ ਤੇਜ਼ੀ ਨਾਲ ਸਾਈਨ-ਇਨ ਕਰਨ ਲਈ ਪਾਸਵਰਡ ਪ੍ਰਬੰਧਕ ਚੁਣੋ"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਵਿੱਚ ਸਾਈਨ-ਇਨ ਕਰਨ ਲਈ ਪਾਸਕੀ ਬਣਾਉਣੀ ਹੈ?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਵਿੱਚ ਸਾਈਨ-ਇਨ ਕਰਨ ਲਈ ਪਾਸਵਰਡ ਰੱਖਿਅਤ ਕਰਨਾ ਹੈ?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਲਈ ਸਾਈਨ-ਇਨ ਜਾਣਕਾਰੀ ਰੱਖਿਅਤ ਕਰਨੀ ਹੈ?"</string>
     <string name="passkey" msgid="632353688396759522">"ਪਾਸਕੀ"</string>
     <string name="password" msgid="6738570945182936667">"ਪਾਸਵਰਡ"</string>
     <string name="passkeys" msgid="5733880786866559847">"ਪਾਸਕੀਆਂ"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"ਖਾਰਜ ਕਰੋ"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਲਈ ਆਪਣੀ ਰੱਖਿਅਤ ਕੀਤੀ ਪਾਸਕੀ ਦੀ ਵਰਤੋਂ ਕਰਨੀ ਹੈ?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਲਈ ਤੁਹਾਡਾ ਰੱਖਿਅਤ ਕੀਤਾ ਪਾਸਵਰਡ ਵਰਤਣਾ ਹੈ?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="USERNAME">%2$s</xliff:g> ਨਾਲ <xliff:g id="APP_NAME">%1$s</xliff:g> ਵਿੱਚ ਸਾਈਨ-ਇਨ ਕਰਨ ਲਈ ਆਪਣੇ ਸਕ੍ਰੀਨ ਲਾਕ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਲਈ ਆਪਣਾ ਸਾਈਨ-ਇਨ ਕਰਨ ਦਾ ਵਿਕਲਪ ਵਰਤਣਾ ਹੈ?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਲਈ ਸਾਈਨ-ਇਨ ਵਿਕਲਪਾਂ ਨੂੰ ਅਣਲਾਕ ਕਰਨਾ ਹੈ?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਲਈ ਕੋਈ ਰੱਖਿਅਤ ਕੀਤੀ ਪਾਸਕੀ ਚੁਣੋ"</string>
diff --git a/packages/CredentialManager/res/values-pl/strings.xml b/packages/CredentialManager/res/values-pl/strings.xml
index 4a4a9fa..5fa26b4 100644
--- a/packages/CredentialManager/res/values-pl/strings.xml
+++ b/packages/CredentialManager/res/values-pl/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"W czasie przechodzenia na technologie niewymagające haseł możliwość stosowania haseł – niezależnie od kluczy dostępu – wciąż będzie dostępna."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Wybierz, gdzie zapisywać <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Wybierz menedżera haseł, aby zapisywać informacje i logować się szybciej"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Utworzyć klucz dostępu do logowania w aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Zapisać hasło do logowania w aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Zapisać dane używane do logowania w aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"klucz"</string>
     <string name="password" msgid="6738570945182936667">"hasło"</string>
     <string name="passkeys" msgid="5733880786866559847">"klucze dostępu"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Zamknij"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Użyć zapisanego klucza dla aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Użyć zapisanego hasła do aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Używaj metody odblokowywania ekranu, aby logować się do aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g> za pomocą nazwy użytkownika <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Użyć tych danych logowania do aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Odblokować opcje logowania do aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Wybierz zapisany klucz dostępu do aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-pt-rBR/strings.xml b/packages/CredentialManager/res/values-pt-rBR/strings.xml
index f2e84c1..994bc55 100644
--- a/packages/CredentialManager/res/values-pt-rBR/strings.xml
+++ b/packages/CredentialManager/res/values-pt-rBR/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Estamos avançando em direção a um futuro sem senhas, mas elas ainda vão estar disponíveis junto às chaves de acesso."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Escolha onde salvar suas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Selecione um gerenciador de senhas para salvar suas informações e fazer login mais rapidamente na próxima vez"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Criar chave de acesso para fazer login no app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Salvar senha para fazer login no app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Salvar informações de login do app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"chave de acesso"</string>
     <string name="password" msgid="6738570945182936667">"senha"</string>
     <string name="passkeys" msgid="5733880786866559847">"chaves de acesso"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Dispensar"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Usar sua chave de acesso salva para o app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Usar a senha salva para o app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Use o bloqueio de tela para fazer login no app <xliff:g id="APP_NAME">%1$s</xliff:g> com a conta <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Usar seu login para o app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Desbloquear opções de login para o app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Escolha uma chave de acesso salva para o app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-pt-rPT/strings.xml b/packages/CredentialManager/res/values-pt-rPT/strings.xml
index f95927b..26c6491 100644
--- a/packages/CredentialManager/res/values-pt-rPT/strings.xml
+++ b/packages/CredentialManager/res/values-pt-rPT/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"À medida que avançamos para um futuro sem palavras-passe, as palavras-passe continuam disponíveis juntamente com as chaves de acesso."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Escolha onde guardar as suas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Selecione um gestor de palavras-passe para guardar as suas informações e iniciar sessão mais rapidamente da próxima vez"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Criar a chave de acesso para iniciar sessão na app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Guardar a palavra-passe para iniciar sessão na app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Guardar as informações de início de sessão da app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"chave de acesso"</string>
     <string name="password" msgid="6738570945182936667">"palavra-passe"</string>
     <string name="passkeys" msgid="5733880786866559847">"chaves de acesso"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Ignorar"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Usar a sua chave de acesso guardada na app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Usar a sua palavra-passe guardada para a app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Use o seu bloqueio de ecrã para iniciar sessão na app <xliff:g id="APP_NAME">%1$s</xliff:g> com <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Usar o seu início de sessão para a app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Desbloquear as opções de início de sessão para a app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Escolha uma chave de acesso guardada para a app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-pt/strings.xml b/packages/CredentialManager/res/values-pt/strings.xml
index f2e84c1..994bc55 100644
--- a/packages/CredentialManager/res/values-pt/strings.xml
+++ b/packages/CredentialManager/res/values-pt/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Estamos avançando em direção a um futuro sem senhas, mas elas ainda vão estar disponíveis junto às chaves de acesso."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Escolha onde salvar suas <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Selecione um gerenciador de senhas para salvar suas informações e fazer login mais rapidamente na próxima vez"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Criar chave de acesso para fazer login no app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Salvar senha para fazer login no app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Salvar informações de login do app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"chave de acesso"</string>
     <string name="password" msgid="6738570945182936667">"senha"</string>
     <string name="passkeys" msgid="5733880786866559847">"chaves de acesso"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Dispensar"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Usar sua chave de acesso salva para o app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Usar a senha salva para o app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Use o bloqueio de tela para fazer login no app <xliff:g id="APP_NAME">%1$s</xliff:g> com a conta <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Usar seu login para o app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Desbloquear opções de login para o app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Escolha uma chave de acesso salva para o app <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-ro/strings.xml b/packages/CredentialManager/res/values-ro/strings.xml
index c77c3b2..342b6ab 100644
--- a/packages/CredentialManager/res/values-ro/strings.xml
+++ b/packages/CredentialManager/res/values-ro/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Ne îndreptăm spre un viitor fără parole, însă acestea sunt încă disponibile, alături de cheile de acces."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Alege unde dorești să salvezi <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Selectează un manager de parole pentru a salva informațiile și a te conecta mai rapid data viitoare"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Creezi o cheie de acces pentru a te conecta la <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Salvezi parola pentru a te conecta la <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Salvezi informațiile de conectare pentru <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"cheia de acces"</string>
     <string name="password" msgid="6738570945182936667">"parolă"</string>
     <string name="passkeys" msgid="5733880786866559847">"cheile de acces"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Închide"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Folosești cheia de acces salvată pentru <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Folosești parola salvată pentru <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Folosește blocarea ecranului ca să te conectezi la <xliff:g id="APP_NAME">%1$s</xliff:g> cu <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Folosești datele de conectare pentru <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Deblochezi opțiunile de conectare pentru <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Alege o cheie de acces salvată pentru <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-ru/strings.xml b/packages/CredentialManager/res/values-ru/strings.xml
index 001587d..e472695 100644
--- a/packages/CredentialManager/res/values-ru/strings.xml
+++ b/packages/CredentialManager/res/values-ru/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Хотя движение к будущему без паролей уже началось, их по-прежнему можно будет использовать наряду с ключами доступа."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Укажите, куда нужно сохранить <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Выберите менеджер паролей, чтобы сохранять учетные данные и быстро выполнять вход."</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Создать ключ доступа для входа в приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Сохранить пароль для входа в приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Сохранить данные для входа в приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
     <string name="passkey" msgid="632353688396759522">"ключ доступа"</string>
     <string name="password" msgid="6738570945182936667">"пароль"</string>
     <string name="passkeys" msgid="5733880786866559847">"ключи доступа"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Закрыть"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Использовать сохраненный ключ доступа для приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Использовать сохраненный пароль для приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Используйте способ разблокировки экрана для входа в приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" (<xliff:g id="USERNAME">%2$s</xliff:g>)."</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Войти в приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" с этими данными?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Разблокировать варианты входа для приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Выберите сохраненный ключ доступа для приложения \"<xliff:g id="APP_NAME">%1$s</xliff:g>\""</string>
diff --git a/packages/CredentialManager/res/values-si/strings.xml b/packages/CredentialManager/res/values-si/strings.xml
index 612083f..ce0b9cd 100644
--- a/packages/CredentialManager/res/values-si/strings.xml
+++ b/packages/CredentialManager/res/values-si/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"අපි මුරපද රහිත අනාගතයක් කරා ගමන් කරන විට, මුරයතුරු සමග මුරපද තවමත් පවතී."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"ඔබේ <xliff:g id="CREATETYPES">%1$s</xliff:g> සුරැකිය යුතු ස්ථානය තෝරා ගන්න"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"ඔබේ තතු සුරැකීමට සහ මීළඟ වතාවේ වේගයෙන් පුරනය වීමට මුරපද කළමනාකරුවෙකු තෝරන්න"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> වෙත පුරනය වීමට මුරයතුරක් තනන්න ද?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> වෙත පුරනය වීමට මුරපදය සුරකින්න ද?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> සඳහා පුරනය වීමේ තතු සුරකින්න ද?"</string>
     <string name="passkey" msgid="632353688396759522">"මුරයතුර"</string>
     <string name="password" msgid="6738570945182936667">"මුරපදය"</string>
     <string name="passkeys" msgid="5733880786866559847">"මුරයතුරු"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"අස් කරන්න"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> සඳහා ඔබේ සුරැකි මුරයතුර භාවිතා කරන්න ද?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> සඳහා ඔබේ සුරැකි මුරපදය භාවිත කරන්න ද?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="USERNAME">%2$s</xliff:g> සමඟින් <xliff:g id="APP_NAME">%1$s</xliff:g> වෙත පුරනය වීමට ඔබේ තිර අගුල භාවිත කරන්න"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> සඳහා ඔබේ පුරනය වීම භාවිතා කරන්න ද?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> සඳහා පුරන විකල්ප අගුලු හරින්න ද?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> සඳහා සුරකින ලද මුරයතුරක් තෝරන්න"</string>
diff --git a/packages/CredentialManager/res/values-sk/strings.xml b/packages/CredentialManager/res/values-sk/strings.xml
index 67d91c8..62a2e69 100644
--- a/packages/CredentialManager/res/values-sk/strings.xml
+++ b/packages/CredentialManager/res/values-sk/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Blížime sa k budúcnosti bez hesiel, ale heslá budú popri prístupových kľúčoch stále k dispozícii."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Vyberte, kam sa majú ukladať <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Vyberte správcu hesiel, do ktorého sa budú ukladať vaše údaje, aby ste sa nabudúce mohli rýchlejšie prihlásiť"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Chcete vytvoriť prístupový kľúč na prihlasovanie do aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Chcete uložiť heslo na prihlasovanie do aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Chcete uložiť prihlasovacie údaje pre aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"prístupový kľúč"</string>
     <string name="password" msgid="6738570945182936667">"heslo"</string>
     <string name="passkeys" msgid="5733880786866559847">"prístupové kľúče"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Zavrieť"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Chcete pre aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> použiť uložený prístupový kľúč?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Chcete použiť uložené heslo aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Pomocou zámky obrazovky sa prihláste do aplikácie <xliff:g id="APP_NAME">%1$s</xliff:g> používateľským menom <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Chcete použiť svoje prihlásenie pre aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Chcete odomknúť možnosti prihlásenia pre aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Vyberte uložený prístupový kľúč pre aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-sl/strings.xml b/packages/CredentialManager/res/values-sl/strings.xml
index 2c237ed..d2aaf68 100644
--- a/packages/CredentialManager/res/values-sl/strings.xml
+++ b/packages/CredentialManager/res/values-sl/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Na poti v prihodnost brez gesel bodo poleg ključev za dostop še vedno v uporabi tudi gesla."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Izbira mesta za shranjevanje <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Izberite upravitelja gesel za shranjevanje podatkov za prijavo, da se boste naslednjič lahko hitreje prijavili."</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Želite ustvariti ključ za dostop za prijavo v aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Želite shraniti geslo za prijavo v aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Želite shraniti podatke za prijavo za aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"ključ za dostop"</string>
     <string name="password" msgid="6738570945182936667">"geslo"</string>
     <string name="passkeys" msgid="5733880786866559847">"ključi za dostop"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Opusti"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Želite uporabiti shranjeni ključ za dostop do aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Ali želite uporabiti shranjeno geslo za aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Uporabite zaklepanje zaslona za prijavo v aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g> z uporabniškim imenom <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Želite uporabiti svojo prijavo za aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Želite odkleniti možnosti prijave za aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Izberite shranjeni ključ za dostop za aplikacijo <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-sq/strings.xml b/packages/CredentialManager/res/values-sq/strings.xml
index 71fb2f5..f31d16a 100644
--- a/packages/CredentialManager/res/values-sq/strings.xml
+++ b/packages/CredentialManager/res/values-sq/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Teksa shkojmë drejt një të ardhmeje pa fjalëkalime, këto të fundit do të ofrohen ende së bashku me çelësat e kalimit."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Zgjidh se ku t\'i ruash <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Zgjidh një menaxher fjalëkalimesh për të ruajtur informacionet e tua dhe për t\'u identifikuar më shpejt herën tjetër"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Të krijohet një çelës kalimi për t\'u identifikuar në <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Të ruhet fjalëkalimi për t\'u identifikuar në <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Të ruhen informacionet e identifikimit për <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"çelësin e kalimit"</string>
     <string name="password" msgid="6738570945182936667">"fjalëkalimi"</string>
     <string name="passkeys" msgid="5733880786866559847">"çelësat e kalimit"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Hiq"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Të përdoret fjalëkalimi yt i ruajtur për <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Të përdoret fjalëkalimi i ruajtur për <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Përdor kyçjen e ekranit për t\'u identifikuar në <xliff:g id="APP_NAME">%1$s</xliff:g> me <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Të përdoret identifikimi yt për <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Të shkyçen opsionet e identifikimit për <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Zgjidh një çelës kalimi të ruajtur për <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-sr/strings.xml b/packages/CredentialManager/res/values-sr/strings.xml
index 8cd0463..e68a20c 100644
--- a/packages/CredentialManager/res/values-sr/strings.xml
+++ b/packages/CredentialManager/res/values-sr/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Како се крећемо ка будућности без лозинки, лозинке ће и даље бити доступне уз приступне кодове."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Одаберите где ћете сачувати: <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Изаберите менаџера лозинки да бисте сачували податке и брже се пријавили следећи пут"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Желите да направите приступни кључ да бисте се пријавили у <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Желите да сачувате лозинку да бисте се пријавили у <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Желите да сачувате податке за пријављивање за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"приступни кôд"</string>
     <string name="password" msgid="6738570945182936667">"лозинка"</string>
     <string name="passkeys" msgid="5733880786866559847">"приступни кодови"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Одбаци"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Желите да користите сачувани приступни кôд за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Желите да користите сачувану лозинку за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Користите откључавање екрана да бисте се пријавили у <xliff:g id="APP_NAME">%1$s</xliff:g> као <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Желите ли да користите своје податке за пријављивање за апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Желите да откључате опције пријављивања за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Изаберите сачуван приступни кључ за: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-sv/strings.xml b/packages/CredentialManager/res/values-sv/strings.xml
index bb6ae3f..e18fea1 100644
--- a/packages/CredentialManager/res/values-sv/strings.xml
+++ b/packages/CredentialManager/res/values-sv/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Medan vi beger oss mot en lösenordslös framtid kommer lösenord fortfarande att vara tillgängliga utöver nycklar."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Välj var du vill spara <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Välj en lösenordshanterare för att spara dina uppgifter och logga in snabbare nästa gång"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Vill du skapa en nyckel för att logga in i <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Vill du spara lösenordet för att logga in i <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Vill du spara inloggningsuppgifterna för <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"nyckel"</string>
     <string name="password" msgid="6738570945182936667">"lösenord"</string>
     <string name="passkeys" msgid="5733880786866559847">"nycklar"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Stäng"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Vill du använda din sparade nyckel för <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Vill du använda det sparade lösenordet för <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Använd skärmlåset för att logga in i <xliff:g id="APP_NAME">%1$s</xliff:g> med <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Vill du använda din inloggning för <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Vill du låsa upp inloggningsalternativ för <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Välj en sparad nyckel för <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-sw/strings.xml b/packages/CredentialManager/res/values-sw/strings.xml
index 1a7a75e..65672d5 100644
--- a/packages/CredentialManager/res/values-sw/strings.xml
+++ b/packages/CredentialManager/res/values-sw/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Tunavyoelekea katika enzi isiyo ya manenosiri, manenosiri yataendelea kupatikana pamoja na funguo za siri."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Chagua ambako unahifadhi <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Chagua kidhibiti cha manenosiri ili uhifadhi taarifa zako na uingie kwenye akaunti kwa urahisi wakati mwingine"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Ungependa kubuni ufunguo wa siri wa kuingia katika akaunti ya <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Ungependa kuhifadhi nenosiri la kuingia katika akaunti ya <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Ungependa kuhifadhi maelezo ya kuingia katika akaunti ya <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"ufunguo wa siri"</string>
     <string name="password" msgid="6738570945182936667">"nenosiri"</string>
     <string name="passkeys" msgid="5733880786866559847">"funguo za siri"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Ondoa"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Ungependa kutumia ufunguo wa siri uliohifadhiwa wa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Je, ungependa kutumia nenosiri lako lililohifadhiwa kuingia katika <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Tumia mbinu yako ya kufunga skrini kuingia katika akaunti ya <xliff:g id="APP_NAME">%1$s</xliff:g> ukitumia <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Ungependa kutumia kitambulisho chako cha kuingia katika akaunti ya <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Je, ungependa kuona chaguo za kuingia katika <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Chagua ufunguo wa siri uliohifadhiwa ambao ungependa kutumia kuingia katika <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-ta/strings.xml b/packages/CredentialManager/res/values-ta/strings.xml
index 7a4ed5a..49d1710 100644
--- a/packages/CredentialManager/res/values-ta/strings.xml
+++ b/packages/CredentialManager/res/values-ta/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"கடவுச்சொல்லற்ற எதிர்காலத்தை நோக்கி நாம் பயணிக்கிறோம். கடவுச்சாவிகளைப் பயன்படுத்தும் இதே வேளையில் கடவுச்சொற்களையும் பயன்படுத்த முடியும்."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"உங்கள் <xliff:g id="CREATETYPES">%1$s</xliff:g> எங்கே சேமிக்கப்பட வேண்டும் என்பதைத் தேர்வுசெய்யுங்கள்"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"உங்கள் தகவல்களைச் சேமித்து அடுத்த முறை விரைவாக உள்நுழைய ஒரு கடவுச்சொல் நிர்வாகியைத் தேர்வுசெய்யுங்கள்"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸில் உள்நுழைய கடவுச்சாவியை உருவாக்கவா?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸில் உள்நுழைய கடவுச்சொல்லைச் சேமிக்கவா?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸுக்கான உள்நுழைவுத் தகவலைச் சேமிக்கவா?"</string>
     <string name="passkey" msgid="632353688396759522">"கடவுச்சாவி"</string>
     <string name="password" msgid="6738570945182936667">"கடவுச்சொல்"</string>
     <string name="passkeys" msgid="5733880786866559847">"கடவுச்சாவிகள்"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"நிராகரிக்கும்"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸுக்கு ஏற்கெனவே சேமிக்கப்பட்ட கடவுக்குறியீட்டைப் பயன்படுத்தவா?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸுக்குச் சேமித்த கடவுச்சொல்லைப் பயன்படுத்தவா?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="USERNAME">%2$s</xliff:g> ஐப் பயன்படுத்தி <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸில் உள்நுழைய உங்கள் திரைப் பூட்டைப் பயன்படுத்துங்கள்"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸுக்கு உங்கள் உள்நுழைவு விவரங்களைப் பயன்படுத்தவா?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸுக்கான உள்நுழைவு விருப்பங்களை அன்லாக் செய்யவா?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸுக்கான சேமிக்கப்பட்ட கடவுச்சாவியைத் தேர்ந்தெடுங்கள்"</string>
diff --git a/packages/CredentialManager/res/values-te/strings.xml b/packages/CredentialManager/res/values-te/strings.xml
index f2493c0..742a422 100644
--- a/packages/CredentialManager/res/values-te/strings.xml
+++ b/packages/CredentialManager/res/values-te/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"మనం భవిష్యత్తులో పాస్‌వర్డ్ రహిత టెక్నాలజీని ఉపయోగించినా, పాస్‌కీలతో పాటు పాస్‌వర్డ్‌లు కూడా అందుబాటులో ఉంటాయి."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"మీ <xliff:g id="CREATETYPES">%1$s</xliff:g> ఎక్కడ సేవ్ చేయాలో ఎంచుకోండి"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"తర్వాతిసారి మరింత వేగంగా సైన్ ఇన్ చేసేందుకు వీలుగా మీ సమాచారాన్ని సేవ్ చేయడం కోసం ఒక పాస్‌వర్డ్ మేనేజర్‌ను ఎంచుకోండి"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g>‌కు సైన్ ఇన్ చేయడానికి పాస్-కీని క్రియేట్ చేయాలా?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g>‌కు సైన్ ఇన్ చేయడానికి పాస్‌వర్డ్‌ను సేవ్ చేయాలా?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> కోసం సైన్ ఇన్ సమాచారాన్ని సేవ్ చేయాలా?"</string>
     <string name="passkey" msgid="632353688396759522">"పాస్-కీ"</string>
     <string name="password" msgid="6738570945182936667">"పాస్‌వర్డ్"</string>
     <string name="passkeys" msgid="5733880786866559847">"పాస్-కీలు"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"విస్మరించండి"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> కోసం మీ సేవ్ చేసిన పాస్-కీని ఉపయోగించాలా?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> కోసం మీ సేవ్ చేసిన పాస్‌వర్డ్‌ను ఉపయోగించాలా?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"మీ స్క్రీన్ లాక్‌ను ఉపయోగించి <xliff:g id="USERNAME">%2$s</xliff:g>‌తో <xliff:g id="APP_NAME">%1$s</xliff:g>‌కు సైన్ ఇన్ చేయండి"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> కోసం మీ సైన్ ఇన్ వివరాలను ఉపయోగించాలా?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> కోసం సైన్ ఇన్ ఆప్షన్‌లను అన్‌లాక్ చేయాలా?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> కోసం సేవ్ చేసిన పాస్-కీని ఎంచుకోండి"</string>
diff --git a/packages/CredentialManager/res/values-th/strings.xml b/packages/CredentialManager/res/values-th/strings.xml
index 1e08088..3f9de26 100644
--- a/packages/CredentialManager/res/values-th/strings.xml
+++ b/packages/CredentialManager/res/values-th/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"ในขณะที่เราก้าวไปสู่อนาคตที่ไม่ต้องใช้รหัสผ่านนั้น รหัสผ่านจะยังคงใช้ได้อยู่ควบคู่ไปกับการเปลี่ยนไปใช้พาสคีย์"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"เลือกว่าต้องการบันทึก<xliff:g id="CREATETYPES">%1$s</xliff:g>ไว้ที่ใด"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"เลือกเครื่องมือจัดการรหัสผ่านเพื่อบันทึกข้อมูลและลงชื่อเข้าใช้เร็วขึ้นในครั้งถัดไป"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"สร้างพาสคีย์เพื่อลงชื่อเข้าใช้ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"บันทึกรหัสผ่านเพื่อลงชื่อเข้าใช้ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"บันทึกข้อมูลการลงชื่อเข้าใช้สำหรับ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string>
     <string name="passkey" msgid="632353688396759522">"พาสคีย์"</string>
     <string name="password" msgid="6738570945182936667">"รหัสผ่าน"</string>
     <string name="passkeys" msgid="5733880786866559847">"พาสคีย์"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"ปิด"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"ใช้พาสคีย์ที่บันทึกไว้สำหรับ <xliff:g id="APP_NAME">%1$s</xliff:g> ใช่ไหม"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"ใช้รหัสผ่านที่บันทึกไว้สำหรับ <xliff:g id="APP_NAME">%1$s</xliff:g> ใช่ไหม"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"ใช้การล็อกหน้าจอเพื่อลงชื่อเข้าใช้ <xliff:g id="APP_NAME">%1$s</xliff:g> ด้วย <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"ใช้การลงชื่อเข้าใช้สำหรับ <xliff:g id="APP_NAME">%1$s</xliff:g> ใช่ไหม"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"ปลดล็อกตัวเลือกการลงชื่อเข้าใช้สำหรับ <xliff:g id="APP_NAME">%1$s</xliff:g> ใช่ไหม"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"เลือกพาสคีย์ที่บันทึกไว้สำหรับ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-tl/strings.xml b/packages/CredentialManager/res/values-tl/strings.xml
index a3bdc8f..659c1ec 100644
--- a/packages/CredentialManager/res/values-tl/strings.xml
+++ b/packages/CredentialManager/res/values-tl/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Habang lumalayo tayo sa mga password, magiging available pa rin ang mga password kasama ng mga passkey."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Piliin kung saan mo ise-save ang iyong <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Pumili ng password manager para ma-save ang iyong impormasyon at makapag-sign in nang mas mabilis sa susunod na pagkakataon"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Gumawa ng passkey para mag-sign in sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"I-save ang password para mag-sign in sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"I-save ang impormasyon sa pag-sign in para sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"passkey"</string>
     <string name="password" msgid="6738570945182936667">"password"</string>
     <string name="passkeys" msgid="5733880786866559847">"mga passkey"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"I-dismiss"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Gamitin ang iyong naka-save na passkey para sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Gamitin ang iyong naka-save na password para sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Gamitin ang iyong lock ng screen para mag-sign in sa <xliff:g id="APP_NAME">%1$s</xliff:g> gamit ang <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Gamitin ang iyong sign-in para sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"I-unlock ang mga opsyon sa pag-sign in para sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Pumili ng naka-save na passkey para sa <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-tr/strings.xml b/packages/CredentialManager/res/values-tr/strings.xml
index 9a05d2a..5139a67 100644
--- a/packages/CredentialManager/res/values-tr/strings.xml
+++ b/packages/CredentialManager/res/values-tr/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Şifresiz bir geleceğe doğru ilerlerken şifreler, geçiş anahtarlarıyla birlikte kullanılmaya devam edecektir."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"<xliff:g id="CREATETYPES">%1$s</xliff:g> kaydedileceği yeri seçin"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Bilgilerinizi kaydedip bir dahaki sefere daha hızlı oturum açmak için bir şifre yöneticisi seçin"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasında oturum açmak için geçiş anahtarı oluşturulsun mu?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasında oturum açmak için şifre kaydedilsin mi?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> için oturum açma bilgileri kaydedilsin mi?"</string>
     <string name="passkey" msgid="632353688396759522">"Geçiş anahtarı"</string>
     <string name="password" msgid="6738570945182936667">"Şifre"</string>
     <string name="passkeys" msgid="5733880786866559847">"Geçiş anahtarlarınızın"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Kapat"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> için kayıtlı geçiş anahtarınız kullanılsın mı?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> için kayıtlı şifreniz kullanılsın mı?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulamasında <xliff:g id="USERNAME">%2$s</xliff:g> hesabıyla oturum açmak için ekran kilidinizi kullanın"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> için oturum açma bilgileriniz kullanılsın mı?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> için oturum açma seçeneklerine izin verilsin mi?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> için kayıtlı bir geçiş anahtarı kullanın"</string>
diff --git a/packages/CredentialManager/res/values-uk/strings.xml b/packages/CredentialManager/res/values-uk/strings.xml
index 9781020..62eac9a 100644
--- a/packages/CredentialManager/res/values-uk/strings.xml
+++ b/packages/CredentialManager/res/values-uk/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"На шляху до безпарольного майбутнього паролі й надалі будуть використовуватися паралельно з ключами доступу."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Виберіть, де зберігати <xliff:g id="CREATETYPES">%1$s</xliff:g>"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Виберіть менеджер паролів, щоб зберігати свої дані й надалі входити в облікові записи швидше"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Створити ключ доступу для входу в додаток <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Зберегти пароль для входу в додаток <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Зберегти дані для входу для додатка <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"ключ доступу"</string>
     <string name="password" msgid="6738570945182936667">"пароль"</string>
     <string name="passkeys" msgid="5733880786866559847">"ключі доступу"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Закрити"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Використати збережений ключ доступу для додатка <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Використати ваш збережений пароль для додатка <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Використовуйте свій спосіб розблокування екрана, щоб входити в додаток <xliff:g id="APP_NAME">%1$s</xliff:g> як користувач <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Використовувати ваші дані для входу в додаток <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Розблокувати опції входу для додатка <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Виберіть збережений ключ доступу для додатка <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-ur/strings.xml b/packages/CredentialManager/res/values-ur/strings.xml
index b4e19bf..9fad273 100644
--- a/packages/CredentialManager/res/values-ur/strings.xml
+++ b/packages/CredentialManager/res/values-ur/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"چونکہ ہم بغیر پاس ورڈ والے مستقبل کی طرف جا رہے ہیں اس کے باوجود پاس ورڈز پاس کیز کے ساتھ ہی دستیاب ہوں گے۔"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"منتخب کریں کہ آپ کی <xliff:g id="CREATETYPES">%1$s</xliff:g> کو کہاں محفوظ کرنا ہے"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"اپنی معلومات کو محفوظ کرنے اور اگلی بار تیزی سے سائن ان کرنے کے لیے پاس ورڈ مینیجر منتخب کریں"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> میں سائن ان کرنے کیلئے پاس کی تخلیق کریں؟"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> میں سائن ان کرنے کیلئے پاس ورڈ محفوظ کریں؟"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے لیے سائن ان کی معلومات محفوظ کریں؟"</string>
     <string name="passkey" msgid="632353688396759522">"پاس کی"</string>
     <string name="password" msgid="6738570945182936667">"پاس ورڈ"</string>
     <string name="passkeys" msgid="5733880786866559847">"پاس کیز"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"برخاست کریں"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے لیے اپنی محفوظ کردہ پاس کی استعمال کریں؟"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے لیے آپ کا محفوظ کردہ پاس ورڈ استعمال کریں؟"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="USERNAME">%2$s</xliff:g> کے ساتھ <xliff:g id="APP_NAME">%1$s</xliff:g> میں سائن ان کرنے کے لیے اپنا اسکرین لاک استعمال کریں"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے لیے آپ کی سائن ان تفصیلات استعمال کریں؟"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے لیے سائن ان کے اختیارات کو غیر مقفل کریں؟"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> کے لیے ایک محفوظ کردہ پاس کی منتخب کریں"</string>
diff --git a/packages/CredentialManager/res/values-uz/strings.xml b/packages/CredentialManager/res/values-uz/strings.xml
index 0811e14..a3d2025 100644
--- a/packages/CredentialManager/res/values-uz/strings.xml
+++ b/packages/CredentialManager/res/values-uz/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Parolsiz kelajak sari harakatlanar ekanmiz, parollar kalitlar bilan birga ishlatilishda davom etadi."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Bu <xliff:g id="CREATETYPES">%1$s</xliff:g> qayerga saqlanishini tanlang"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Maʼlumotlaringizni saqlash va keyingi safar tez kirish uchun parollar menejerini tanlang"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga kirish uchun kirish kaliti yaratilsinmi?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga kirish uchun parol saqlansinmi?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"<xliff:g id="APP_NAME">%1$s</xliff:g> uchun kirish maʼlumoti saqlansinmi?"</string>
     <string name="passkey" msgid="632353688396759522">"kalit"</string>
     <string name="password" msgid="6738570945182936667">"parol"</string>
     <string name="passkeys" msgid="5733880786866559847">"kalitlar"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Yopish"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"<xliff:g id="APP_NAME">%1$s</xliff:g> uchun saqlangan kalit ishlatilsinmi?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"<xliff:g id="APP_NAME">%1$s</xliff:g> uchun saqlangan parol ishlatilsinmi?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga <xliff:g id="USERNAME">%2$s</xliff:g> bilan kirish uchun ekran qulfini ishlating"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga bu maʼlumotlar bilan kirilsinmi?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"<xliff:g id="APP_NAME">%1$s</xliff:g> uchun kirish usullari ochilsinmi?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"<xliff:g id="APP_NAME">%1$s</xliff:g> uchun saqlangan kalitni tanlang"</string>
diff --git a/packages/CredentialManager/res/values-vi/strings.xml b/packages/CredentialManager/res/values-vi/strings.xml
index 2550c06..da04efd 100644
--- a/packages/CredentialManager/res/values-vi/strings.xml
+++ b/packages/CredentialManager/res/values-vi/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Trong quá trình chúng tôi hướng đến tương lai không dùng mật khẩu, bạn vẫn sẽ dùng được mật khẩu cùng với khoá truy cập."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Chọn vị trí lưu <xliff:g id="CREATETYPES">%1$s</xliff:g> của bạn"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Hãy chọn một trình quản lý mật khẩu để lưu thông tin của bạn và đăng nhập nhanh hơn vào lần tới"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Tạo khoá truy cập để đăng nhập vào <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Lưu mật khẩu để đăng nhập vào <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Lưu thông tin đăng nhập cho <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"khoá đăng nhập"</string>
     <string name="password" msgid="6738570945182936667">"mật khẩu"</string>
     <string name="passkeys" msgid="5733880786866559847">"khoá truy cập"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Đóng"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Dùng khoá đăng nhập bạn đã lưu cho <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Sử dụng mật khẩu bạn đã lưu cho <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Dùng phương thức khoá màn hình để đăng nhập vào <xliff:g id="APP_NAME">%1$s</xliff:g> bằng <xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Dùng thông tin đăng nhập của bạn cho <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Mở khoá các tuỳ chọn đăng nhập cho <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Chọn khoá truy cập đã lưu cho <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-zh-rCN/strings.xml b/packages/CredentialManager/res/values-zh-rCN/strings.xml
index 5cbdf90..968e978 100644
--- a/packages/CredentialManager/res/values-zh-rCN/strings.xml
+++ b/packages/CredentialManager/res/values-zh-rCN/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"在我们向无密码未来迈进的过程中,密码仍会与通行密钥并行使用。"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"选择保存<xliff:g id="CREATETYPES">%1$s</xliff:g>的位置"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"请选择一款密码管理工具来保存您的信息,以便下次更快地登录"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"要创建通行密钥以便登录“<xliff:g id="APP_NAME">%1$s</xliff:g>”吗?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"要保存密码以便登录“<xliff:g id="APP_NAME">%1$s</xliff:g>”吗?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"要保存“<xliff:g id="APP_NAME">%1$s</xliff:g>”的登录信息吗?"</string>
     <string name="passkey" msgid="632353688396759522">"通行密钥"</string>
     <string name="password" msgid="6738570945182936667">"密码"</string>
     <string name="passkeys" msgid="5733880786866559847">"通行密钥"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"忽略"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"要使用您为“<xliff:g id="APP_NAME">%1$s</xliff:g>”保存的通行密钥吗?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"要使用已保存的密码登录“<xliff:g id="APP_NAME">%1$s</xliff:g>”吗?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"使用您的屏锁以 <xliff:g id="USERNAME">%2$s</xliff:g> 的身份登录“<xliff:g id="APP_NAME">%1$s</xliff:g>”"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"是否使用您的<xliff:g id="APP_NAME">%1$s</xliff:g>登录凭据继续?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"要解锁“<xliff:g id="APP_NAME">%1$s</xliff:g>”的登录选项吗?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"选择一个已保存的通行密钥来登录“<xliff:g id="APP_NAME">%1$s</xliff:g>”"</string>
diff --git a/packages/CredentialManager/res/values-zh-rHK/strings.xml b/packages/CredentialManager/res/values-zh-rHK/strings.xml
index 1a8eea7f..7a375c9 100644
--- a/packages/CredentialManager/res/values-zh-rHK/strings.xml
+++ b/packages/CredentialManager/res/values-zh-rHK/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"我們將會改用無密碼技術,而密碼仍可與密鑰並行使用。"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"選擇儲存<xliff:g id="CREATETYPES">%1$s</xliff:g>的位置"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"選取密碼管理工具即可儲存自己的資料,縮短下次登入的時間"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"要建立密鑰以登入 <xliff:g id="APP_NAME">%1$s</xliff:g> 嗎?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"要儲存密碼以登入 <xliff:g id="APP_NAME">%1$s</xliff:g> 嗎?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"要儲存 <xliff:g id="APP_NAME">%1$s</xliff:g> 的登入資料嗎?"</string>
     <string name="passkey" msgid="632353688396759522">"密鑰"</string>
     <string name="password" msgid="6738570945182936667">"密碼"</string>
     <string name="passkeys" msgid="5733880786866559847">"密鑰"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"關閉"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"要使用已儲存的「<xliff:g id="APP_NAME">%1$s</xliff:g>」密鑰嗎?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"要使用已儲存的「<xliff:g id="APP_NAME">%1$s</xliff:g>」密碼嗎?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"使用螢幕鎖定方式以 <xliff:g id="USERNAME">%2$s</xliff:g> 登入 <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"要以此登入方式使用「<xliff:g id="APP_NAME">%1$s</xliff:g>」嗎?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"要解鎖「<xliff:g id="APP_NAME">%1$s</xliff:g>」的登入選項嗎?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"選擇已儲存的「<xliff:g id="APP_NAME">%1$s</xliff:g>」密鑰"</string>
diff --git a/packages/CredentialManager/res/values-zh-rTW/strings.xml b/packages/CredentialManager/res/values-zh-rTW/strings.xml
index a1f353f..0299088 100644
--- a/packages/CredentialManager/res/values-zh-rTW/strings.xml
+++ b/packages/CredentialManager/res/values-zh-rTW/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"我們日後將改採無密碼技術,密碼仍可與密碼金鑰並行使用。"</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"選擇要將<xliff:g id="CREATETYPES">%1$s</xliff:g>存在哪裡"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"選取密碼管理工具並儲存資訊,下次就能更快登入"</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"要建立用於登入「<xliff:g id="APP_NAME">%1$s</xliff:g>」的密碼金鑰嗎?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"要儲存用於登入「<xliff:g id="APP_NAME">%1$s</xliff:g>」的密碼嗎?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"要儲存「<xliff:g id="APP_NAME">%1$s</xliff:g>」的登入資訊嗎?"</string>
     <string name="passkey" msgid="632353688396759522">"密碼金鑰"</string>
     <string name="password" msgid="6738570945182936667">"密碼"</string>
     <string name="passkeys" msgid="5733880786866559847">"密碼金鑰"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"關閉"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"要使用已儲存的「<xliff:g id="APP_NAME">%1$s</xliff:g>」密碼金鑰嗎?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"要使用已儲存的「<xliff:g id="APP_NAME">%1$s</xliff:g>」密碼嗎?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"用 <xliff:g id="USERNAME">%2$s</xliff:g> 登入「<xliff:g id="APP_NAME">%1$s</xliff:g>」時使用螢幕鎖定功能進行驗證"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"要使用你的憑證登入「<xliff:g id="APP_NAME">%1$s</xliff:g>」嗎?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"要解鎖「<xliff:g id="APP_NAME">%1$s</xliff:g>」的登入選項嗎?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"選擇已儲存的「<xliff:g id="APP_NAME">%1$s</xliff:g>」密碼金鑰"</string>
diff --git a/packages/CredentialManager/res/values-zu/strings.xml b/packages/CredentialManager/res/values-zu/strings.xml
index 68b98a7..4f888f4 100644
--- a/packages/CredentialManager/res/values-zu/strings.xml
+++ b/packages/CredentialManager/res/values-zu/strings.xml
@@ -39,12 +39,9 @@
     <string name="seamless_transition_detail" msgid="4475509237171739843">"Njengoba sibhekela kwikusasa elingenaphasiwedi, amagama ayimfihlo asazotholakala eceleni kokhiye bokudlula."</string>
     <string name="choose_provider_title" msgid="8870795677024868108">"Khetha lapho ongagcina khona i-<xliff:g id="CREATETYPES">%1$s</xliff:g> yakho"</string>
     <string name="choose_provider_body" msgid="4967074531845147434">"Khetha isiphathi sephasiwedi ukuze ulondoloze ulwazi lwakho futhi ungene ngemvume ngokushesha ngesikhathi esizayo."</string>
-    <!-- no translation found for choose_create_option_passkey_title (8762295821604276511) -->
-    <skip />
-    <!-- no translation found for choose_create_option_password_title (4481366993598649224) -->
-    <skip />
-    <!-- no translation found for choose_create_option_sign_in_title (7092914088455358079) -->
-    <skip />
+    <string name="choose_create_option_passkey_title" msgid="8762295821604276511">"Sungula ukhiye wokudlula ukuze ungene ngemvume ku-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_password_title" msgid="4481366993598649224">"Londoloza iphasiwedi ukuze ungene ngemvume ku-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
+    <string name="choose_create_option_sign_in_title" msgid="7092914088455358079">"Londoloza ulwazi lokungena lwe-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="passkey" msgid="632353688396759522">"ukhiye wokudlula"</string>
     <string name="password" msgid="6738570945182936667">"iphasiwedi"</string>
     <string name="passkeys" msgid="5733880786866559847">"okhiye bokudlula"</string>
@@ -73,8 +70,7 @@
     <string name="accessibility_snackbar_dismiss" msgid="3456598374801836120">"Chitha"</string>
     <string name="get_dialog_title_use_passkey_for" msgid="6236608872708021767">"Sebenzisa ukhiye wakho wokungena olondoloziwe <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_use_password_for" msgid="625828023234318484">"Sebenzisa iphasiwedi yakho elondoloziwe ye-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
-    <!-- no translation found for get_dialog_title_single_tap_for (2057945648748859483) -->
-    <skip />
+    <string name="get_dialog_title_single_tap_for" msgid="2057945648748859483">"Sebenzisa ukukhiya kwakho kwesikrini ukuze ungene ngemvume ku-<xliff:g id="APP_NAME">%1$s</xliff:g> ngo-<xliff:g id="USERNAME">%2$s</xliff:g>"</string>
     <string name="get_dialog_title_use_sign_in_for" msgid="790049858275131785">"Sebenzisa ukungena kwakho ngemvume ku-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_unlock_options_for" msgid="7605568190597632433">"Vula ukungena ngemvume okukhethwa kukho kwe-<xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="get_dialog_title_choose_passkey_for" msgid="9175997688078538490">"Khetha ukhiye wokudlula olondoloziwe we-<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/shared/project.config b/packages/CredentialManager/shared/project.config
new file mode 100644
index 0000000..f748d6c
--- /dev/null
+++ b/packages/CredentialManager/shared/project.config
@@ -0,0 +1,9 @@
+[notify "team"]
+	header = cc
+        email = sgjerry@google.com
+        email = helenqin@google.com
+	email = hemnani@google.com
+	email = shuanghao@google.com
+	email = harinirajan@google.com
+	type = new_changes
+	type = submitted_changes
\ No newline at end of file
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
index 6ba684d..1253ce3 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
@@ -47,6 +47,7 @@
 import android.util.Log
 import android.content.Intent
 import android.view.autofill.AutofillId
+import android.view.autofill.AutofillManager
 import android.view.autofill.IAutoFillManagerClient
 import android.widget.RemoteViews
 import android.widget.inline.InlinePresentationSpec
@@ -372,6 +373,7 @@
 
         fillResponseBuilder.addDataset(
                 Dataset.Builder()
+                        .setId(AutofillManager.PINNED_DATASET_ID)
                         .setField(
                                 autofillId,
                                 Field.Builder().setPresentations(
@@ -411,6 +413,7 @@
 
         fillResponseBuilder.addDataset(
                 dataSetBuilder
+                        .setId(AutofillManager.PINNED_DATASET_ID)
                         .setField(
                                 autofillId,
                                 Field.Builder().setPresentations(
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
index d21077e..a30956e 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/BiometricHandler.kt
@@ -98,7 +98,8 @@
     context: Context,
     openMoreOptionsPage: () -> Unit,
     sendDataToProvider: (EntryInfo, BiometricPrompt.AuthenticationResult) -> Unit,
-    onCancelFlowAndFinish: (String) -> Unit,
+    onCancelFlowAndFinish: () -> Unit,
+    onIllegalStateAndFinish: (String) -> Unit,
     getRequestDisplayInfo: RequestDisplayInfo? = null,
     getProviderInfoList: List<ProviderInfo>? = null,
     getProviderDisplayInfo: ProviderDisplayInfo? = null,
@@ -131,7 +132,7 @@
 
     val callback: BiometricPrompt.AuthenticationCallback =
         setupBiometricAuthenticationCallback(sendDataToProvider, biometricEntry,
-            onCancelFlowAndFinish)
+            onCancelFlowAndFinish, onIllegalStateAndFinish)
 
     val cancellationSignal = CancellationSignal()
     cancellationSignal.setOnCancelListener {
@@ -211,7 +212,8 @@
 private fun setupBiometricAuthenticationCallback(
     sendDataToProvider: (EntryInfo, BiometricPrompt.AuthenticationResult) -> Unit,
     selectedEntry: EntryInfo,
-    onCancelFlowAndFinish: (String) -> Unit
+    onCancelFlowAndFinish: () -> Unit,
+    onIllegalStateAndFinish: (String) -> Unit,
 ): BiometricPrompt.AuthenticationCallback {
     val callback: BiometricPrompt.AuthenticationCallback =
         object : BiometricPrompt.AuthenticationCallback() {
@@ -224,14 +226,12 @@
                     if (authResult != null) {
                         sendDataToProvider(selectedEntry, authResult)
                     } else {
-                        onCancelFlowAndFinish("The biometric flow succeeded but unexpectedly " +
+                        onIllegalStateAndFinish("The biometric flow succeeded but unexpectedly " +
                                 "returned a null value.")
-                        // TODO(b/326243754) : Propagate to provider
                     }
                 } catch (e: Exception) {
-                    onCancelFlowAndFinish("The biometric flow succeeded but failed on handling " +
+                    onIllegalStateAndFinish("The biometric flow succeeded but failed on handling " +
                             "the result. See: \n$e\n")
-                    // TODO(b/326243754) : Propagate to provider
                 }
             }
 
@@ -245,6 +245,12 @@
             override fun onAuthenticationError(errorCode: Int, errString: CharSequence?) {
                 super.onAuthenticationError(errorCode, errString)
                 Log.d(TAG, "Authentication error-ed out: $errorCode and $errString")
+                if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED) {
+                    // Note that because the biometric prompt is imbued directly
+                    // into the selector, parity applies to the selector's cancellation instead
+                    // of the provider's biometric prompt cancellation.
+                    onCancelFlowAndFinish()
+                }
                 // TODO(b/326243754) : Propagate to provider
             }
 
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt
index e43b09e..f65a1b7 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/common/ui/BottomSheet.kt
@@ -20,7 +20,9 @@
 import androidx.compose.animation.animateContentSize
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.WindowInsets
 import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.navigationBars
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.wrapContentHeight
 import androidx.compose.material3.ExperimentalMaterial3Api
@@ -69,6 +71,7 @@
                 },
                 scrimColor = MaterialTheme.colorScheme.scrim.copy(alpha = .32f),
                 shape = EntryShape.TopRoundedCorner,
+                windowInsets = WindowInsets.navigationBars,
                 dragHandle = null,
                 // Never take over the full screen. We always want to leave some top scrim space
                 // for exiting and viewing the underlying app to help a user gain context.
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index b59ccc2..4d7272c 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -148,7 +148,8 @@
                                 // activeEntry will always be what represents the single tap flow
                                 biometricEntry = getCredentialUiState.activeEntry,
                                 onMoreOptionSelected = viewModel::getFlowOnMoreOptionSelected,
-                                onCancelFlowAndFinish = viewModel::onIllegalUiState,
+                                onCancelFlowAndFinish = viewModel::onUserCancel,
+                                onIllegalStateAndFinish = viewModel::onIllegalUiState,
                                 requestDisplayInfo = getCredentialUiState.requestDisplayInfo,
                                 providerInfoList = getCredentialUiState.providerInfoList,
                                 providerDisplayInfo = getCredentialUiState.providerDisplayInfo,
@@ -212,7 +213,8 @@
 @Composable
 internal fun BiometricSelectionPage(
     biometricEntry: EntryInfo?,
-    onCancelFlowAndFinish: (String) -> Unit,
+    onCancelFlowAndFinish: () -> Unit,
+    onIllegalStateAndFinish: (String) -> Unit,
     onMoreOptionSelected: () -> Unit,
     requestDisplayInfo: RequestDisplayInfo,
     providerInfoList: List<ProviderInfo>,
@@ -230,6 +232,7 @@
         openMoreOptionsPage = onMoreOptionSelected,
         sendDataToProvider = onBiometricEntrySelected,
         onCancelFlowAndFinish = onCancelFlowAndFinish,
+        onIllegalStateAndFinish = onIllegalStateAndFinish,
         getRequestDisplayInfo = requestDisplayInfo,
         getProviderInfoList = providerInfoList,
         getProviderDisplayInfo = providerDisplayInfo,
diff --git a/packages/EasterEgg/Android.bp b/packages/EasterEgg/Android.bp
index 6f4f9ca..ec1fe39 100644
--- a/packages/EasterEgg/Android.bp
+++ b/packages/EasterEgg/Android.bp
@@ -83,6 +83,7 @@
 aconfig_declarations {
     name: "easter_egg_flags",
     package: "com.android.egg.flags",
+    container: "system",
     srcs: [
         "easter_egg_flags.aconfig",
     ],
diff --git a/packages/EasterEgg/easter_egg_flags.aconfig b/packages/EasterEgg/easter_egg_flags.aconfig
index 3268a4f..7ddc238 100644
--- a/packages/EasterEgg/easter_egg_flags.aconfig
+++ b/packages/EasterEgg/easter_egg_flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.egg.flags"
+container: "system"
 
 flag {
     name: "flag_flag"
diff --git a/packages/InputDevices/res/raw/keyboard_layout_french.kcm b/packages/InputDevices/res/raw/keyboard_layout_french.kcm
index 636f98d..4f4fb1b 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_french.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_french.kcm
@@ -35,85 +35,97 @@
 }
 
 key 1 {
-    label:                              '1'
+    label:                              '&'
     base:                               '&'
-    shift:                              '1'
+    shift, capslock:                    '1'
+    shift+capslock:                     '&'
 }
 
 key 2 {
-    label:                              '2'
+    label:                              '\u00e9'
     base:                               '\u00e9'
-    shift:                              '2'
+    shift, capslock:                    '2'
+    shift+capslock:                     '\u00e9'
     ralt:                               '\u0303'
 }
 
 key 3 {
-    label:                              '3'
+    label:                              '"'
     base:                               '"'
-    shift:                              '3'
+    shift, capslock:                    '3'
+    shift+capslock:                     '"'
     ralt:                               '#'
 }
 
 key 4 {
-    label:                              '4'
+    label:                              '\''
     base:                               '\''
-    shift:                              '4'
+    shift, capslock:                    '4'
+    shift+capslock:                     '\''
     ralt:                               '{'
 }
 
 key 5 {
-    label:                              '5'
+    label:                              '('
     base:                               '('
-    shift:                              '5'
+    shift, capslock:                    '5'
+    shift+capslock:                     '('
     ralt:                               '['
 }
 
 key 6 {
-    label:                              '6'
+    label:                              '-'
     base:                               '-'
-    shift:                              '6'
+    shift, capslock:                    '6'
+    shift+capslock:                     '-'
     ralt:                               '|'
 }
 
 key 7 {
-    label:                              '7'
+    label:                              '\u00e8'
     base:                               '\u00e8'
-    shift:                              '7'
+    shift, capslock:                    '7'
+    shift+capslock:                     '\u00e8'
     ralt:                               '\u0300'
 }
 
 key 8 {
-    label:                              '8'
+    label:                              '_'
     base:                               '_'
-    shift:                              '8'
+    shift, capslock:                    '8'
+    shift+capslock:                     '_'
     ralt:                               '\\'
 }
 
 key 9 {
-    label:                              '9'
+    label:                              '\u00e7'
     base:                               '\u00e7'
-    shift:                              '9'
+    shift, capslock:                    '9'
+    shift+capslock:                     '\u00e7'
     ralt:                               '^'
 }
 
 key 0 {
-    label:                              '0'
+    label:                              '\u00e0'
     base:                               '\u00e0'
-    shift:                              '0'
+    shift, capslock:                    '0'
+    shift+capslock:                     '\u00e0'
     ralt:                               '@'
 }
 
 key MINUS {
     label:                              ')'
     base:                               ')'
-    shift:                              '\u00b0'
+    shift, capslock:                    '\u00b0'
+    shift+capslock:                     ')'
     ralt:                               ']'
 }
 
 key EQUALS {
     label:                              '='
     base:                               '='
-    shift:                              '+'
+    shift, capslock:                    '+'
+    shift+capslock:                     '='
     ralt:                               '}'
 }
 
@@ -193,13 +205,15 @@
 key LEFT_BRACKET {
     label:                              '\u02c6'
     base:                               '\u0302'
-    shift:                              '\u0308'
+    shift, capslock:                    '\u0308'
+    shift+capslock:                     '\u0302'
 }
 
 key RIGHT_BRACKET {
     label:                              '$'
     base:                               '$'
-    shift:                              '\u00a3'
+    shift, capslock:                    '\u00a3'
+    shift+capslock:                     '$'
     ralt:                               '\u00a4'
 }
 
@@ -278,13 +292,15 @@
 key APOSTROPHE {
     label:                              '\u00f9'
     base:                               '\u00f9'
-    shift:                              '%'
+    shift, capslock:                    '%'
+    shift+capslock:                     '\u00f9'
 }
 
 key BACKSLASH {
     label:                              '*'
     base:                               '*'
-    shift:                              '\u00b5'
+    shift, capslock:                    '\u00b5'
+    shift+capslock:                     '*'
 }
 
 ### ROW 4
@@ -340,23 +356,27 @@
 key COMMA {
     label:                              ','
     base:                               ','
-    shift:                              '?'
+    shift, capslock:                    '?'
+    shift+capslock:                     ','
 }
 
 key SEMICOLON {
     label:                              ';'
     base:                               ';'
-    shift:                              '.'
+    shift, capslock:                    '.'
+    shift+capslock:                     ';'
 }
 
 key PERIOD {
     label:                              ':'
     base:                               ':'
-    shift:                              '/'
+    shift, capslock:                    '/'
+    shift+capslock:                     ':'
 }
 
 key SLASH {
     label:                              '!'
     base:                               '!'
-    shift:                              '\u00a7'
+    shift, capslock:                    '\u00a7'
+    shift+capslock:                     '!'
 }
diff --git a/packages/PackageInstaller/Android.bp b/packages/PackageInstaller/Android.bp
index 79c810c..bd84b58 100644
--- a/packages/PackageInstaller/Android.bp
+++ b/packages/PackageInstaller/Android.bp
@@ -46,7 +46,6 @@
     sdk_version: "system_current",
     rename_resources_package: false,
     static_libs: [
-        "xz-java",
         "androidx.leanback_leanback",
         "androidx.annotation_annotation",
         "androidx.fragment_fragment",
@@ -79,7 +78,6 @@
     overrides: ["PackageInstaller"],
 
     static_libs: [
-        "xz-java",
         "androidx.leanback_leanback",
         "androidx.fragment_fragment",
         "androidx.lifecycle_lifecycle-livedata",
@@ -112,7 +110,6 @@
     overrides: ["PackageInstaller"],
 
     static_libs: [
-        "xz-java",
         "androidx.leanback_leanback",
         "androidx.annotation_annotation",
         "androidx.fragment_fragment",
diff --git a/packages/PackageInstaller/AndroidManifest.xml b/packages/PackageInstaller/AndroidManifest.xml
index bf69d3b..05f4d69 100644
--- a/packages/PackageInstaller/AndroidManifest.xml
+++ b/packages/PackageInstaller/AndroidManifest.xml
@@ -146,17 +146,6 @@
                 android:configChanges="mnc|mnc|touchscreen|navigation|screenLayout|screenSize|smallestScreenSize|orientation|locale|keyboard|keyboardHidden|fontScale|uiMode|layoutDirection|density"
                 android:exported="false" />
 
-        <!-- Wearable Components -->
-        <service android:name=".wear.WearPackageInstallerService"
-                 android:permission="com.google.android.permission.INSTALL_WEARABLE_PACKAGES"
-                 android:foregroundServiceType="systemExempted"
-                 android:exported="true"/>
-
-        <provider android:name=".wear.WearPackageIconProvider"
-                  android:authorities="com.google.android.packageinstaller.wear.provider"
-                  android:grantUriPermissions="true"
-                  android:exported="false" />
-
         <receiver android:name="androidx.profileinstaller.ProfileInstallReceiver"
             tools:node="remove" />
 
diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml
index eaae47d..149783d 100644
--- a/packages/PackageInstaller/res/values-nl/strings.xml
+++ b/packages/PackageInstaller/res/values-nl/strings.xml
@@ -83,8 +83,8 @@
     <string name="uninstall_failed" msgid="1847750968168364332">"Verwijdering mislukt."</string>
     <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kan niet worden verwijderd."</string>
     <string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-kloon verwijderen…"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Kan actieve apparaatbeheer-app niet verwijderen"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Kan actieve apparaatbeheer-app niet verwijderen voor <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Kan actieve app voor apparaatbeheer niet verwijderen"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Kan actieve app voor apparaatbeheer niet verwijderen voor <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
     <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Deze app is vereist voor sommige gebruikers of profielen en is verwijderd voor andere"</string>
     <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Deze app is vereist voor je profiel en kan niet worden verwijderd."</string>
     <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Deze app is vereist door je apparaatbeheerder en kan niet worden verwijderd."</string>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt
index 08028b1..f7752ff 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/InstallRepository.kt
@@ -60,6 +60,7 @@
 import com.android.packageinstaller.v2.model.PackageUtil.isCallerSessionOwner
 import com.android.packageinstaller.v2.model.PackageUtil.isInstallPermissionGrantedOrRequested
 import com.android.packageinstaller.v2.model.PackageUtil.isPermissionGranted
+import com.android.packageinstaller.v2.model.PackageUtil.localLogv
 import java.io.File
 import java.io.IOException
 import kotlinx.coroutines.DelicateCoroutinesApi
@@ -75,7 +76,6 @@
     private val devicePolicyManager: DevicePolicyManager? =
         context.getSystemService(DevicePolicyManager::class.java)
     private val appOpsManager: AppOpsManager? = context.getSystemService(AppOpsManager::class.java)
-    private val localLOGV = false
     private var isSessionInstall = false
     private var isTrustedSource = false
     private val _stagingResult = MutableLiveData<InstallStage>()
@@ -155,8 +155,18 @@
             originatingUid, callingAttributionTag
         )
 
+        if(localLogv) {
+            Log.i(LOG_TAG, "Intent: $intent\n" +
+                "sessionId: $sessionId\n" +
+                "staged sessionId: $stagedSessionId\n" +
+                "calling package: $callingPackage\n" +
+                "callingUid: $callingUid\n" +
+                "originatingUid: $originatingUid")
+        }
+
         if (callingUid == Process.INVALID_UID && sourceInfo == null) {
             // Caller's identity could not be determined. Abort the install
+            Log.e(LOG_TAG, "Cannot determine caller since UID is invalid and sourceInfo is null")
             return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
         }
 
@@ -165,6 +175,9 @@
             || (stagedSessionId != SessionInfo.INVALID_ID
                 && !isCallerSessionOwner(packageInstaller, Process.myUid(), stagedSessionId))
         ) {
+            Log.e(LOG_TAG, "UID is not the owner of the session:\n" +
+                "CallingUid: $originatingUid | SessionId: $sessionId\n" +
+                "My UID: ${Process.myUid()} | StagedSessionId: $stagedSessionId")
             return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
         }
 
@@ -173,6 +186,9 @@
                 context, callingUid, originatingUid, isTrustedSource
             )
         ) {
+            Log.e(LOG_TAG, "UID $originatingUid needs to declare " +
+                Manifest.permission.REQUEST_INSTALL_PACKAGES
+            )
             return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
         }
 
@@ -180,6 +196,7 @@
         if (restriction != null) {
             val adminSupportDetailsIntent =
                 devicePolicyManager!!.createAdminSupportIntent(restriction)
+            Log.e(LOG_TAG, "$restriction set in place. Cannot install." )
             return InstallAborted(
                 ABORT_REASON_POLICY, message = restriction, resultIntent = adminSupportDetailsIntent
             )
@@ -287,7 +304,7 @@
                         stagedSessionId = packageInstaller.createSession(params)
                     }
                 } catch (e: Exception) {
-                    Log.w(LOG_TAG, "Failed to create a staging session", e)
+                    Log.e(LOG_TAG, "Failed to create a staging session", e)
                     _stagingResult.value = InstallAborted(
                         ABORT_REASON_INTERNAL_ERROR,
                         resultIntent = Intent().putExtra(
@@ -308,6 +325,7 @@
                     _stagingResult.value = InstallReady()
                 } else {
                     cleanupStagingSession()
+                    Log.e(LOG_TAG, "Could not stage APK.")
                     _stagingResult.value = InstallAborted(
                         ABORT_REASON_INTERNAL_ERROR,
                         resultIntent = Intent().putExtra(
@@ -318,6 +336,7 @@
                 }
             }
         } else {
+            Log.e(LOG_TAG, "Invalid URI: ${if (uri == null) "null" else uri.scheme}")
             _stagingResult.value = InstallAborted(
                 ABORT_REASON_INTERNAL_ERROR,
                 resultIntent = Intent().putExtra(
@@ -403,8 +422,8 @@
      */
     fun requestUserConfirmation(): InstallStage {
         return if (isTrustedSource) {
-            if (localLOGV) {
-                Log.i(LOG_TAG, "install allowed")
+            if (localLogv) {
+                Log.i(LOG_TAG, "Install allowed")
             }
             // Returns InstallUserActionRequired stage if install details could be successfully
             // computed, else it returns InstallAborted.
@@ -428,7 +447,7 @@
             val info = packageInstaller.getSessionInfo(sessionId)
             val resolvedPath = info?.resolvedBaseApkPath
             if (info == null || !info.isSealed || resolvedPath == null) {
-                Log.w(LOG_TAG, "Session $sessionId in funky state; ignoring")
+                Log.e(LOG_TAG, "Session $sessionId in funky state; ignoring")
                 return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
             }
             packageSource = Uri.fromFile(File(resolvedPath))
@@ -440,7 +459,7 @@
         } else if (PackageInstaller.ACTION_CONFIRM_PRE_APPROVAL == intent.action) {
             val info = packageInstaller.getSessionInfo(sessionId)
             if (info == null || !info.isPreApprovalRequested) {
-                Log.w(LOG_TAG, "Session $sessionId in funky state; ignoring")
+                Log.e(LOG_TAG, "Session $sessionId in funky state; ignoring")
                 return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
             }
             packageSource = info
@@ -465,7 +484,7 @@
 
         // if there's nothing to do, quietly slip into the ether
         if (packageSource == null) {
-            Log.w(LOG_TAG, "Unspecified source")
+            Log.e(LOG_TAG, "Unspecified source")
             return InstallAborted(
                 ABORT_REASON_INTERNAL_ERROR,
                 resultIntent = Intent().putExtra(
@@ -509,7 +528,7 @@
         if (scheme == null) {
             return InstallAborted(ABORT_REASON_INTERNAL_ERROR)
         }
-        if (localLOGV) {
+        if (localLogv) {
             Log.i(LOG_TAG, "processPackageUri(): uri = $packageUri, scheme = $scheme")
         }
         when (scheme) {
@@ -528,7 +547,7 @@
                     }
                 }
                 if (newPackageInfo == null) {
-                    Log.w(
+                    Log.e(
                         LOG_TAG, "Requested package " + packageUri.schemeSpecificPart
                             + " not available. Discontinuing installation"
                     )
@@ -542,7 +561,7 @@
                     )
                 }
                 appSnippet = getAppSnippet(context, newPackageInfo!!)
-                if (localLOGV) {
+                if (localLogv) {
                     Log.i(LOG_TAG, "Created snippet for " + appSnippet.label)
                 }
             }
@@ -569,7 +588,7 @@
                         activityResultCode = Activity.RESULT_FIRST_USER
                     )
                 }
-                if (localLOGV) {
+                if (localLogv) {
                     Log.i(LOG_TAG, "Creating snippet for local file $sourceFile")
                 }
                 appSnippet = getAppSnippet(context, newPackageInfo!!, sourceFile!!)
@@ -590,9 +609,7 @@
      * Use the SessionInfo and set up the installer for pre-commit install session.
      *
      * @param sessionInfo The SessionInfo to compose
-     * @return
-     *  * [InstallUserActionRequired] if source could be processed
-     *  * [InstallAborted] if source is invalid or there was an error is processing a source
+     * @return [InstallUserActionRequired]
      */
     private fun processSessionInfo(sessionInfo: SessionInfo, userActionReason: Int): InstallStage {
         newPackageInfo = generateStubPackageInfo(sessionInfo.getAppPackageName())
@@ -718,7 +735,7 @@
             appOpStr!!, requestInfo.originatingUid, requestInfo.callingPackage,
             requestInfo.attributionTag, "Started package installation activity"
         )
-        if (localLOGV) {
+        if (localLogv) {
             Log.i(LOG_TAG, "handleUnknownSources(): appMode=$appOpMode")
         }
 
@@ -764,6 +781,9 @@
     fun initiateInstall() {
         if (sessionId > 0) {
             packageInstaller.setPermissionsResult(sessionId, true)
+            if (localLogv) {
+                Log.i(LOG_TAG, "Install permission granted for session $sessionId")
+            }
             _installResult.value = InstallAborted(
                 ABORT_REASON_DONE, activityResultCode = Activity.RESULT_OK
             )
@@ -824,8 +844,13 @@
     private fun setStageBasedOnResult(
         statusCode: Int,
         legacyStatus: Int,
-        message: String?
+        message: String?,
     ) {
+        if (localLogv) {
+            Log.i(LOG_TAG, "Status code: $statusCode\n" +
+                "legacy status: $legacyStatus\n" +
+                "message: $message")
+        }
         if (statusCode == PackageInstaller.STATUS_SUCCESS) {
             val shouldReturnResult = intent.getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)
             val resultIntent = if (shouldReturnResult) {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt
index 8d8c2f1..bae6f68 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/PackageUtil.kt
@@ -36,7 +36,8 @@
 object PackageUtil {
     private val LOG_TAG = InstallRepository::class.java.simpleName
     private const val DOWNLOADS_AUTHORITY = "downloads"
-    private const val SPLIT_BASE_APK_END_WITH = "base.apk"
+    private const val SPLIT_BASE_APK_SUFFIX = "base.apk"
+    const val localLogv = false
 
     /**
      * Determines if the UID belongs to the system downloads provider and returns the
@@ -394,7 +395,7 @@
     @JvmStatic
     fun getPackageInfo(context: Context, sourceFile: File, flags: Int): PackageInfo? {
         var filePath = sourceFile.absolutePath
-        if (filePath.endsWith(SPLIT_BASE_APK_END_WITH)) {
+        if (filePath.endsWith(SPLIT_BASE_APK_SUFFIX)) {
             val dir = sourceFile.parentFile
             if ((dir?.listFiles()?.size ?: 0) > 1) {
                 // split apks, use file directory to get archive info
@@ -436,5 +437,9 @@
      * The class to hold an incoming package's icon and label.
      * See [getAppSnippet]
      */
-    data class AppSnippet(var label: CharSequence?, var icon: Drawable?)
+    data class AppSnippet(var label: CharSequence?, var icon: Drawable?) {
+        override fun toString(): String {
+            return "AppSnippet[label = ${label}, hasIcon = ${icon != null}]"
+        }
+    }
 }
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/UninstallRepository.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/UninstallRepository.kt
index c6b6d36..0091a3e8 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/UninstallRepository.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/model/UninstallRepository.kt
@@ -226,18 +226,19 @@
                 userName
             )
             if (userManager!!.isSameProfileGroup(myUserHandle, uninstalledUser!!)) {
-                if (customUserManager!!.isManagedProfile()) {
+                if (customUserManager.isManagedProfile) {
                     messageString = context.getString(
                             R.string.uninstall_application_text_current_user_work_profile, userName
                     )
-                } else if (customUserManager!!.isCloneProfile()){
+                } else if (customUserManager.isCloneProfile){
                     isClonedApp = true
                     messageString = context.getString(
                             R.string.uninstall_application_text_current_user_clone_profile
                     )
                 } else if (Flags.allowPrivateProfile()
                         && android.multiuser.Flags.enablePrivateSpaceFeatures()
-                        && customUserManager!!.isPrivateProfile()) {
+                        && customUserManager.isPrivateProfile
+                ) {
                     // TODO(b/324244123): Get these Strings from a User Property API.
                     messageString = context.getString(
                             R.string.uninstall_application_text_current_user_private_profile
@@ -401,6 +402,7 @@
         uninstallData.putBoolean(Intent.EXTRA_UNINSTALL_ALL_USERS, uninstallFromAllUsers)
         uninstallData.putCharSequence(EXTRA_APP_LABEL, targetAppLabel)
         uninstallData.putBoolean(EXTRA_IS_CLONE_APP, isClonedApp)
+        uninstallData.putInt(EXTRA_TARGET_USER_ID, uninstalledUser!!.identifier)
         Log.i(LOG_TAG, "Uninstalling extras = $uninstallData")
 
         // Get a PendingIntent for result broadcast and issue an uninstall request
@@ -730,7 +732,7 @@
         }
     }
 
-    fun cancelInstall() {
+    fun cancelUninstall() {
         if (callback != null) {
             callback!!.onUninstallComplete(
                 targetPackageName!!,
@@ -749,6 +751,7 @@
         private const val EXTRA_IS_CLONE_APP = "com.android.packageinstaller.extra.IS_CLONE_APP"
         private const val EXTRA_PACKAGE_NAME =
             "com.android.packageinstaller.extra.EXTRA_PACKAGE_NAME"
+        private const val EXTRA_TARGET_USER_ID = "EXTRA_TARGET_USER_ID"
     }
 
     class CallerInfo(val activityName: String?, val uid: Int)
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/InstallLaunch.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/InstallLaunch.kt
index 6f8eca3..31b9ccb 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/InstallLaunch.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/InstallLaunch.kt
@@ -43,6 +43,7 @@
 import com.android.packageinstaller.v2.model.InstallStage
 import com.android.packageinstaller.v2.model.InstallSuccess
 import com.android.packageinstaller.v2.model.InstallUserActionRequired
+import com.android.packageinstaller.v2.model.PackageUtil.localLogv
 import com.android.packageinstaller.v2.ui.fragments.AnonymousSourceFragment
 import com.android.packageinstaller.v2.ui.fragments.ExternalSourcesBlockedFragment
 import com.android.packageinstaller.v2.ui.fragments.InstallConfirmationFragment
@@ -66,8 +67,6 @@
         private const val TAG_DIALOG = "dialog"
     }
 
-    private val localLOGV = false
-
     /**
      * A collection of unknown sources listeners that are actively listening for app ops mode
      * changes
@@ -199,14 +198,14 @@
         // admin enforcing the restriction for the affected user. If not enforced by the admin,
         // show the system dialog.
         if (adminSupportIntent != null) {
-            if (localLOGV) {
+            if (localLogv) {
                 Log.i(LOG_TAG, "Restriction set by admin, starting $adminSupportIntent")
             }
             startActivity(adminSupportIntent)
             // Finish the package installer app since the next dialog will not be shown by this app
             shouldFinish = true
         } else {
-            if (localLOGV) {
+            if (localLogv) {
                 Log.i(LOG_TAG, "Restriction set by system: $restriction")
             }
             val blockedByPolicyDialog = createDevicePolicyRestrictionDialog(restriction)
@@ -225,7 +224,7 @@
      * @return The dialog
      */
     private fun createDevicePolicyRestrictionDialog(restriction: String?): DialogFragment? {
-        if (localLOGV) {
+        if (localLogv) {
             Log.i(LOG_TAG, "createDialog($restriction)")
         }
         return when (restriction) {
@@ -259,6 +258,9 @@
     }
 
     override fun onPositiveResponse(reasonCode: Int) {
+        if (localLogv) {
+            Log.d(LOG_TAG, "Positive button clicked. ReasonCode: $reasonCode")
+        }
         when (reasonCode) {
             InstallUserActionRequired.USER_ACTION_REASON_ANONYMOUS_SOURCE ->
                 installViewModel!!.forcedSkipSourceCheck()
@@ -269,6 +271,9 @@
     }
 
     override fun onNegativeResponse(stageCode: Int) {
+        if (localLogv) {
+            Log.d(LOG_TAG, "Negative button clicked. StageCode: $stageCode")
+        }
         if (stageCode == InstallStage.STAGE_USER_ACTION_REQUIRED) {
             installViewModel!!.cleanupInstall()
         }
@@ -276,10 +281,16 @@
     }
 
     override fun onNegativeResponse(resultCode: Int, data: Intent?) {
+        if (localLogv) {
+            Log.d(LOG_TAG, "Negative button clicked. resultCode: $resultCode; Intent: $data")
+        }
         setResult(resultCode, data, true)
     }
 
     override fun sendUnknownAppsIntent(sourcePackageName: String) {
+        if (localLogv) {
+            Log.d(LOG_TAG, "Launching unknown-apps settings intent for $sourcePackageName")
+        }
         val settingsIntent = Intent()
         settingsIntent.setAction(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
         val packageUri = Uri.parse("package:$sourcePackageName")
@@ -299,6 +310,9 @@
     }
 
     override fun openInstalledApp(intent: Intent?) {
+        if (localLogv) {
+            Log.d(LOG_TAG, "Opening $intent")
+        }
         setResult(Activity.RESULT_OK, intent, true)
         if (intent != null && intent.hasCategory(Intent.CATEGORY_LAUNCHER)) {
             startActivity(intent)
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/UninstallLaunch.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/UninstallLaunch.kt
index 0050c7e..c4ca272 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/UninstallLaunch.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/UninstallLaunch.kt
@@ -28,6 +28,7 @@
 import androidx.fragment.app.FragmentActivity
 import androidx.fragment.app.FragmentManager
 import androidx.lifecycle.ViewModelProvider
+import com.android.packageinstaller.v2.model.PackageUtil.localLogv
 import com.android.packageinstaller.v2.model.UninstallAborted
 import com.android.packageinstaller.v2.model.UninstallFailed
 import com.android.packageinstaller.v2.model.UninstallRepository
@@ -159,11 +160,17 @@
     }
 
     override fun onPositiveResponse(keepData: Boolean) {
+        if (localLogv) {
+            Log.d(LOG_TAG, "Staring uninstall")
+        }
         uninstallViewModel!!.initiateUninstall(keepData)
     }
 
     override fun onNegativeResponse() {
-        uninstallViewModel!!.cancelInstall()
+        if (localLogv) {
+            Log.d(LOG_TAG, "Cancelling uninstall")
+        }
+        uninstallViewModel!!.cancelUninstall()
         setResult(Activity.RESULT_FIRST_USER, null, true)
     }
 }
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/AnonymousSourceFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/AnonymousSourceFragment.java
index b29cb2a..cc40b0c 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/AnonymousSourceFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/AnonymousSourceFragment.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
+import android.util.Log;
 import androidx.annotation.NonNull;
 import androidx.fragment.app.DialogFragment;
 import com.android.packageinstaller.R;
@@ -33,7 +34,7 @@
  */
 public class AnonymousSourceFragment extends DialogFragment {
 
-    public static String TAG = AnonymousSourceFragment.class.getSimpleName();
+    public static final String LOG_TAG = AnonymousSourceFragment.class.getSimpleName();
     @NonNull
     private InstallActionListener mInstallActionListener;
     @NonNull
@@ -48,7 +49,8 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
-       mDialog = new AlertDialog.Builder(requireContext())
+        Log.i(LOG_TAG, "Creating " + LOG_TAG);
+        mDialog = new AlertDialog.Builder(requireContext())
             .setMessage(R.string.anonymous_source_warning)
             .setPositiveButton(R.string.anonymous_source_continue,
                 ((dialog, which) -> mInstallActionListener.onPositiveResponse(
@@ -56,7 +58,7 @@
             .setNegativeButton(R.string.cancel,
                 ((dialog, which) -> mInstallActionListener.onNegativeResponse(
                     InstallStage.STAGE_USER_ACTION_REQUIRED))).create();
-       return mDialog;
+        return mDialog;
     }
 
     @Override
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java
index 2314d6b..a95137d 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ExternalSourcesBlockedFragment.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
+import android.util.Log;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.fragment.app.DialogFragment;
@@ -34,7 +35,7 @@
  */
 public class ExternalSourcesBlockedFragment extends DialogFragment {
 
-    private final String TAG = ExternalSourcesBlockedFragment.class.getSimpleName();
+    private static final String LOG_TAG = ExternalSourcesBlockedFragment.class.getSimpleName();
     @NonNull
     private final InstallUserActionRequired mDialogData;
     @NonNull
@@ -55,6 +56,7 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        Log.i(LOG_TAG, "Creating " + LOG_TAG + "\n" + mDialogData);
         mDialog = new AlertDialog.Builder(requireContext())
             .setTitle(mDialogData.getAppLabel())
             .setIcon(mDialogData.getAppIcon())
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java
index 0a4aa48..99b1eec 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallConfirmationFragment.java
@@ -23,6 +23,7 @@
 import android.os.Bundle;
 import android.text.Html;
 import android.text.method.ScrollingMovementMethod;
+import android.util.Log;
 import android.view.View;
 import android.widget.TextView;
 import androidx.annotation.NonNull;
@@ -37,8 +38,7 @@
  */
 public class InstallConfirmationFragment extends DialogFragment {
 
-    public static String TAG = InstallConfirmationFragment.class.getSimpleName();
-
+    public static final String LOG_TAG = InstallConfirmationFragment.class.getSimpleName();
     @NonNull
     private final InstallUserActionRequired mDialogData;
     @NonNull
@@ -59,6 +59,7 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        Log.i(LOG_TAG, "Creating " + LOG_TAG + "\n" + mDialogData);
         View dialogView = getLayoutInflater().inflate(R.layout.install_content_view, null);
 
         int positiveBtnTextRes;
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallFailedFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallFailedFragment.java
index 4667a7a..7c9d98d 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallFailedFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallFailedFragment.java
@@ -38,7 +38,7 @@
  */
 public class InstallFailedFragment extends DialogFragment {
 
-    private static final String TAG = InstallFailedFragment.class.getSimpleName();
+    private static final String LOG_TAG = InstallFailedFragment.class.getSimpleName();
     private final InstallFailed mDialogData;
     private InstallActionListener mInstallActionListener;
 
@@ -55,6 +55,7 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        Log.i(LOG_TAG, "Creating " + LOG_TAG + "\n" + mDialogData);
         View dialogView = getLayoutInflater().inflate(R.layout.install_content_view, null);
         AlertDialog dialog = new AlertDialog.Builder(requireContext())
             .setTitle(mDialogData.getAppLabel())
@@ -75,7 +76,7 @@
      * @param statusCode The status code from the package installer.
      */
     private void setExplanationFromErrorCode(int statusCode, View dialogView) {
-        Log.d(TAG, "Installation status code: " + statusCode);
+        Log.i(LOG_TAG, "Installation status code: " + statusCode);
 
         View viewToEnable;
         switch (statusCode) {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallInstallingFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallInstallingFragment.java
index 7327b5d..27210b7 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallInstallingFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallInstallingFragment.java
@@ -20,6 +20,7 @@
 import android.app.Dialog;
 import android.content.DialogInterface;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.View;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -32,6 +33,7 @@
  */
 public class InstallInstallingFragment extends DialogFragment {
 
+    private static final String LOG_TAG = InstallInstallingFragment.class.getSimpleName();
     private final InstallInstalling mDialogData;
     private AlertDialog mDialog;
 
@@ -42,6 +44,7 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        Log.i(LOG_TAG, "Creating " + LOG_TAG + "\n" + mDialogData);
         View dialogView = getLayoutInflater().inflate(R.layout.install_content_view, null);
         mDialog = new AlertDialog.Builder(requireContext())
             .setTitle(mDialogData.getAppLabel())
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallStagingFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallStagingFragment.java
index feb2428..3cab96b 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallStagingFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallStagingFragment.java
@@ -20,6 +20,7 @@
 import android.app.Dialog;
 import android.content.DialogInterface;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.View;
 import android.widget.ProgressBar;
 import androidx.annotation.NonNull;
@@ -29,13 +30,14 @@
 
 public class InstallStagingFragment extends DialogFragment {
 
-    private static final String TAG = InstallStagingFragment.class.getSimpleName();
+    private static final String LOG_TAG = InstallStagingFragment.class.getSimpleName();
     private ProgressBar mProgressBar;
     private AlertDialog mDialog;
 
     @NonNull
     @Override
     public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        Log.i(LOG_TAG, "Creating " + LOG_TAG);
         View dialogView = getLayoutInflater().inflate(R.layout.install_content_view, null);
         dialogView.requireViewById(R.id.staging).setVisibility(View.VISIBLE);
 
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallSuccessFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallSuccessFragment.java
index e491f9c..28b5423b 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallSuccessFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/InstallSuccessFragment.java
@@ -60,6 +60,7 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        Log.i(LOG_TAG, "Creating " + LOG_TAG + "\n" + mDialogData);
         View dialogView = getLayoutInflater().inflate(R.layout.install_content_view, null);
         mDialog = new AlertDialog.Builder(requireContext())
             .setTitle(mDialogData.getAppLabel())
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ParseErrorFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ParseErrorFragment.java
index 68d48d6..cde3d8d 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ParseErrorFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/ParseErrorFragment.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
+import android.util.Log;
 import androidx.annotation.NonNull;
 import androidx.fragment.app.DialogFragment;
 import com.android.packageinstaller.R;
@@ -29,7 +30,7 @@
 
 public class ParseErrorFragment extends DialogFragment {
 
-    private static final String TAG = ParseErrorFragment.class.getSimpleName();
+    private static final String LOG_TAG = ParseErrorFragment.class.getSimpleName();
     private final InstallAborted mDialogData;
     private InstallActionListener mInstallActionListener;
 
@@ -46,7 +47,8 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
-        return new AlertDialog.Builder(getActivity())
+        Log.i(LOG_TAG, "Creating " + LOG_TAG + "\n" + mDialogData);
+        return new AlertDialog.Builder(requireContext())
             .setMessage(R.string.Parse_error_dlg_text)
             .setPositiveButton(R.string.ok,
                 (dialog, which) ->
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/SimpleErrorFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/SimpleErrorFragment.java
index 58b8b2d..66a353a 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/SimpleErrorFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/SimpleErrorFragment.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
+import android.util.Log;
 import androidx.annotation.NonNull;
 import androidx.fragment.app.DialogFragment;
 import com.android.packageinstaller.R;
@@ -29,7 +30,7 @@
 
 public class SimpleErrorFragment extends DialogFragment {
 
-    private static final String TAG = SimpleErrorFragment.class.getSimpleName();
+    private static final String LOG_TAG = SimpleErrorFragment.class.getSimpleName();
     private final int mMessageResId;
     private InstallActionListener mInstallActionListener;
 
@@ -46,7 +47,9 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
-        return new AlertDialog.Builder(getActivity())
+        Log.i(LOG_TAG, "Creating " + LOG_TAG + "\n" +
+            "Dialog message: " + requireContext().getString(mMessageResId));
+        return new AlertDialog.Builder(requireContext())
             .setMessage(mMessageResId)
             .setPositiveButton(R.string.ok,
                 (dialog, which) ->
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallConfirmationFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallConfirmationFragment.java
index 32ac4a6..87af1ae 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallConfirmationFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallConfirmationFragment.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.View;
 import android.widget.CheckBox;
 import android.widget.TextView;
@@ -37,7 +38,7 @@
  * Dialog to show while requesting user confirmation for uninstalling an app.
  */
 public class UninstallConfirmationFragment extends DialogFragment {
-
+    private static final String LOG_TAG = UninstallConfirmationFragment.class.getSimpleName();
     private final UninstallUserActionRequired mDialogData;
     private UninstallActionListener mUninstallActionListener;
 
@@ -56,6 +57,7 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        Log.i(LOG_TAG, "Creating " + LOG_TAG + "\n" + mDialogData);
         AlertDialog.Builder builder = new AlertDialog.Builder(requireContext())
             .setTitle(mDialogData.getTitle())
             .setPositiveButton(R.string.ok,
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallErrorFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallErrorFragment.java
index eb7183d..51e16cb 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallErrorFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallErrorFragment.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
+import android.util.Log;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.fragment.app.DialogFragment;
@@ -33,6 +34,7 @@
  */
 public class UninstallErrorFragment extends DialogFragment {
 
+    private static final String LOG_TAG = UninstallErrorFragment.class.getSimpleName();
     private final UninstallAborted mDialogData;
     private UninstallActionListener mUninstallActionListener;
 
@@ -49,6 +51,7 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        Log.i(LOG_TAG, "Creating " + LOG_TAG + "\n" + mDialogData);
         AlertDialog.Builder builder = new AlertDialog.Builder(requireContext())
             .setMessage(mDialogData.getDialogTextResource())
             .setNegativeButton(R.string.ok,
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallUninstallingFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallUninstallingFragment.java
index 835efc6..626ff6b 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallUninstallingFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/ui/fragments/UninstallUninstallingFragment.java
@@ -19,6 +19,7 @@
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.os.Bundle;
+import android.util.Log;
 import androidx.annotation.NonNull;
 import androidx.fragment.app.DialogFragment;
 import com.android.packageinstaller.R;
@@ -29,6 +30,7 @@
  */
 public class UninstallUninstallingFragment extends DialogFragment {
 
+    private static final String LOG_TAG = UninstallUninstallingFragment.class.getSimpleName();
     UninstallUninstalling mDialogData;
 
     public UninstallUninstallingFragment(UninstallUninstalling dialogData) {
@@ -38,6 +40,7 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(Bundle savedInstanceState) {
+        Log.i(LOG_TAG, "Creating " + LOG_TAG + "\n" + mDialogData);
         AlertDialog.Builder builder = new AlertDialog.Builder(requireContext())
             .setCancelable(false);
         if (mDialogData.isCloneUser()) {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/v2/viewmodel/UninstallViewModel.kt b/packages/PackageInstaller/src/com/android/packageinstaller/v2/viewmodel/UninstallViewModel.kt
index 80886e9..3081d7d 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/v2/viewmodel/UninstallViewModel.kt
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/v2/viewmodel/UninstallViewModel.kt
@@ -56,7 +56,7 @@
         }
     }
 
-    fun cancelInstall() {
-        repository.cancelInstall()
+    fun cancelUninstall() {
+        repository.cancelUninstall()
     }
 }
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallTask.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallTask.java
deleted file mode 100644
index 53a460d..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallTask.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.packageinstaller.wear;
-
-import android.content.Context;
-import android.content.IntentSender;
-import android.content.pm.PackageInstaller;
-import android.os.Looper;
-import android.os.ParcelFileDescriptor;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Task that installs an APK. This must not be called on the main thread.
- * This code is based off the Finsky/Wearsky implementation
- */
-public class InstallTask {
-    private static final String TAG = "InstallTask";
-
-    private static final int DEFAULT_BUFFER_SIZE = 8192;
-
-    private final Context mContext;
-    private String mPackageName;
-    private ParcelFileDescriptor mParcelFileDescriptor;
-    private PackageInstallerImpl.InstallListener mCallback;
-    private PackageInstaller.Session mSession;
-    private IntentSender mCommitCallback;
-
-    private Exception mException = null;
-    private int mErrorCode = 0;
-    private String mErrorDesc = null;
-
-    public InstallTask(Context context, String packageName,
-            ParcelFileDescriptor parcelFileDescriptor,
-            PackageInstallerImpl.InstallListener callback, PackageInstaller.Session session,
-            IntentSender commitCallback) {
-        mContext = context;
-        mPackageName = packageName;
-        mParcelFileDescriptor = parcelFileDescriptor;
-        mCallback = callback;
-        mSession = session;
-        mCommitCallback = commitCallback;
-    }
-
-    public boolean isError() {
-        return mErrorCode != InstallerConstants.STATUS_SUCCESS || !TextUtils.isEmpty(mErrorDesc);
-    }
-
-    public void execute() {
-        if (Looper.myLooper() == Looper.getMainLooper()) {
-            throw new IllegalStateException("This method cannot be called from the UI thread.");
-        }
-
-        OutputStream sessionStream = null;
-        try {
-            sessionStream = mSession.openWrite(mPackageName, 0, -1);
-
-            // 2b: Stream the asset to the installer. Note:
-            // Note: writeToOutputStreamFromAsset() always safely closes the input stream
-            writeToOutputStreamFromAsset(sessionStream);
-            mSession.fsync(sessionStream);
-        } catch (Exception e) {
-            mException = e;
-            mErrorCode = InstallerConstants.ERROR_INSTALL_COPY_STREAM;
-            mErrorDesc = "Could not write to stream";
-        } finally {
-            if (sessionStream != null) {
-                // 2c: close output stream
-                try {
-                    sessionStream.close();
-                } catch (Exception e) {
-                    // Ignore otherwise
-                    if (mException == null) {
-                        mException = e;
-                        mErrorCode = InstallerConstants.ERROR_INSTALL_CLOSE_STREAM;
-                        mErrorDesc = "Could not close session stream";
-                    }
-                }
-            }
-        }
-
-        if (mErrorCode != InstallerConstants.STATUS_SUCCESS) {
-            // An error occurred, we're done
-            Log.e(TAG, "Exception while installing " + mPackageName + ": " + mErrorCode + ", "
-                    + mErrorDesc + ", " + mException);
-            mSession.close();
-            mCallback.installFailed(mErrorCode, "[" + mPackageName + "]" + mErrorDesc);
-        } else {
-            // 3. Commit the session (this actually installs it.)  Session map
-            // will be cleaned up in the callback.
-            mCallback.installBeginning();
-            mSession.commit(mCommitCallback);
-            mSession.close();
-        }
-    }
-
-    /**
-     * {@code PackageInstaller} works with streams. Get the {@code FileDescriptor}
-     * corresponding to the {@code Asset} and then write the contents into an
-     * {@code OutputStream} that is passed in.
-     * <br>
-     * The {@code FileDescriptor} is closed but the {@code OutputStream} is not closed.
-     */
-    private boolean writeToOutputStreamFromAsset(OutputStream outputStream) {
-        if (outputStream == null) {
-            mErrorCode = InstallerConstants.ERROR_INSTALL_COPY_STREAM_EXCEPTION;
-            mErrorDesc = "Got a null OutputStream.";
-            return false;
-        }
-
-        if (mParcelFileDescriptor == null || mParcelFileDescriptor.getFileDescriptor() == null)  {
-            mErrorCode = InstallerConstants.ERROR_COULD_NOT_GET_FD;
-            mErrorDesc = "Could not get FD";
-            return false;
-        }
-
-        InputStream inputStream = null;
-        try {
-            byte[] inputBuf = new byte[DEFAULT_BUFFER_SIZE];
-            int bytesRead;
-            inputStream = new ParcelFileDescriptor.AutoCloseInputStream(mParcelFileDescriptor);
-
-            while ((bytesRead = inputStream.read(inputBuf)) > -1) {
-                if (bytesRead > 0) {
-                    outputStream.write(inputBuf, 0, bytesRead);
-                }
-            }
-
-            outputStream.flush();
-        } catch (IOException e) {
-            mErrorCode = InstallerConstants.ERROR_INSTALL_APK_COPY_FAILURE;
-            mErrorDesc = "Reading from Asset FD or writing to temp file failed: " + e;
-            return false;
-        } finally {
-            safeClose(inputStream);
-        }
-
-        return true;
-    }
-
-    /**
-     * Quietly close a closeable resource (e.g. a stream or file). The input may already
-     * be closed and it may even be null.
-     */
-    public static void safeClose(Closeable resource) {
-        if (resource != null) {
-            try {
-                resource.close();
-            } catch (IOException ioe) {
-                // Catch and discard the error
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallerConstants.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallerConstants.java
deleted file mode 100644
index 3daf3d8..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallerConstants.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.packageinstaller.wear;
-
-/**
- * Constants for Installation / Uninstallation requests.
- * Using the same values as Finsky/Wearsky code for consistency in user analytics of failures
- */
-public class InstallerConstants {
-    /** Request succeeded */
-    public static final int STATUS_SUCCESS = 0;
-
-    /**
-     * The new PackageInstaller also returns a small set of less granular error codes, which
-     * we'll remap to the range -500 and below to keep away from existing installer codes
-     * (which run from -1 to -110).
-     */
-    public final static int ERROR_PACKAGEINSTALLER_BASE = -500;
-
-    public static final int ERROR_COULD_NOT_GET_FD = -603;
-    /** This node is not targeted by this request. */
-
-    /** The install did not complete because could not create PackageInstaller session */
-    public final static int ERROR_INSTALL_CREATE_SESSION = -612;
-    /** The install did not complete because could not open PackageInstaller session  */
-    public final static int ERROR_INSTALL_OPEN_SESSION = -613;
-    /** The install did not complete because could not open PackageInstaller output stream */
-    public final static int ERROR_INSTALL_OPEN_STREAM = -614;
-    /** The install did not complete because of an exception while streaming bytes */
-    public final static int ERROR_INSTALL_COPY_STREAM_EXCEPTION = -615;
-    /** The install did not complete because of an unexpected exception from PackageInstaller */
-    public final static int ERROR_INSTALL_SESSION_EXCEPTION = -616;
-    /** The install did not complete because of an unexpected userActionRequired callback */
-    public final static int ERROR_INSTALL_USER_ACTION_REQUIRED = -617;
-    /** The install did not complete because of an unexpected broadcast (missing fields) */
-    public final static int ERROR_INSTALL_MALFORMED_BROADCAST = -618;
-    /** The install did not complete because of an error while copying from downloaded file */
-    public final static int ERROR_INSTALL_APK_COPY_FAILURE = -619;
-    /** The install did not complete because of an error while copying to the PackageInstaller
-     * output stream */
-    public final static int ERROR_INSTALL_COPY_STREAM = -620;
-    /** The install did not complete because of an error while closing the PackageInstaller
-     * output stream */
-    public final static int ERROR_INSTALL_CLOSE_STREAM = -621;
-}
\ No newline at end of file
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerFactory.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerFactory.java
deleted file mode 100644
index bdc22cf..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerFactory.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.packageinstaller.wear;
-
-import android.content.Context;
-
-/**
- * Factory that creates a Package Installer.
- */
-public class PackageInstallerFactory {
-    private static PackageInstallerImpl sPackageInstaller;
-
-    /**
-     * Return the PackageInstaller shared object. {@code init} should have already been called.
-     */
-    public synchronized static PackageInstallerImpl getPackageInstaller(Context context) {
-        if (sPackageInstaller == null) {
-            sPackageInstaller = new PackageInstallerImpl(context);
-        }
-        return sPackageInstaller;
-    }
-}
\ No newline at end of file
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java
deleted file mode 100644
index 1e37f15..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.packageinstaller.wear;
-
-import android.annotation.TargetApi;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.pm.PackageInstaller;
-import android.os.Build;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Implementation of package manager installation using modern PackageInstaller api.
- *
- * Heavily copied from Wearsky/Finsky implementation
- */
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
-public class PackageInstallerImpl {
-    private static final String TAG = "PackageInstallerImpl";
-
-    /** Intent actions used for broadcasts from PackageInstaller back to the local receiver */
-    private static final String ACTION_INSTALL_COMMIT =
-            "com.android.vending.INTENT_PACKAGE_INSTALL_COMMIT";
-
-    private final Context mContext;
-    private final PackageInstaller mPackageInstaller;
-    private final Map<String, PackageInstaller.SessionInfo> mSessionInfoMap;
-    private final Map<String, PackageInstaller.Session> mOpenSessionMap;
-
-    public PackageInstallerImpl(Context context) {
-        mContext = context.getApplicationContext();
-        mPackageInstaller = mContext.getPackageManager().getPackageInstaller();
-
-        // Capture a map of known sessions
-        // This list will be pruned a bit later (stale sessions will be canceled)
-        mSessionInfoMap = new HashMap<String, PackageInstaller.SessionInfo>();
-        List<PackageInstaller.SessionInfo> mySessions = mPackageInstaller.getMySessions();
-        for (int i = 0; i < mySessions.size(); i++) {
-            PackageInstaller.SessionInfo sessionInfo = mySessions.get(i);
-            String packageName = sessionInfo.getAppPackageName();
-            PackageInstaller.SessionInfo oldInfo = mSessionInfoMap.put(packageName, sessionInfo);
-
-            // Checking for old info is strictly for logging purposes
-            if (oldInfo != null) {
-                Log.w(TAG, "Multiple sessions for " + packageName + " found. Removing " + oldInfo
-                        .getSessionId() + " & keeping " + mySessions.get(i).getSessionId());
-            }
-        }
-        mOpenSessionMap = new HashMap<String, PackageInstaller.Session>();
-    }
-
-    /**
-     * This callback will be made after an installation attempt succeeds or fails.
-     */
-    public interface InstallListener {
-        /**
-         * This callback signals that preflight checks have succeeded and installation
-         * is beginning.
-         */
-        void installBeginning();
-
-        /**
-         * This callback signals that installation has completed.
-         */
-        void installSucceeded();
-
-        /**
-         * This callback signals that installation has failed.
-         */
-        void installFailed(int errorCode, String errorDesc);
-    }
-
-    /**
-     * This is a placeholder implementation that bundles an entire "session" into a single
-     * call. This will be replaced by more granular versions that allow longer session lifetimes,
-     * download progress tracking, etc.
-     *
-     * This must not be called on main thread.
-     */
-    public void install(final String packageName, ParcelFileDescriptor parcelFileDescriptor,
-            final InstallListener callback) {
-        // 0. Generic try/catch block because I am not really sure what exceptions (other than
-        // IOException) might be thrown by PackageInstaller and I want to handle them
-        // at least slightly gracefully.
-        try {
-            // 1. Create or recover a session, and open it
-            // Try recovery first
-            PackageInstaller.Session session = null;
-            PackageInstaller.SessionInfo sessionInfo = mSessionInfoMap.get(packageName);
-            if (sessionInfo != null) {
-                // See if it's openable, or already held open
-                session = getSession(packageName);
-            }
-            // If open failed, or there was no session, create a new one and open it.
-            // If we cannot create or open here, the failure is terminal.
-            if (session == null) {
-                try {
-                    innerCreateSession(packageName);
-                } catch (IOException ioe) {
-                    Log.e(TAG, "Can't create session for " + packageName + ": " + ioe.getMessage());
-                    callback.installFailed(InstallerConstants.ERROR_INSTALL_CREATE_SESSION,
-                            "Could not create session");
-                    mSessionInfoMap.remove(packageName);
-                    return;
-                }
-                sessionInfo = mSessionInfoMap.get(packageName);
-                try {
-                    session = mPackageInstaller.openSession(sessionInfo.getSessionId());
-                    mOpenSessionMap.put(packageName, session);
-                } catch (SecurityException se) {
-                    Log.e(TAG, "Can't open session for " + packageName + ": " + se.getMessage());
-                    callback.installFailed(InstallerConstants.ERROR_INSTALL_OPEN_SESSION,
-                            "Can't open session");
-                    mSessionInfoMap.remove(packageName);
-                    return;
-                }
-            }
-
-            // 2. Launch task to handle file operations.
-            InstallTask task = new InstallTask( mContext, packageName, parcelFileDescriptor,
-                    callback, session,
-                    getCommitCallback(packageName, sessionInfo.getSessionId(), callback));
-            task.execute();
-            if (task.isError()) {
-                cancelSession(sessionInfo.getSessionId(), packageName);
-            }
-        } catch (Exception e) {
-            Log.e(TAG, "Unexpected exception while installing: " + packageName + ": "
-                    + e.getMessage());
-            callback.installFailed(InstallerConstants.ERROR_INSTALL_SESSION_EXCEPTION,
-                    "Unexpected exception while installing " + packageName);
-        }
-    }
-
-    /**
-     * Retrieve an existing session. Will open if needed, but does not attempt to create.
-     */
-    private PackageInstaller.Session getSession(String packageName) {
-        // Check for already-open session
-        PackageInstaller.Session session = mOpenSessionMap.get(packageName);
-        if (session != null) {
-            try {
-                // Probe the session to ensure that it's still open. This may or may not
-                // throw (if non-open), but it may serve as a canary for stale sessions.
-                session.getNames();
-                return session;
-            } catch (IOException ioe) {
-                Log.e(TAG, "Stale open session for " + packageName + ": " + ioe.getMessage());
-                mOpenSessionMap.remove(packageName);
-            } catch (SecurityException se) {
-                Log.e(TAG, "Stale open session for " + packageName + ": " + se.getMessage());
-                mOpenSessionMap.remove(packageName);
-            }
-        }
-        // Check to see if this is a known session
-        PackageInstaller.SessionInfo sessionInfo = mSessionInfoMap.get(packageName);
-        if (sessionInfo == null) {
-            return null;
-        }
-        // Try to open it. If we fail here, assume that the SessionInfo was stale.
-        try {
-            session = mPackageInstaller.openSession(sessionInfo.getSessionId());
-        } catch (SecurityException se) {
-            Log.w(TAG, "SessionInfo was stale for " + packageName + " - deleting info");
-            mSessionInfoMap.remove(packageName);
-            return null;
-        } catch (IOException ioe) {
-            Log.w(TAG, "IOException opening old session for " + ioe.getMessage()
-                    + " - deleting info");
-            mSessionInfoMap.remove(packageName);
-            return null;
-        }
-        mOpenSessionMap.put(packageName, session);
-        return session;
-    }
-
-    /** This version throws an IOException when the session cannot be created */
-    private void innerCreateSession(String packageName) throws IOException {
-        if (mSessionInfoMap.containsKey(packageName)) {
-            Log.w(TAG, "Creating session for " + packageName + " when one already exists");
-            return;
-        }
-        PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
-                PackageInstaller.SessionParams.MODE_FULL_INSTALL);
-        params.setAppPackageName(packageName);
-
-        // IOException may be thrown at this point
-        int sessionId = mPackageInstaller.createSession(params);
-        PackageInstaller.SessionInfo sessionInfo = mPackageInstaller.getSessionInfo(sessionId);
-        mSessionInfoMap.put(packageName, sessionInfo);
-    }
-
-    /**
-     * Cancel a session based on its sessionId. Package name is for logging only.
-     */
-    private void cancelSession(int sessionId, String packageName) {
-        // Close if currently held open
-        closeSession(packageName);
-        // Remove local record
-        mSessionInfoMap.remove(packageName);
-        try {
-            mPackageInstaller.abandonSession(sessionId);
-        } catch (SecurityException se) {
-            // The session no longer exists, so we can exit quietly.
-            return;
-        }
-    }
-
-    /**
-     * Close a session if it happens to be held open.
-     */
-    private void closeSession(String packageName) {
-        PackageInstaller.Session session = mOpenSessionMap.remove(packageName);
-        if (session != null) {
-            // Unfortunately close() is not idempotent. Try our best to make this safe.
-            try {
-                session.close();
-            } catch (Exception e) {
-                Log.w(TAG, "Unexpected error closing session for " + packageName + ": "
-                        + e.getMessage());
-            }
-        }
-    }
-
-    /**
-     * Creates a commit callback for the package install that's underway. This will be called
-     * some time after calling session.commit() (above).
-     */
-    private IntentSender getCommitCallback(final String packageName, final int sessionId,
-            final InstallListener callback) {
-        // Create a single-use broadcast receiver
-        BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                mContext.unregisterReceiver(this);
-                handleCommitCallback(intent, packageName, sessionId, callback);
-            }
-        };
-        // Create a matching intent-filter and register the receiver
-        String action = ACTION_INSTALL_COMMIT + "." + packageName;
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(action);
-        mContext.registerReceiver(broadcastReceiver, intentFilter,
-                Context.RECEIVER_EXPORTED);
-
-        // Create a matching PendingIntent and use it to generate the IntentSender
-        Intent broadcastIntent = new Intent(action).setPackage(mContext.getPackageName());
-        PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, packageName.hashCode(),
-                broadcastIntent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT
-                        | PendingIntent.FLAG_MUTABLE);
-        return pendingIntent.getIntentSender();
-    }
-
-    /**
-     * Examine the extras to determine information about the package update/install, decode
-     * the result, and call the appropriate callback.
-     *
-     * @param intent The intent, which the PackageInstaller will have added Extras to
-     * @param packageName The package name we created the receiver for
-     * @param sessionId The session Id we created the receiver for
-     * @param callback The callback to report success/failure to
-     */
-    private void handleCommitCallback(Intent intent, String packageName, int sessionId,
-            InstallListener callback) {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "Installation of " + packageName + " finished with extras "
-                    + intent.getExtras());
-        }
-        String statusMessage = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE);
-        int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, Integer.MIN_VALUE);
-        if (status == PackageInstaller.STATUS_SUCCESS) {
-            cancelSession(sessionId, packageName);
-            callback.installSucceeded();
-        } else if (status == -1 /*PackageInstaller.STATUS_USER_ACTION_REQUIRED*/) {
-            // TODO - use the constant when the correct/final name is in the SDK
-            // TODO This is unexpected, so we are treating as failure for now
-            cancelSession(sessionId, packageName);
-            callback.installFailed(InstallerConstants.ERROR_INSTALL_USER_ACTION_REQUIRED,
-                    "Unexpected: user action required");
-        } else {
-            cancelSession(sessionId, packageName);
-            int errorCode = getPackageManagerErrorCode(status);
-            Log.e(TAG, "Error " + errorCode + " while installing " + packageName + ": "
-                    + statusMessage);
-            callback.installFailed(errorCode, null);
-        }
-    }
-
-    private int getPackageManagerErrorCode(int status) {
-        // This is a hack: because PackageInstaller now reports error codes
-        // with small positive values, we need to remap them into a space
-        // that is more compatible with the existing package manager error codes.
-        // See https://sites.google.com/a/google.com/universal-store/documentation
-        //       /android-client/download-error-codes
-        int errorCode;
-        if (status == Integer.MIN_VALUE) {
-            errorCode = InstallerConstants.ERROR_INSTALL_MALFORMED_BROADCAST;
-        } else {
-            errorCode = InstallerConstants.ERROR_PACKAGEINSTALLER_BASE - status;
-        }
-        return errorCode;
-    }
-}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageArgs.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageArgs.java
deleted file mode 100644
index 2c289b2..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageArgs.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.packageinstaller.wear;
-
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-
-/**
- * Installation Util that contains a list of parameters that are needed for
- * installing/uninstalling.
- */
-public class WearPackageArgs {
-    private static final String KEY_PACKAGE_NAME =
-            "com.google.android.clockwork.EXTRA_PACKAGE_NAME";
-    private static final String KEY_ASSET_URI =
-            "com.google.android.clockwork.EXTRA_ASSET_URI";
-    private static final String KEY_START_ID =
-            "com.google.android.clockwork.EXTRA_START_ID";
-    private static final String KEY_PERM_URI =
-            "com.google.android.clockwork.EXTRA_PERM_URI";
-    private static final String KEY_CHECK_PERMS =
-            "com.google.android.clockwork.EXTRA_CHECK_PERMS";
-    private static final String KEY_SKIP_IF_SAME_VERSION =
-            "com.google.android.clockwork.EXTRA_SKIP_IF_SAME_VERSION";
-    private static final String KEY_COMPRESSION_ALG =
-            "com.google.android.clockwork.EXTRA_KEY_COMPRESSION_ALG";
-    private static final String KEY_COMPANION_SDK_VERSION =
-            "com.google.android.clockwork.EXTRA_KEY_COMPANION_SDK_VERSION";
-    private static final String KEY_COMPANION_DEVICE_VERSION =
-            "com.google.android.clockwork.EXTRA_KEY_COMPANION_DEVICE_VERSION";
-    private static final String KEY_SHOULD_CHECK_GMS_DEPENDENCY =
-            "com.google.android.clockwork.EXTRA_KEY_SHOULD_CHECK_GMS_DEPENDENCY";
-    private static final String KEY_SKIP_IF_LOWER_VERSION =
-            "com.google.android.clockwork.EXTRA_SKIP_IF_LOWER_VERSION";
-
-    public static String getPackageName(Bundle b) {
-        return b.getString(KEY_PACKAGE_NAME);
-    }
-
-    public static Bundle setPackageName(Bundle b, String packageName) {
-        b.putString(KEY_PACKAGE_NAME, packageName);
-        return b;
-    }
-
-    public static Uri getAssetUri(Bundle b) {
-        return b.getParcelable(KEY_ASSET_URI);
-    }
-
-    public static Uri getPermUri(Bundle b) {
-        return b.getParcelable(KEY_PERM_URI);
-    }
-
-    public static boolean checkPerms(Bundle b) {
-        return b.getBoolean(KEY_CHECK_PERMS);
-    }
-
-    public static boolean skipIfSameVersion(Bundle b) {
-        return b.getBoolean(KEY_SKIP_IF_SAME_VERSION);
-    }
-
-    public static int getCompanionSdkVersion(Bundle b) {
-        return b.getInt(KEY_COMPANION_SDK_VERSION);
-    }
-
-    public static int getCompanionDeviceVersion(Bundle b) {
-        return b.getInt(KEY_COMPANION_DEVICE_VERSION);
-    }
-
-    public static String getCompressionAlg(Bundle b) {
-        return b.getString(KEY_COMPRESSION_ALG);
-    }
-
-    public static int getStartId(Bundle b) {
-        return b.getInt(KEY_START_ID);
-    }
-
-    public static boolean skipIfLowerVersion(Bundle b) {
-        return b.getBoolean(KEY_SKIP_IF_LOWER_VERSION, false);
-    }
-
-    public static Bundle setStartId(Bundle b, int startId) {
-        b.putInt(KEY_START_ID, startId);
-        return b;
-    }
-}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageIconProvider.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageIconProvider.java
deleted file mode 100644
index 02b9d29..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageIconProvider.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.packageinstaller.wear;
-
-import android.annotation.TargetApi;
-import android.app.ActivityManager;
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.Build;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.List;
-
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-
-public class WearPackageIconProvider extends ContentProvider {
-    private static final String TAG = "WearPackageIconProvider";
-    public static final String AUTHORITY = "com.google.android.packageinstaller.wear.provider";
-
-    private static final String REQUIRED_PERMISSION =
-            "com.google.android.permission.INSTALL_WEARABLE_PACKAGES";
-
-    /** MIME types. */
-    public static final String ICON_TYPE = "vnd.android.cursor.item/cw_package_icon";
-
-    @Override
-    public boolean onCreate() {
-        return true;
-    }
-
-    @Override
-    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
-            String sortOrder) {
-        throw new UnsupportedOperationException("Query is not supported.");
-    }
-
-    @Override
-    public String getType(Uri uri) {
-        if (uri == null) {
-            throw new IllegalArgumentException("URI passed in is null.");
-        }
-
-        if (AUTHORITY.equals(uri.getEncodedAuthority())) {
-            return ICON_TYPE;
-        }
-        return null;
-    }
-
-    @Override
-    public Uri insert(Uri uri, ContentValues values) {
-        throw new UnsupportedOperationException("Insert is not supported.");
-    }
-
-    @Override
-    public int delete(Uri uri, String selection, String[] selectionArgs) {
-        if (uri == null) {
-            throw new IllegalArgumentException("URI passed in is null.");
-        }
-
-        enforcePermissions(uri);
-
-        if (ICON_TYPE.equals(getType(uri))) {
-            final File file = WearPackageUtil.getIconFile(
-                    this.getContext().getApplicationContext(), getPackageNameFromUri(uri));
-            if (file != null) {
-                file.delete();
-            }
-        }
-
-        return 0;
-    }
-
-    @Override
-    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-        throw new UnsupportedOperationException("Update is not supported.");
-    }
-
-    @Override
-    public ParcelFileDescriptor openFile(
-            Uri uri, @SuppressWarnings("unused") String mode) throws FileNotFoundException {
-        if (uri == null) {
-            throw new IllegalArgumentException("URI passed in is null.");
-        }
-
-        enforcePermissions(uri);
-
-        if (ICON_TYPE.equals(getType(uri))) {
-            final File file = WearPackageUtil.getIconFile(
-                    this.getContext().getApplicationContext(), getPackageNameFromUri(uri));
-            if (file != null) {
-                return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
-            }
-        }
-        return null;
-    }
-
-    public static Uri getUriForPackage(final String packageName) {
-        return Uri.parse("content://" + AUTHORITY + "/icons/" + packageName + ".icon");
-    }
-
-    private String getPackageNameFromUri(Uri uri) {
-        if (uri == null) {
-            return null;
-        }
-        List<String> pathSegments = uri.getPathSegments();
-        String packageName = pathSegments.get(pathSegments.size() - 1);
-
-        if (packageName.endsWith(".icon")) {
-            packageName = packageName.substring(0, packageName.lastIndexOf("."));
-        }
-        return packageName;
-    }
-
-    /**
-     * Make sure the calling app is either a system app or the same app or has the right permission.
-     * @throws SecurityException if the caller has insufficient permissions.
-     */
-    @TargetApi(Build.VERSION_CODES.BASE_1_1)
-    private void enforcePermissions(Uri uri) {
-        // Redo some of the permission check in {@link ContentProvider}. Just add an extra check to
-        // allow System process to access this provider.
-        Context context = getContext();
-        final int pid = Binder.getCallingPid();
-        final int uid = Binder.getCallingUid();
-        final int myUid = android.os.Process.myUid();
-
-        if (uid == myUid || isSystemApp(context, pid)) {
-            return;
-        }
-
-        if (context.checkPermission(REQUIRED_PERMISSION, pid, uid) == PERMISSION_GRANTED) {
-            return;
-        }
-
-        // last chance, check against any uri grants
-        if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
-                == PERMISSION_GRANTED) {
-            return;
-        }
-
-        throw new SecurityException("Permission Denial: reading "
-                + getClass().getName() + " uri " + uri + " from pid=" + pid
-                + ", uid=" + uid);
-    }
-
-    /**
-     * From the pid of the calling process, figure out whether this is a system app or not. We do
-     * this by checking the application information corresponding to the pid and then checking if
-     * FLAG_SYSTEM is set.
-     */
-    @TargetApi(Build.VERSION_CODES.CUPCAKE)
-    private boolean isSystemApp(Context context, int pid) {
-        // Get the Activity Manager Object
-        ActivityManager aManager =
-                (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
-        // Get the list of running Applications
-        List<ActivityManager.RunningAppProcessInfo> rapInfoList =
-                aManager.getRunningAppProcesses();
-        for (ActivityManager.RunningAppProcessInfo rapInfo : rapInfoList) {
-            if (rapInfo.pid == pid) {
-                try {
-                    PackageInfo pkgInfo = context.getPackageManager().getPackageInfo(
-                            rapInfo.pkgList[0], 0);
-                    if (pkgInfo != null && pkgInfo.applicationInfo != null &&
-                            (pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
-                        Log.d(TAG, pid + " is a system app.");
-                        return true;
-                    }
-                } catch (PackageManager.NameNotFoundException e) {
-                    Log.e(TAG, "Could not find package information.", e);
-                    return false;
-                }
-            }
-        }
-        return false;
-    }
-}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java
deleted file mode 100644
index ae0f4ec..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.packageinstaller.wear;
-
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.FeatureInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageInstaller;
-import android.content.pm.PackageManager;
-import android.content.pm.VersionedPackage;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.os.PowerManager;
-import android.os.Process;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Pair;
-import androidx.annotation.Nullable;
-import com.android.packageinstaller.DeviceUtils;
-import com.android.packageinstaller.PackageUtil;
-import com.android.packageinstaller.R;
-import com.android.packageinstaller.common.EventResultPersister;
-import com.android.packageinstaller.common.UninstallEventReceiver;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Service that will install/uninstall packages. It will check for permissions and features as well.
- *
- * -----------
- *
- * Debugging information:
- *
- *  Install Action example:
- *  adb shell am startservice -a com.android.packageinstaller.wear.INSTALL_PACKAGE \
- *     -d package://com.google.android.gms \
- *     --eu com.google.android.clockwork.EXTRA_ASSET_URI content://com.google.android.clockwork.home.provider/host/com.google.android.wearable.app/wearable/com.google.android.gms/apk \
- *     --es android.intent.extra.INSTALLER_PACKAGE_NAME com.google.android.gms \
- *     --ez com.google.android.clockwork.EXTRA_CHECK_PERMS false \
- *     --eu com.google.android.clockwork.EXTRA_PERM_URI content://com.google.android.clockwork.home.provider/host/com.google.android.wearable.app/permissions \
- *     com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService
- *
- *  Uninstall Action example:
- *  adb shell am startservice -a com.android.packageinstaller.wear.UNINSTALL_PACKAGE \
- *     -d package://com.google.android.gms \
- *     com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService
- *
- *  Retry GMS:
- *  adb shell am startservice -a com.android.packageinstaller.wear.RETRY_GMS \
- *     com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService
- */
-public class WearPackageInstallerService extends Service
-        implements EventResultPersister.EventResultObserver {
-    private static final String TAG = "WearPkgInstallerService";
-
-    private static final String WEAR_APPS_CHANNEL = "wear_app_install_uninstall";
-    private static final String BROADCAST_ACTION =
-            "com.android.packageinstaller.ACTION_UNINSTALL_COMMIT";
-
-    private final int START_INSTALL = 1;
-    private final int START_UNINSTALL = 2;
-
-    private int mInstallNotificationId = 1;
-    private final Map<String, Integer> mNotifIdMap = new ArrayMap<>();
-    private final Map<Integer, UninstallParams> mServiceIdToParams = new HashMap<>();
-
-    private class UninstallParams {
-        public String mPackageName;
-        public PowerManager.WakeLock mLock;
-
-        UninstallParams(String packageName, PowerManager.WakeLock lock) {
-            mPackageName = packageName;
-            mLock = lock;
-        }
-    }
-
-    private final class ServiceHandler extends Handler {
-        public ServiceHandler(Looper looper) {
-            super(looper);
-        }
-
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case START_INSTALL:
-                    installPackage(msg.getData());
-                    break;
-                case START_UNINSTALL:
-                    uninstallPackage(msg.getData());
-                    break;
-            }
-        }
-    }
-    private ServiceHandler mServiceHandler;
-    private NotificationChannel mNotificationChannel;
-    private static volatile PowerManager.WakeLock lockStatic = null;
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        HandlerThread thread = new HandlerThread("PackageInstallerThread",
-                Process.THREAD_PRIORITY_BACKGROUND);
-        thread.start();
-
-        mServiceHandler = new ServiceHandler(thread.getLooper());
-    }
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        if (!DeviceUtils.isWear(this)) {
-            Log.w(TAG, "Not running on wearable.");
-            finishServiceEarly(startId);
-            return START_NOT_STICKY;
-        }
-
-        if (intent == null) {
-            Log.w(TAG, "Got null intent.");
-            finishServiceEarly(startId);
-            return START_NOT_STICKY;
-        }
-
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "Got install/uninstall request " + intent);
-        }
-
-        Uri packageUri = intent.getData();
-        if (packageUri == null) {
-            Log.e(TAG, "No package URI in intent");
-            finishServiceEarly(startId);
-            return START_NOT_STICKY;
-        }
-
-        final String packageName = WearPackageUtil.getSanitizedPackageName(packageUri);
-        if (packageName == null) {
-            Log.e(TAG, "Invalid package name in URI (expected package:<pkgName>): " + packageUri);
-            finishServiceEarly(startId);
-            return START_NOT_STICKY;
-        }
-
-        PowerManager.WakeLock lock = getLock(this.getApplicationContext());
-        if (!lock.isHeld()) {
-            lock.acquire();
-        }
-
-        Bundle intentBundle = intent.getExtras();
-        if (intentBundle == null) {
-            intentBundle = new Bundle();
-        }
-        WearPackageArgs.setStartId(intentBundle, startId);
-        WearPackageArgs.setPackageName(intentBundle, packageName);
-        Message msg;
-        String notifTitle;
-        if (Intent.ACTION_INSTALL_PACKAGE.equals(intent.getAction())) {
-            msg = mServiceHandler.obtainMessage(START_INSTALL);
-            notifTitle = getString(R.string.installing);
-        } else if (Intent.ACTION_UNINSTALL_PACKAGE.equals(intent.getAction())) {
-            msg = mServiceHandler.obtainMessage(START_UNINSTALL);
-            notifTitle = getString(R.string.uninstalling);
-        } else {
-            Log.e(TAG, "Unknown action : " + intent.getAction());
-            finishServiceEarly(startId);
-            return START_NOT_STICKY;
-        }
-        Pair<Integer, Notification> notifPair = buildNotification(packageName, notifTitle);
-        startForeground(notifPair.first, notifPair.second);
-        msg.setData(intentBundle);
-        mServiceHandler.sendMessage(msg);
-        return START_NOT_STICKY;
-    }
-
-    private void installPackage(Bundle argsBundle) {
-        int startId = WearPackageArgs.getStartId(argsBundle);
-        final String packageName = WearPackageArgs.getPackageName(argsBundle);
-        final Uri assetUri = WearPackageArgs.getAssetUri(argsBundle);
-        final Uri permUri = WearPackageArgs.getPermUri(argsBundle);
-        boolean checkPerms = WearPackageArgs.checkPerms(argsBundle);
-        boolean skipIfSameVersion = WearPackageArgs.skipIfSameVersion(argsBundle);
-        int companionSdkVersion = WearPackageArgs.getCompanionSdkVersion(argsBundle);
-        int companionDeviceVersion = WearPackageArgs.getCompanionDeviceVersion(argsBundle);
-        String compressionAlg = WearPackageArgs.getCompressionAlg(argsBundle);
-        boolean skipIfLowerVersion = WearPackageArgs.skipIfLowerVersion(argsBundle);
-
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "Installing package: " + packageName + ", assetUri: " + assetUri +
-                    ",permUri: " + permUri + ", startId: " + startId + ", checkPerms: " +
-                    checkPerms + ", skipIfSameVersion: " + skipIfSameVersion +
-                    ", compressionAlg: " + compressionAlg + ", companionSdkVersion: " +
-                    companionSdkVersion + ", companionDeviceVersion: " + companionDeviceVersion +
-                    ", skipIfLowerVersion: " + skipIfLowerVersion);
-        }
-        final PackageManager pm = getPackageManager();
-        File tempFile = null;
-        PowerManager.WakeLock lock = getLock(this.getApplicationContext());
-        boolean messageSent = false;
-        try {
-            PackageInfo existingPkgInfo = null;
-            try {
-                existingPkgInfo = pm.getPackageInfo(packageName,
-                        PackageManager.MATCH_ANY_USER | PackageManager.GET_PERMISSIONS);
-                if (existingPkgInfo != null) {
-                    if (Log.isLoggable(TAG, Log.DEBUG)) {
-                        Log.d(TAG, "Replacing package:" + packageName);
-                    }
-                }
-            } catch (PackageManager.NameNotFoundException e) {
-                // Ignore this exception. We could not find the package, will treat as a new
-                // installation.
-            }
-            // TODO(28021618): This was left as a temp file due to the fact that this code is being
-            //       deprecated and that we need the bare minimum to continue working moving forward
-            //       If this code is used as reference, this permission logic might want to be
-            //       reworked to use a stream instead of a file so that we don't need to write a
-            //       file at all.  Note that there might be some trickiness with opening a stream
-            //       for multiple users.
-            ParcelFileDescriptor parcelFd = getContentResolver()
-                    .openFileDescriptor(assetUri, "r");
-            tempFile = WearPackageUtil.getFileFromFd(WearPackageInstallerService.this,
-                    parcelFd, packageName, compressionAlg);
-            if (tempFile == null) {
-                Log.e(TAG, "Could not create a temp file from FD for " + packageName);
-                return;
-            }
-            PackageInfo pkgInfo = PackageUtil.getPackageInfo(this, tempFile,
-                    PackageManager.GET_PERMISSIONS | PackageManager.GET_CONFIGURATIONS);
-            if (pkgInfo == null) {
-                Log.e(TAG, "Could not parse apk information for " + packageName);
-                return;
-            }
-
-            if (!pkgInfo.packageName.equals(packageName)) {
-                Log.e(TAG, "Wearable Package Name has to match what is provided for " +
-                        packageName);
-                return;
-            }
-
-            ApplicationInfo appInfo = pkgInfo.applicationInfo;
-            appInfo.sourceDir = tempFile.getPath();
-            appInfo.publicSourceDir = tempFile.getPath();
-            getLabelAndUpdateNotification(packageName,
-                    getString(R.string.installing_app, appInfo.loadLabel(pm)));
-
-            List<String> wearablePerms = Arrays.asList(pkgInfo.requestedPermissions);
-
-            // Log if the installed pkg has a higher version number.
-            if (existingPkgInfo != null) {
-                long longVersionCode = pkgInfo.getLongVersionCode();
-                if (existingPkgInfo.getLongVersionCode() == longVersionCode) {
-                    if (skipIfSameVersion) {
-                        Log.w(TAG, "Version number (" + longVersionCode +
-                                ") of new app is equal to existing app for " + packageName +
-                                "; not installing due to versionCheck");
-                        return;
-                    } else {
-                        Log.w(TAG, "Version number of new app (" + longVersionCode +
-                                ") is equal to existing app for " + packageName);
-                    }
-                } else if (existingPkgInfo.getLongVersionCode() > longVersionCode) {
-                    if (skipIfLowerVersion) {
-                        // Starting in Feldspar, we are not going to allow downgrades of any app.
-                        Log.w(TAG, "Version number of new app (" + longVersionCode +
-                                ") is lower than existing app ( "
-                                + existingPkgInfo.getLongVersionCode() +
-                                ") for " + packageName + "; not installing due to versionCheck");
-                        return;
-                    } else {
-                        Log.w(TAG, "Version number of new app (" + longVersionCode +
-                                ") is lower than existing app ( "
-                                + existingPkgInfo.getLongVersionCode() + ") for " + packageName);
-                    }
-                }
-
-                // Following the Android Phone model, we should only check for permissions for any
-                // newly defined perms.
-                if (existingPkgInfo.requestedPermissions != null) {
-                    for (int i = 0; i < existingPkgInfo.requestedPermissions.length; ++i) {
-                        // If the permission is granted, then we will not ask to request it again.
-                        if ((existingPkgInfo.requestedPermissionsFlags[i] &
-                                PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) {
-                            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                                Log.d(TAG, existingPkgInfo.requestedPermissions[i] +
-                                        " is already granted for " + packageName);
-                            }
-                            wearablePerms.remove(existingPkgInfo.requestedPermissions[i]);
-                        }
-                    }
-                }
-            }
-
-            // Check that the wearable has all the features.
-            boolean hasAllFeatures = true;
-            for (FeatureInfo feature : pkgInfo.reqFeatures) {
-                if (feature.name != null && !pm.hasSystemFeature(feature.name) &&
-                        (feature.flags & FeatureInfo.FLAG_REQUIRED) != 0) {
-                    Log.e(TAG, "Wearable does not have required feature: " + feature +
-                            " for " + packageName);
-                    hasAllFeatures = false;
-                }
-            }
-
-            if (!hasAllFeatures) {
-                return;
-            }
-
-            // Check permissions on both the new wearable package and also on the already installed
-            // wearable package.
-            // If the app is targeting API level 23, we will also start a service in ClockworkHome
-            // which will ultimately prompt the user to accept/reject permissions.
-            if (checkPerms && !checkPermissions(pkgInfo, companionSdkVersion,
-                    companionDeviceVersion, permUri, wearablePerms, tempFile)) {
-                Log.w(TAG, "Wearable does not have enough permissions.");
-                return;
-            }
-
-            // Finally install the package.
-            ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(assetUri, "r");
-            PackageInstallerFactory.getPackageInstaller(this).install(packageName, fd,
-                    new PackageInstallListener(this, lock, startId, packageName));
-
-            messageSent = true;
-            Log.i(TAG, "Sent installation request for " + packageName);
-        } catch (FileNotFoundException e) {
-            Log.e(TAG, "Could not find the file with URI " + assetUri, e);
-        } finally {
-            if (!messageSent) {
-                // Some error happened. If the message has been sent, we can wait for the observer
-                // which will finish the service.
-                if (tempFile != null) {
-                    tempFile.delete();
-                }
-                finishService(lock, startId);
-            }
-        }
-    }
-
-    // TODO: This was left using the old PackageManager API due to the fact that this code is being
-    //       deprecated and that we need the bare minimum to continue working moving forward
-    //       If this code is used as reference, this logic should be reworked to use the new
-    //       PackageInstaller APIs similar to how installPackage was reworked
-    private void uninstallPackage(Bundle argsBundle) {
-        int startId = WearPackageArgs.getStartId(argsBundle);
-        final String packageName = WearPackageArgs.getPackageName(argsBundle);
-
-        PowerManager.WakeLock lock = getLock(this.getApplicationContext());
-
-        UninstallParams params = new UninstallParams(packageName, lock);
-        mServiceIdToParams.put(startId, params);
-
-        final PackageManager pm = getPackageManager();
-        try {
-            PackageInfo pkgInfo = pm.getPackageInfo(packageName, 0);
-            getLabelAndUpdateNotification(packageName,
-                    getString(R.string.uninstalling_app, pkgInfo.applicationInfo.loadLabel(pm)));
-
-            int uninstallId = UninstallEventReceiver.addObserver(this,
-                    EventResultPersister.GENERATE_NEW_ID, this);
-
-            Intent broadcastIntent = new Intent(BROADCAST_ACTION);
-            broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-            broadcastIntent.putExtra(EventResultPersister.EXTRA_ID, uninstallId);
-            broadcastIntent.putExtra(EventResultPersister.EXTRA_SERVICE_ID, startId);
-            broadcastIntent.setPackage(getPackageName());
-
-            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, uninstallId,
-                    broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT
-                            | PendingIntent.FLAG_MUTABLE);
-
-            // Found package, send uninstall request.
-            pm.getPackageInstaller().uninstall(
-                    new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
-                    PackageManager.DELETE_ALL_USERS,
-                    pendingIntent.getIntentSender());
-
-            Log.i(TAG, "Sent delete request for " + packageName);
-        } catch (IllegalArgumentException | PackageManager.NameNotFoundException e) {
-            // Couldn't find the package, no need to call uninstall.
-            Log.w(TAG, "Could not find package, not deleting " + packageName, e);
-            finishService(lock, startId);
-        } catch (EventResultPersister.OutOfIdsException e) {
-            Log.e(TAG, "Fails to start uninstall", e);
-            finishService(lock, startId);
-        }
-    }
-
-    @Override
-    public void onResult(int status, int legacyStatus, @Nullable String message, int serviceId) {
-        if (mServiceIdToParams.containsKey(serviceId)) {
-            UninstallParams params = mServiceIdToParams.get(serviceId);
-            try {
-                if (status == PackageInstaller.STATUS_SUCCESS) {
-                    Log.i(TAG, "Package " + params.mPackageName + " was uninstalled.");
-                } else {
-                    Log.e(TAG, "Package uninstall failed " + params.mPackageName
-                            + ", returnCode " + legacyStatus);
-                }
-            } finally {
-                finishService(params.mLock, serviceId);
-            }
-        }
-    }
-
-    private boolean checkPermissions(PackageInfo pkgInfo, int companionSdkVersion,
-            int companionDeviceVersion, Uri permUri, List<String> wearablePermissions,
-            File apkFile) {
-        // Assumption: We are running on Android O.
-        // If the Phone App is targeting M, all permissions may not have been granted to the phone
-        // app. If the Wear App is then not targeting M, there may be permissions that are not
-        // granted on the Phone app (by the user) right now and we cannot just grant it for the Wear
-        // app.
-        if (pkgInfo.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
-            // Install the app if Wear App is ready for the new perms model.
-            return true;
-        }
-
-        if (!doesWearHaveUngrantedPerms(pkgInfo.packageName, permUri, wearablePermissions)) {
-            // All permissions requested by the watch are already granted on the phone, no need
-            // to do anything.
-            return true;
-        }
-
-        // Log an error if Wear is targeting < 23 and phone is targeting >= 23.
-        if (companionSdkVersion == 0 || companionSdkVersion >= Build.VERSION_CODES.M) {
-            Log.e(TAG, "MNC: Wear app's targetSdkVersion should be at least 23, if "
-                    + "phone app is targeting at least 23, will continue.");
-        }
-
-        return false;
-    }
-
-    /**
-     * Given a {@string packageName} corresponding to a phone app, query the provider for all the
-     * perms that are granted.
-     *
-     * @return true if the Wear App has any perms that have not been granted yet on the phone side.
-     * @return true if there is any error cases.
-     */
-    private boolean doesWearHaveUngrantedPerms(String packageName, Uri permUri,
-            List<String> wearablePermissions) {
-        if (permUri == null) {
-            Log.e(TAG, "Permission URI is null");
-            // Pretend there is an ungranted permission to avoid installing for error cases.
-            return true;
-        }
-        Cursor permCursor = getContentResolver().query(permUri, null, null, null, null);
-        if (permCursor == null) {
-            Log.e(TAG, "Could not get the cursor for the permissions");
-            // Pretend there is an ungranted permission to avoid installing for error cases.
-            return true;
-        }
-
-        Set<String> grantedPerms = new HashSet<>();
-        Set<String> ungrantedPerms = new HashSet<>();
-        while(permCursor.moveToNext()) {
-            // Make sure that the MatrixCursor returned by the ContentProvider has 2 columns and
-            // verify their types.
-            if (permCursor.getColumnCount() == 2
-                    && Cursor.FIELD_TYPE_STRING == permCursor.getType(0)
-                    && Cursor.FIELD_TYPE_INTEGER == permCursor.getType(1)) {
-                String perm = permCursor.getString(0);
-                Integer granted = permCursor.getInt(1);
-                if (granted == 1) {
-                    grantedPerms.add(perm);
-                } else {
-                    ungrantedPerms.add(perm);
-                }
-            }
-        }
-        permCursor.close();
-
-        boolean hasUngrantedPerm = false;
-        for (String wearablePerm : wearablePermissions) {
-            if (!grantedPerms.contains(wearablePerm)) {
-                hasUngrantedPerm = true;
-                if (!ungrantedPerms.contains(wearablePerm)) {
-                    // This is an error condition. This means that the wearable has permissions that
-                    // are not even declared in its host app. This is a developer error.
-                    Log.e(TAG, "Wearable " + packageName + " has a permission \"" + wearablePerm
-                            + "\" that is not defined in the host application's manifest.");
-                } else {
-                    Log.w(TAG, "Wearable " + packageName + " has a permission \"" + wearablePerm +
-                            "\" that is not granted in the host application.");
-                }
-            }
-        }
-        return hasUngrantedPerm;
-    }
-
-    /** Finishes the service after fulfilling obligation to call startForeground. */
-    private void finishServiceEarly(int startId) {
-        Pair<Integer, Notification> notifPair = buildNotification(
-                getApplicationContext().getPackageName(), "");
-        startForeground(notifPair.first, notifPair.second);
-        finishService(null, startId);
-    }
-
-    private void finishService(PowerManager.WakeLock lock, int startId) {
-        if (lock != null && lock.isHeld()) {
-            lock.release();
-        }
-        stopSelf(startId);
-    }
-
-    private synchronized PowerManager.WakeLock getLock(Context context) {
-        if (lockStatic == null) {
-            PowerManager mgr =
-                    (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-            lockStatic = mgr.newWakeLock(
-                    PowerManager.PARTIAL_WAKE_LOCK, context.getClass().getSimpleName());
-            lockStatic.setReferenceCounted(true);
-        }
-        return lockStatic;
-    }
-
-    private class PackageInstallListener implements PackageInstallerImpl.InstallListener {
-        private Context mContext;
-        private PowerManager.WakeLock mWakeLock;
-        private int mStartId;
-        private String mApplicationPackageName;
-        private PackageInstallListener(Context context, PowerManager.WakeLock wakeLock,
-                int startId, String applicationPackageName) {
-            mContext = context;
-            mWakeLock = wakeLock;
-            mStartId = startId;
-            mApplicationPackageName = applicationPackageName;
-        }
-
-        @Override
-        public void installBeginning() {
-            Log.i(TAG, "Package " + mApplicationPackageName + " is being installed.");
-        }
-
-        @Override
-        public void installSucceeded() {
-            try {
-                Log.i(TAG, "Package " + mApplicationPackageName + " was installed.");
-
-                // Delete tempFile from the file system.
-                File tempFile = WearPackageUtil.getTemporaryFile(mContext, mApplicationPackageName);
-                if (tempFile != null) {
-                    tempFile.delete();
-                }
-            } finally {
-                finishService(mWakeLock, mStartId);
-            }
-        }
-
-        @Override
-        public void installFailed(int errorCode, String errorDesc) {
-            Log.e(TAG, "Package install failed " + mApplicationPackageName
-                    + ", errorCode " + errorCode);
-            finishService(mWakeLock, mStartId);
-        }
-    }
-
-    private synchronized Pair<Integer, Notification> buildNotification(final String packageName,
-            final String title) {
-        int notifId;
-        if (mNotifIdMap.containsKey(packageName)) {
-            notifId = mNotifIdMap.get(packageName);
-        } else {
-            notifId = mInstallNotificationId++;
-            mNotifIdMap.put(packageName, notifId);
-        }
-
-        if (mNotificationChannel == null) {
-            mNotificationChannel = new NotificationChannel(WEAR_APPS_CHANNEL,
-                    getString(R.string.wear_app_channel), NotificationManager.IMPORTANCE_MIN);
-            NotificationManager notificationManager = getSystemService(NotificationManager.class);
-            notificationManager.createNotificationChannel(mNotificationChannel);
-        }
-        return new Pair<>(notifId, new Notification.Builder(this, WEAR_APPS_CHANNEL)
-            .setSmallIcon(R.drawable.ic_file_download)
-            .setContentTitle(title)
-            .build());
-    }
-
-    private void getLabelAndUpdateNotification(String packageName, String title) {
-        // Update notification since we have a label now.
-        NotificationManager notificationManager = getSystemService(NotificationManager.class);
-        Pair<Integer, Notification> notifPair = buildNotification(packageName, title);
-        notificationManager.notify(notifPair.first, notifPair.second);
-    }
-}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageUtil.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageUtil.java
deleted file mode 100644
index 6a9145d..0000000
--- a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageUtil.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.packageinstaller.wear;
-
-import android.content.Context;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.text.TextUtils;
-import android.util.Log;
-
-import org.tukaani.xz.LZMAInputStream;
-import org.tukaani.xz.XZInputStream;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-public class WearPackageUtil {
-    private static final String TAG = "WearablePkgInstaller";
-
-    private static final String COMPRESSION_LZMA = "lzma";
-    private static final String COMPRESSION_XZ = "xz";
-
-    public static File getTemporaryFile(Context context, String packageName) {
-        try {
-            File newFileDir = new File(context.getFilesDir(), "tmp");
-            newFileDir.mkdirs();
-            Os.chmod(newFileDir.getAbsolutePath(), 0771);
-            File newFile = new File(newFileDir, packageName + ".apk");
-            return newFile;
-        }   catch (ErrnoException e) {
-            Log.e(TAG, "Failed to open.", e);
-            return null;
-        }
-    }
-
-    public static File getIconFile(final Context context, final String packageName) {
-        try {
-            File newFileDir = new File(context.getFilesDir(), "images/icons");
-            newFileDir.mkdirs();
-            Os.chmod(newFileDir.getAbsolutePath(), 0771);
-            return new File(newFileDir, packageName + ".icon");
-        }   catch (ErrnoException e) {
-            Log.e(TAG, "Failed to open.", e);
-            return null;
-        }
-    }
-
-    /**
-     * In order to make sure that the Wearable Asset Manager has a reasonable apk that can be used
-     * by the PackageManager, we will parse it before sending it to the PackageManager.
-     * Unfortunately, ParsingPackageUtils needs a file to parse. So, we have to temporarily convert
-     * the fd to a File.
-     *
-     * @param context
-     * @param fd FileDescriptor to convert to File
-     * @param packageName Name of package, will define the name of the file
-     * @param compressionAlg Can be null. For ALT mode the APK will be compressed. We will
-     *                       decompress it here
-     */
-    public static File getFileFromFd(Context context, ParcelFileDescriptor fd,
-            String packageName, String compressionAlg) {
-        File newFile = getTemporaryFile(context, packageName);
-        if (fd == null || fd.getFileDescriptor() == null)  {
-            return null;
-        }
-        InputStream fr = new ParcelFileDescriptor.AutoCloseInputStream(fd);
-        try {
-            if (TextUtils.equals(compressionAlg, COMPRESSION_XZ)) {
-                fr = new XZInputStream(fr);
-            } else if (TextUtils.equals(compressionAlg, COMPRESSION_LZMA)) {
-                fr = new LZMAInputStream(fr);
-            }
-        } catch (IOException e) {
-            Log.e(TAG, "Compression was set to " + compressionAlg + ", but could not decode ", e);
-            return null;
-        }
-
-        int nRead;
-        byte[] data = new byte[1024];
-        try {
-            final FileOutputStream fo = new FileOutputStream(newFile);
-            while ((nRead = fr.read(data, 0, data.length)) != -1) {
-                fo.write(data, 0, nRead);
-            }
-            fo.flush();
-            fo.close();
-            Os.chmod(newFile.getAbsolutePath(), 0644);
-            return newFile;
-        } catch (IOException e) {
-            Log.e(TAG, "Reading from Asset FD or writing to temp file failed ", e);
-            return null;
-        }   catch (ErrnoException e) {
-            Log.e(TAG, "Could not set permissions on file ", e);
-            return null;
-        } finally {
-            try {
-                fr.close();
-            } catch (IOException e) {
-                Log.e(TAG, "Failed to close the file from FD ", e);
-            }
-        }
-    }
-
-    /**
-     * @return com.google.com from expected formats like
-     * Uri: package:com.google.com, package:/com.google.com, package://com.google.com
-     */
-    public static String getSanitizedPackageName(Uri packageUri) {
-        String packageName = packageUri.getEncodedSchemeSpecificPart();
-        if (packageName != null) {
-            return packageName.replaceAll("^/+", "");
-        }
-        return packageName;
-    }
-}
diff --git a/packages/PrintSpooler/res/values-te/strings.xml b/packages/PrintSpooler/res/values-te/strings.xml
index ed0b6d4..18fdc73 100644
--- a/packages/PrintSpooler/res/values-te/strings.xml
+++ b/packages/PrintSpooler/res/values-te/strings.xml
@@ -31,7 +31,7 @@
     <string name="template_all_pages" msgid="3322235982020148762">"మొత్తం <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string>
     <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> పరిధి"</string>
     <string name="pages_range_example" msgid="8558694453556945172">"ఉదా. 1—5,8,11—13"</string>
-    <string name="print_preview" msgid="8010217796057763343">"ముద్రణ ప్రివ్యూ"</string>
+    <string name="print_preview" msgid="8010217796057763343">"ప్రింట్ ప్రివ్యూ"</string>
     <string name="install_for_print_preview" msgid="6366303997385509332">"ప్రివ్యూ చేయడానికి PDF వ్యూయర్‌ను ఇన్‌స్టాల్ చేయండి"</string>
     <string name="printing_app_crashed" msgid="854477616686566398">"ముద్రణ యాప్ క్రాష్ అయ్యింది"</string>
     <string name="generating_print_job" msgid="3119608742651698916">"ముద్రణ జాబ్‌ను ఉత్పన్నం చేస్తోంది"</string>
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index bd56aae..d6cbf2a 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -11,6 +11,7 @@
     name: "SettingsLib",
     defaults: [
         "SettingsLintDefaults",
+        "SettingsLibAvatarPickerDefaults",
     ],
 
     static_libs: [
@@ -21,7 +22,7 @@
         "guava",
 
         "WifiTrackerLibRes",
-        "iconloader",
+        "//frameworks/libs/systemui:iconloader",
         "setupdesign",
 
         "SettingsLibActionBarShadow",
@@ -87,6 +88,7 @@
 aconfig_declarations {
     name: "settingslib_media_flags",
     package: "com.android.settingslib.media.flags",
+    container: "system",
     srcs: [
         "aconfig/settingslib_media_flag_declarations.aconfig",
     ],
@@ -100,6 +102,7 @@
 aconfig_declarations {
     name: "settingslib_flags",
     package: "com.android.settingslib.flags",
+    container: "system",
     srcs: [
         "aconfig/settingslib.aconfig",
     ],
@@ -109,3 +112,32 @@
     name: "settingslib_flags_lib",
     aconfig_declarations: "settingslib_flags",
 }
+
+soong_config_module_type {
+    name: "avatar_picker_java_defaults",
+    module_type: "java_defaults",
+    config_namespace: "SettingsLib",
+    bool_variables: [
+        "legacy_avatar_picker_app_enabled",
+    ],
+    properties: [
+        "static_libs",
+        "manifest",
+    ],
+}
+
+soong_config_bool_variable {
+    name: "legacy_avatar_picker_app_enabled",
+}
+
+avatar_picker_java_defaults {
+    name: "SettingsLibAvatarPickerDefaults",
+    soong_config_variables: {
+        // If flag is enabled, add the library
+        legacy_avatar_picker_app_enabled: {
+            static_libs: [
+                "SettingsLibAvatarPicker",
+            ],
+        },
+    },
+}
diff --git a/packages/SettingsLib/AndroidManifest.xml b/packages/SettingsLib/AndroidManifest.xml
index 322d6cf..412ff29 100644
--- a/packages/SettingsLib/AndroidManifest.xml
+++ b/packages/SettingsLib/AndroidManifest.xml
@@ -21,9 +21,6 @@
     <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
 
     <application>
-        <activity
-            android:name="com.android.settingslib.users.AvatarPickerActivity"
-            android:theme="@style/SudThemeGlifV2.DayNight"/>
     </application>
 
 </manifest>
diff --git a/packages/SettingsLib/AvatarPicker/Android.bp b/packages/SettingsLib/AvatarPicker/Android.bp
new file mode 100644
index 0000000..1d42cd4
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/Android.bp
@@ -0,0 +1,31 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+android_library {
+    name: "SettingsLibAvatarPicker",
+    manifest: "AndroidManifest.xml",
+    use_resource_processor: true,
+    platform_apis: true,
+
+    defaults: [
+        "SettingsLintDefaults",
+    ],
+
+    static_libs: [
+        "SettingsLibSettingsTheme",
+        "setupdesign",
+        "guava",
+    ],
+
+    resource_dirs: ["res"],
+    srcs: [
+        "src/**/*.java",
+        "src/**/*.kt",
+    ],
+}
diff --git a/packages/SettingsLib/AvatarPicker/AndroidManifest.xml b/packages/SettingsLib/AvatarPicker/AndroidManifest.xml
new file mode 100644
index 0000000..73dd35b
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.settingslib.avatarpicker">
+
+    <uses-sdk android:minSdkVersion="23" />
+    <application>
+        <activity
+            android:name=".AvatarPickerActivity"
+            android:theme="@style/SudThemeGlifV2.DayNight"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="com.android.avatarpicker.FULL_SCREEN_ACTIVITY" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/packages/SettingsLib/AvatarPicker/res/drawable/avatar_choose_photo_circled.xml b/packages/SettingsLib/AvatarPicker/res/drawable/avatar_choose_photo_circled.xml
new file mode 100644
index 0000000..27bb87f
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/drawable/avatar_choose_photo_circled.xml
@@ -0,0 +1,30 @@
+<!--
+    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.
+  -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item>
+        <shape android:shape="oval">
+            <stroke
+                android:width="2dp"
+                android:color="?android:attr/colorPrimary" />
+        </shape>
+    </item>
+    <item
+        android:bottom="@dimen/avatar_picker_icon_inset"
+        android:drawable="@drawable/ic_avatar_choose_photo"
+        android:left="@dimen/avatar_picker_icon_inset"
+        android:right="@dimen/avatar_picker_icon_inset"
+        android:top="@dimen/avatar_picker_icon_inset" />
+</layer-list>
diff --git a/packages/SettingsLib/res/drawable/avatar_selector.xml b/packages/SettingsLib/AvatarPicker/res/drawable/avatar_selector.xml
similarity index 75%
rename from packages/SettingsLib/res/drawable/avatar_selector.xml
rename to packages/SettingsLib/AvatarPicker/res/drawable/avatar_selector.xml
index ccde597..1fb521a 100644
--- a/packages/SettingsLib/res/drawable/avatar_selector.xml
+++ b/packages/SettingsLib/AvatarPicker/res/drawable/avatar_selector.xml
@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-    Copyright (C) 2022 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!--
+    Copyright (C) 2024 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
@@ -17,9 +16,7 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_selected="true">
         <shape android:shape="oval">
-            <stroke
-                android:color="?android:attr/colorPrimary"
-                android:width="@dimen/avatar_picker_padding"/>
+            <stroke android:width="@dimen/avatar_picker_padding" android:color="?android:attr/colorPrimary" />
         </shape>
     </item>
 </selector>
\ No newline at end of file
diff --git a/packages/SettingsLib/AvatarPicker/res/drawable/avatar_take_photo_circled.xml b/packages/SettingsLib/AvatarPicker/res/drawable/avatar_take_photo_circled.xml
new file mode 100644
index 0000000..d678e9b
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/drawable/avatar_take_photo_circled.xml
@@ -0,0 +1,30 @@
+<!--
+    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.
+  -->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item>
+        <shape android:shape="oval">
+            <stroke
+                android:width="2dp"
+                android:color="?android:attr/colorPrimary" />
+        </shape>
+    </item>
+    <item
+        android:bottom="@dimen/avatar_picker_icon_inset"
+        android:drawable="@drawable/ic_avatar_take_photo"
+        android:left="@dimen/avatar_picker_icon_inset"
+        android:right="@dimen/avatar_picker_icon_inset"
+        android:top="@dimen/avatar_picker_icon_inset" />
+</layer-list>
diff --git a/packages/SettingsLib/AvatarPicker/res/drawable/ic_account_circle.xml b/packages/SettingsLib/AvatarPicker/res/drawable/ic_account_circle.xml
new file mode 100644
index 0000000..6421f91
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/drawable/ic_account_circle.xml
@@ -0,0 +1,24 @@
+<!--
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M5.85,17.1Q7.125,16.125 8.7,15.562Q10.275,15 12,15Q13.725,15 15.3,15.562Q16.875,16.125 18.15,17.1Q19.025,16.075 19.513,14.775Q20,13.475 20,12Q20,8.675 17.663,6.337Q15.325,4 12,4Q8.675,4 6.338,6.337Q4,8.675 4,12Q4,13.475 4.488,14.775Q4.975,16.075 5.85,17.1ZM12,13Q10.525,13 9.512,11.988Q8.5,10.975 8.5,9.5Q8.5,8.025 9.512,7.012Q10.525,6 12,6Q13.475,6 14.488,7.012Q15.5,8.025 15.5,9.5Q15.5,10.975 14.488,11.988Q13.475,13 12,13ZM12,22Q9.925,22 8.1,21.212Q6.275,20.425 4.925,19.075Q3.575,17.725 2.788,15.9Q2,14.075 2,12Q2,9.925 2.788,8.1Q3.575,6.275 4.925,4.925Q6.275,3.575 8.1,2.787Q9.925,2 12,2Q14.075,2 15.9,2.787Q17.725,3.575 19.075,4.925Q20.425,6.275 21.212,8.1Q22,9.925 22,12Q22,14.075 21.212,15.9Q20.425,17.725 19.075,19.075Q17.725,20.425 15.9,21.212Q14.075,22 12,22ZM12,20Q13.325,20 14.5,19.613Q15.675,19.225 16.65,18.5Q15.675,17.775 14.5,17.387Q13.325,17 12,17Q10.675,17 9.5,17.387Q8.325,17.775 7.35,18.5Q8.325,19.225 9.5,19.613Q10.675,20 12,20ZM12,11Q12.65,11 13.075,10.575Q13.5,10.15 13.5,9.5Q13.5,8.85 13.075,8.425Q12.65,8 12,8Q11.35,8 10.925,8.425Q10.5,8.85 10.5,9.5Q10.5,10.15 10.925,10.575Q11.35,11 12,11ZM12,9.5Q12,9.5 12,9.5Q12,9.5 12,9.5Q12,9.5 12,9.5Q12,9.5 12,9.5Q12,9.5 12,9.5Q12,9.5 12,9.5Q12,9.5 12,9.5Q12,9.5 12,9.5ZM12,18.5Q12,18.5 12,18.5Q12,18.5 12,18.5Q12,18.5 12,18.5Q12,18.5 12,18.5Q12,18.5 12,18.5Q12,18.5 12,18.5Q12,18.5 12,18.5Q12,18.5 12,18.5Z" />
+</vector>
diff --git a/packages/SettingsLib/AvatarPicker/res/drawable/ic_account_circle_filled.xml b/packages/SettingsLib/AvatarPicker/res/drawable/ic_account_circle_filled.xml
new file mode 100644
index 0000000..645fdf7
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/drawable/ic_account_circle_filled.xml
@@ -0,0 +1,27 @@
+<!--
+    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:viewportHeight="24"
+    android:viewportWidth="24">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM18.36,16.83c-1.43,-1.74 -4.9,-2.33 -6.36,-2.33s-4.93,0.59 -6.36,2.33A7.95,7.95 0,0 1,4 12c0,-4.41 3.59,-8 8,-8s8,3.59 8,8c0,1.82 -0.62,3.49 -1.64,4.83z" />
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M12,6c-1.94,0 -3.5,1.56 -3.5,3.5S10.06,13 12,13s3.5,-1.56 3.5,-3.5S13.94,6 12,6z" />
+</vector>
diff --git a/packages/SettingsLib/AvatarPicker/res/drawable/ic_account_circle_outline.xml b/packages/SettingsLib/AvatarPicker/res/drawable/ic_account_circle_outline.xml
new file mode 100644
index 0000000..a5c1038
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/drawable/ic_account_circle_outline.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:viewportHeight="24"
+    android:viewportWidth="24">
+    <path
+        android:fillColor="?android:attr/colorPrimary"
+        android:pathData="M5.85,17.1q1.275,-0.975 2.85,-1.538Q10.275,15 12,15q1.725,0 3.3,0.563 1.575,0.562 2.85,1.537 0.875,-1.025 1.363,-2.325Q20,13.475 20,12q0,-3.325 -2.337,-5.662Q15.325,4 12,4T6.338,6.338Q4,8.675 4,12q0,1.475 0.487,2.775 0.488,1.3 1.363,2.325zM12,13q-1.475,0 -2.488,-1.012Q8.5,10.975 8.5,9.5t1.012,-2.487Q10.525,6 12,6t2.488,1.013Q15.5,8.024 15.5,9.5t-1.012,2.488Q13.475,13 12,13zM12,22q-2.075,0 -3.9,-0.788 -1.825,-0.787 -3.175,-2.137 -1.35,-1.35 -2.137,-3.175Q2,14.075 2,12t0.788,-3.9q0.787,-1.825 2.137,-3.175 1.35,-1.35 3.175,-2.137Q9.925,2 12,2t3.9,0.788q1.825,0.787 3.175,2.137 1.35,1.35 2.137,3.175Q22,9.925 22,12t-0.788,3.9q-0.787,1.825 -2.137,3.175 -1.35,1.35 -3.175,2.137Q14.075,22 12,22zM12,20q1.325,0 2.5,-0.387 1.175,-0.388 2.15,-1.113 -0.975,-0.725 -2.15,-1.113Q13.325,17 12,17t-2.5,0.387q-1.175,0.388 -2.15,1.113 0.975,0.725 2.15,1.113Q10.675,20 12,20zM12,11q0.65,0 1.075,-0.425 0.425,-0.425 0.425,-1.075 0,-0.65 -0.425,-1.075Q12.65,8 12,8q-0.65,0 -1.075,0.425Q10.5,8.85 10.5,9.5q0,0.65 0.425,1.075Q11.35,11 12,11zM12,9.5zM12,18.5z" />
+</vector>
+
diff --git a/packages/SettingsLib/res/layout/avatar_item.xml b/packages/SettingsLib/AvatarPicker/res/layout/avatar_item.xml
similarity index 86%
rename from packages/SettingsLib/res/layout/avatar_item.xml
rename to packages/SettingsLib/AvatarPicker/res/layout/avatar_item.xml
index c52f664..cc4e8a7 100644
--- a/packages/SettingsLib/res/layout/avatar_item.xml
+++ b/packages/SettingsLib/AvatarPicker/res/layout/avatar_item.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
     Copyright (C) 2022 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,9 +15,9 @@
   -->
 <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/avatar_image"
-    android:layout_height="@dimen/avatar_size_in_picker"
     android:layout_width="@dimen/avatar_size_in_picker"
-    android:layout_margin="@dimen/avatar_picker_margin"
+    android:layout_height="@dimen/avatar_size_in_picker"
     android:layout_gravity="center"
-    android:padding="@dimen/avatar_picker_padding"
-    android:background="@drawable/avatar_selector"/>
+    android:layout_margin="@dimen/avatar_picker_margin"
+    android:background="@drawable/avatar_selector"
+    android:padding="@dimen/avatar_picker_padding" />
diff --git a/packages/SettingsLib/res/layout/avatar_picker.xml b/packages/SettingsLib/AvatarPicker/res/layout/avatar_picker.xml
similarity index 75%
rename from packages/SettingsLib/res/layout/avatar_picker.xml
rename to packages/SettingsLib/AvatarPicker/res/layout/avatar_picker.xml
index 2d40bd0..e9d375e 100644
--- a/packages/SettingsLib/res/layout/avatar_picker.xml
+++ b/packages/SettingsLib/AvatarPicker/res/layout/avatar_picker.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?xml version="1.0" encoding="utf-8"?><!--
     Copyright (C) 2022 The Android Open Source Project
 
     Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,25 +13,25 @@
     See the License for the specific language governing permissions and
     limitations under the License.
   -->
-<com.google.android.setupdesign.GlifLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
+<com.google.android.setupdesign.GlifLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/glif_layout"
-    android:layout_height="match_parent"
     android:layout_width="match_parent"
+    android:layout_height="match_parent"
     android:icon="@drawable/ic_account_circle_outline"
-    app:sucUsePartnerResource="true"
-    app:sucHeaderText="@string/avatar_picker_title">
+    app:sucHeaderText="@string/avatar_picker_title"
+    app:sucUsePartnerResource="true">
 
     <LinearLayout
-        android:layout_height="match_parent"
+        style="@style/SudContentFrame"
         android:layout_width="match_parent"
-        android:gravity="center_horizontal"
-        style="@style/SudContentFrame">
+        android:layout_height="match_parent"
+        android:gravity="center_horizontal">
+
         <androidx.recyclerview.widget.RecyclerView
             android:id="@+id/avatar_grid"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"/>
+            android:layout_height="wrap_content" />
     </LinearLayout>
 
 </com.google.android.setupdesign.GlifLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/AvatarPicker/res/values/arrays.xml b/packages/SettingsLib/AvatarPicker/res/values/arrays.xml
new file mode 100644
index 0000000..042bc41
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values/arrays.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+   Copyright 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.
+
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Images offered as options in the avatar picker. If populated, the avatar_image_descriptions
+         array must also be populated with a content description for each image. -->
+    <array name="avatar_images" />
+
+    <!-- Content descriptions for each of the images in the avatar_images array. When overlaid
+         these values should be translated, but this empty array must not be translated or it may
+         replace the real descriptions with an empty array. -->
+    <string-array name="avatar_image_descriptions" translatable="false" />
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/AvatarPicker/res/values/dimens.xml b/packages/SettingsLib/AvatarPicker/res/values/dimens.xml
new file mode 100644
index 0000000..df54dc2
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values/dimens.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+  -->
+<resources>
+    <dimen name="avatar_size_in_picker">96dp</dimen>
+    <dimen name="avatar_picker_padding">6dp</dimen>
+    <dimen name="avatar_picker_margin">2dp</dimen>
+    <dimen name="avatar_picker_icon_inset">25dp</dimen>
+    <integer name="avatar_picker_columns">3</integer>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/AvatarPicker/res/values/strings.xml b/packages/SettingsLib/AvatarPicker/res/values/strings.xml
new file mode 100644
index 0000000..1ead128
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/res/values/strings.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+    Copyright (C) 2024 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License
+  -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- An option in a photo selection dialog to choose a pre-existing image [CHAR LIMIT=50] -->
+    <string name="user_image_choose_photo">Choose an image</string>
+
+    <!-- An option in a photo selection dialog to take a new photo [CHAR LIMIT=50] -->
+    <string name="user_image_take_photo">Take a photo</string>
+
+    <!-- Title for a screen allowing the user to choose a profile picture. [CHAR LIMIT=NONE] -->
+    <string name="avatar_picker_title">Choose a profile picture</string>
+
+    <!-- Content description for a default user icon. [CHAR LIMIT=NONE] -->
+    <string name="default_user_icon_description">Default user icon</string>
+
+    <!-- Button label for generic Done action, to be pressed when an action has been completed [CHAR LIMIT=20] -->
+    <string name="done">Done</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/AvatarPhotoController.java b/packages/SettingsLib/AvatarPicker/src/AvatarPhotoController.java
similarity index 97%
rename from packages/SettingsLib/src/com/android/settingslib/users/AvatarPhotoController.java
rename to packages/SettingsLib/AvatarPicker/src/AvatarPhotoController.java
index f165c9f..c20392a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/AvatarPhotoController.java
+++ b/packages/SettingsLib/AvatarPicker/src/AvatarPhotoController.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settingslib.users;
+package com.android.settingslib.avatarpicker;
 
 import android.app.Activity;
 import android.content.ClipData;
@@ -39,8 +39,6 @@
 import androidx.annotation.Nullable;
 import androidx.core.content.FileProvider;
 
-import com.android.settingslib.utils.ThreadUtils;
-
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -170,8 +168,9 @@
     private void copyAndCropPhoto(final Uri pictureUri, boolean delayBeforeCrop) {
         ListenableFuture<Uri> future = ThreadUtils.getBackgroundExecutor().submit(() -> {
             final ContentResolver cr = mContextInjector.getContentResolver();
-            try (InputStream in = cr.openInputStream(pictureUri);
-                    OutputStream out = cr.openOutputStream(mPreCropPictureUri)) {
+            try {
+                InputStream in = cr.openInputStream(pictureUri);
+                OutputStream out = cr.openOutputStream(mPreCropPictureUri);
                 Streams.copy(in, out);
                 return mPreCropPictureUri;
             } catch (IOException e) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java b/packages/SettingsLib/AvatarPicker/src/AvatarPickerActivity.java
similarity index 99%
rename from packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java
rename to packages/SettingsLib/AvatarPicker/src/AvatarPickerActivity.java
index 61c8ee7..de101b1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/AvatarPickerActivity.java
+++ b/packages/SettingsLib/AvatarPicker/src/AvatarPickerActivity.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settingslib.users;
+package com.android.settingslib.avatarpicker;
 
 import android.app.Activity;
 import android.content.ContentResolver;
@@ -38,7 +38,6 @@
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.internal.util.UserIcons;
-import com.android.settingslib.R;
 
 import com.google.android.setupcompat.template.FooterBarMixin;
 import com.google.android.setupcompat.template.FooterButton;
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/PhotoCapabilityUtils.java b/packages/SettingsLib/AvatarPicker/src/PhotoCapabilityUtils.java
similarity index 98%
rename from packages/SettingsLib/src/com/android/settingslib/users/PhotoCapabilityUtils.java
rename to packages/SettingsLib/AvatarPicker/src/PhotoCapabilityUtils.java
index b8615a7..43cb0f5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/PhotoCapabilityUtils.java
+++ b/packages/SettingsLib/AvatarPicker/src/PhotoCapabilityUtils.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.settingslib.users;
+package com.android.settingslib.avatarpicker;
 
 import android.app.KeyguardManager;
 import android.content.Context;
diff --git a/packages/SettingsLib/AvatarPicker/src/ThreadUtils.java b/packages/SettingsLib/AvatarPicker/src/ThreadUtils.java
new file mode 100644
index 0000000..dc19e66
--- /dev/null
+++ b/packages/SettingsLib/AvatarPicker/src/ThreadUtils.java
@@ -0,0 +1,115 @@
+/*
+ * 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.settingslib.avatarpicker;
+
+import android.os.Handler;
+import android.os.Looper;
+
+import androidx.annotation.NonNull;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executors;
+
+// copied from SettinsLib/utils
+public class ThreadUtils {
+
+    private static volatile Thread sMainThread;
+    private static volatile Handler sMainThreadHandler;
+    private static volatile ListeningExecutorService sListeningService;
+
+    /**
+     * Returns true if the current thread is the UI thread.
+     */
+    public static boolean isMainThread() {
+        if (sMainThread == null) {
+            sMainThread = Looper.getMainLooper().getThread();
+        }
+        return Thread.currentThread() == sMainThread;
+    }
+
+    /**
+     * Returns a shared UI thread handler.
+     */
+    @NonNull
+    public static Handler getUiThreadHandler() {
+        if (sMainThreadHandler == null) {
+            sMainThreadHandler = new Handler(Looper.getMainLooper());
+        }
+
+        return sMainThreadHandler;
+    }
+
+    /**
+     * Checks that the current thread is the UI thread. Otherwise throws an exception.
+     */
+    public static void ensureMainThread() {
+        if (!isMainThread()) {
+            throw new RuntimeException("Must be called on the UI thread");
+        }
+    }
+
+    /**
+     * Posts runnable in background using shared background thread pool.
+     *
+     * @return A future of the task that can be monitored for updates or cancelled.
+     */
+    @SuppressWarnings("rawtypes")
+    @NonNull
+    public static ListenableFuture postOnBackgroundThread(@NonNull Runnable runnable) {
+        return getBackgroundExecutor().submit(runnable);
+    }
+
+    /**
+     * Posts callable in background using shared background thread pool.
+     *
+     * @return A future of the task that can be monitored for updates or cancelled.
+     */
+    @NonNull
+    public static <T> ListenableFuture<T> postOnBackgroundThread(@NonNull Callable<T> callable) {
+        return getBackgroundExecutor().submit(callable);
+    }
+
+    /**
+     * Posts the runnable on the main thread.
+     *
+     * @deprecated moving work to the main thread should be done via the main executor provided to
+     * {@link com.google.common.util.concurrent.FutureCallback} via
+     * {@link android.content.Context#getMainExecutor()} or by calling an SDK method such as
+     * {@link android.app.Activity#runOnUiThread(Runnable)} or
+     * {@link android.content.Context#getMainThreadHandler()} where appropriate.
+     */
+    @Deprecated
+    public static void postOnMainThread(@NonNull Runnable runnable) {
+        getUiThreadHandler().post(runnable);
+    }
+
+    /**
+     * Provides a shared {@link ListeningExecutorService} created using a fixed thread pool executor
+     */
+    @NonNull
+    public static synchronized ListeningExecutorService getBackgroundExecutor() {
+        if (sListeningService == null) {
+            sListeningService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(
+                    Runtime.getRuntime().availableProcessors()));
+        }
+        return sListeningService;
+    }
+}
diff --git a/packages/SettingsLib/ProfileSelector/res/values-af/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-af/strings.xml
index 5d5b675..9b92007 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-af/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-af/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Persoonlik"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Werk"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privaat"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-am/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-am/strings.xml
index fb0f36c..3dd41dae 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-am/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-am/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"የግል"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"ሥራ"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"የግል"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ar/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ar/strings.xml
index 62b4a11..bef0caa 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ar/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ar/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"شخصي"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"للعمل"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"خاص"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-as/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-as/strings.xml
index ca3ea81..8a6d25a 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-as/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-as/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"ব্যক্তিগত"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"কৰ্মস্থান"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"ব্যক্তিগত"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-az/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-az/strings.xml
index f1412a9..6469f6f 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-az/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-az/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Şəxsi"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"İş"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Şəxsi"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-b+sr+Latn/strings.xml
index 144fb48..4cc4c2c 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-b+sr+Latn/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Lično"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Posao"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privatno"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-be/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-be/strings.xml
index f7d8200..e21f430 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-be/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-be/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Асабістыя"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Працоўныя"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Прыватнае"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-bg/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-bg/strings.xml
index 4ecff11..38b596d 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-bg/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-bg/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Лични"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Служебни"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Частен"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-bn/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-bn/strings.xml
index e22e399..a6dba8a 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-bn/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-bn/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"ব্যক্তিগত"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"অফিস"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"ব্যক্তিগত"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-bs/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-bs/strings.xml
index e3b6339..1afcbf0 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-bs/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-bs/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Lično"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Poslovno"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privatno"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ca/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ca/strings.xml
index 1d79a7d..89c6150 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ca/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ca/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personal"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Feina"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privat"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-cs/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-cs/strings.xml
index 85e8432..d50fc9a 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-cs/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-cs/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Osobní"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Prácovní"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Soukromé"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-da/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-da/strings.xml
index 770fdbc..2a6bdac 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-da/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-da/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personlig"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Arbejde"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privat"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-de/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-de/strings.xml
index 37c05c4..bb9a6a9 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-de/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-de/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Privat"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Dienstlich"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privat"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-el/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-el/strings.xml
index 10056bb..628388d 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-el/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-el/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Προσωπικά"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Εργασία"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Ιδιωτικό"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-en-rAU/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-en-rAU/strings.xml
index 5bc205d..d67912f 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-en-rAU/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personal"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Work"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Private"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-en-rGB/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-en-rGB/strings.xml
index 5bc205d..d67912f 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-en-rGB/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personal"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Work"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Private"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-en-rIN/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-en-rIN/strings.xml
index 5bc205d..d67912f 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-en-rIN/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personal"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Work"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Private"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-es-rUS/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-es-rUS/strings.xml
index 73cb0f8..a76700a 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-es-rUS/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personal"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Trabajo"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privado"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-es/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-es/strings.xml
index 73cb0f8..a76700a 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-es/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-es/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personal"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Trabajo"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privado"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-eu/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-eu/strings.xml
index 5110b45..921874e 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-eu/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-eu/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Pertsonala"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Lanekoa"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Pribatua"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-fa/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-fa/strings.xml
index 03b8ba1..07c0fac 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-fa/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-fa/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"شخصی"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"محل کار"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"خصوصی"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-fi/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-fi/strings.xml
index 2c9126c..df1db99 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-fi/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-fi/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Henkilökohtainen"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Työ"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Yksityinen"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-fr-rCA/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-fr-rCA/strings.xml
index 8ab5238..c9ba591 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-fr-rCA/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personnel"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Professionnel"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privé"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-fr/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-fr/strings.xml
index 8ab5238..c9ba591 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-fr/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-fr/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personnel"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Professionnel"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privé"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-gu/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-gu/strings.xml
index 1a8f09a..f495cde 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-gu/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-gu/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"વ્યક્તિગત"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"ઑફિસ"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"ખાનગી"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-hi/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-hi/strings.xml
index eda9af1..e55f48e 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-hi/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-hi/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"निजी ऐप्लिकेशन"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"वर्क"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"निजी"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-hr/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-hr/strings.xml
index b6188ef..1fd58cc 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-hr/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-hr/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Osobno"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Posao"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privatno"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-hu/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-hu/strings.xml
index 10fa94f..732527cb 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-hu/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-hu/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Személyes"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Munkahelyi"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privát"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-hy/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-hy/strings.xml
index eaf21de..a36078c 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-hy/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-hy/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Անձնական"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Աշխատանքային"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Անձնական"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-in/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-in/strings.xml
index d8de292..3859f87 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-in/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-in/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Pribadi"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Kerja"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Pribadi"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-is/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-is/strings.xml
index b4ecc12..75668e8 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-is/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-is/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Persónulegt"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Vinna"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Lokað"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-it/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-it/strings.xml
index eed793d..42dc312 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-it/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-it/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personale"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Lavoro"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privato"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-iw/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-iw/strings.xml
index cbf58b7..850c10c 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-iw/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-iw/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"פרופיל אישי"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"פרופיל עבודה"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"פרטי"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ja/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ja/strings.xml
index 8af4d8b..21419e6 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ja/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ja/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"個人用"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"仕事用"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"非公開"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ka/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ka/strings.xml
index 5dac3d8..d6c2e6d 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ka/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ka/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"პირადი"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"სამსახური"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"პირადი"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-kk/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-kk/strings.xml
index 2250a8c..4741f21 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-kk/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-kk/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Жеке"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Жұмыс істейтін"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Жеке"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-km/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-km/strings.xml
index 119e89a..a8630695 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-km/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-km/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"ផ្ទាល់ខ្លួន"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"ការងារ"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"ឯកជន"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-kn/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-kn/strings.xml
index 7ad03c3..7204586 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-kn/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-kn/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"ವೈಯಕ್ತಿಕ"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"ಕೆಲಸ"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"ಖಾಸಗಿ"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ko/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ko/strings.xml
index 105b437..be305b1 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ko/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ko/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"개인"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"업무"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"비공개"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ky/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ky/strings.xml
index 58e52d2..4766066 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ky/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ky/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Жеке"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Жумуш"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Купуя"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-lo/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-lo/strings.xml
index a2cedbc..2e199c4 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-lo/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-lo/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"ສ່ວນຕົວ"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"ບ່ອນເຮັດວຽກ"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"ສ່ວນຕົວ"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-lt/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-lt/strings.xml
index 96cc949..6514c40 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-lt/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-lt/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Asmeninė"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Darbo"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privatus"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-lv/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-lv/strings.xml
index 6e1166f..ffa9b81 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-lv/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-lv/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personīgais"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Darba"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privāts"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-mk/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-mk/strings.xml
index 40d1714c..07cf9c7 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-mk/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-mk/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Лични"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Работа"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Приватен"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ml/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ml/strings.xml
index 43b916f..0f8d8f0 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ml/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ml/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"വ്യക്തിപരം"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"ഔദ്യോഗികം"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"സ്വകാര്യം"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-mn/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-mn/strings.xml
index 5a60d6a..4bc230e 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-mn/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-mn/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Хувийн"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Ажил"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Хувийн"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-mr/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-mr/strings.xml
index dfde95a..0e412e0 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-mr/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-mr/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"वैयक्तिक"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"ऑफिस"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"खाजगी"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ms/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ms/strings.xml
index 49f957b..e1145c3 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ms/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ms/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Peribadi"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Kerja"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Peribadi"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-my/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-my/strings.xml
index ec98763..060dc2e 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-my/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-my/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"ကိုယ်ရေးကိုယ်တာ"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"အလုပ်"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"သီးသန့်"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-nb/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-nb/strings.xml
index 98ac66d..a428099 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-nb/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-nb/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personlig"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Jobb"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privat"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ne/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ne/strings.xml
index 8385a5a..ca17836f 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ne/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ne/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"व्यक्तिगत"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"कामसम्बन्धी"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"निजी"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-nl/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-nl/strings.xml
index aee9f4b..5ba850f 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-nl/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-nl/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Persoonlijk"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Werk"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privé"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-or/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-or/strings.xml
index 21d28a4..fd2e491 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-or/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-or/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"ବ୍ୟକ୍ତିଗତ"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"ୱାର୍କ"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"ପ୍ରାଇଭେଟ"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-pa/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-pa/strings.xml
index b591c04..025c1be 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-pa/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-pa/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"ਨਿੱਜੀ"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"ਕਾਰਜ"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"ਨਿੱਜੀ"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-pt-rBR/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-pt-rBR/strings.xml
index 4afb4471..eb33d57 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-pt-rBR/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Pessoal"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Trabalho"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Particular"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-pt/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-pt/strings.xml
index 4afb4471..eb33d57 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-pt/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-pt/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Pessoal"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Trabalho"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Particular"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ro/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ro/strings.xml
index 44cec967..1405b7d 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ro/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ro/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personal"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Serviciu"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privat"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ru/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ru/strings.xml
index ce6df63..ee4212f 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ru/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ru/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Личный профиль"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Рабочий профиль"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Личное"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-si/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-si/strings.xml
index e937726..c4425e7 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-si/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-si/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"පුද්ගලික"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"කාර්ය"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"පෞද්ගලික"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-sk/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-sk/strings.xml
index bce4983..da02fb9 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-sk/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-sk/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Osobné"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Pracovné"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Súkromné"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-sl/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-sl/strings.xml
index 097a833..93739db 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-sl/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-sl/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Osebno"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Delo"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Zasebno"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-sq/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-sq/strings.xml
index 22d6c7b..f69248e 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-sq/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-sq/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personale"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Puna"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privat"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-sr/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-sr/strings.xml
index a0db83f..9c5e09f 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-sr/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-sr/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Лично"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Посао"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Приватно"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-sv/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-sv/strings.xml
index 78fe78e..8a570b2 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-sv/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-sv/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Privat"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Arbete"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Privat"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-sw/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-sw/strings.xml
index 854b0e8..acf0946 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-sw/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-sw/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Binafsi"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Kazini"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Faragha"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ta/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ta/strings.xml
index 4718055..e7e33d7 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ta/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ta/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"தனிப்பட்டவை"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"பணி"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"தனிப்பட்டவை"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-te/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-te/strings.xml
index a96403c..3057a2a 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-te/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-te/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"వ్యక్తిగతం"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"వర్క్"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"ప్రైవేట్"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-th/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-th/strings.xml
index b7ef3e5..06b919b 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-th/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-th/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"ส่วนตัว"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"งาน"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"ส่วนตัว"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-tl/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-tl/strings.xml
index 8e4e0d4..5a28b12 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-tl/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-tl/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Personal"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Trabaho"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Pribado"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-tr/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-tr/strings.xml
index 3a34ad8..59f21c8 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-tr/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-tr/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Kişisel"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"İş"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Gizli"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-uk/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-uk/strings.xml
index 5cde1b0..76ab328 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-uk/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-uk/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Особисті"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Робочі"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Приватний профіль"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-ur/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-ur/strings.xml
index 908b872..3b279bd 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-ur/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-ur/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"ذاتی"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"کام"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"نجی"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-uz/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-uz/strings.xml
index ea57a3a..50ccf1de 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-uz/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-uz/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Shaxsiy"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Ish"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Yopiq"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-vi/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-vi/strings.xml
index 4a4c13a..5f66706 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-vi/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-vi/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"Cá nhân"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"Công việc"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"Riêng tư"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-zh-rCN/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-zh-rCN/strings.xml
index f36778f..1ea211b 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-zh-rCN/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"个人"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"工作"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"私密"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-zh-rHK/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-zh-rHK/strings.xml
index 823ce80..4da7cf5 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-zh-rHK/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"個人"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"工作"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"私人"</string>
 </resources>
diff --git a/packages/SettingsLib/ProfileSelector/res/values-zh-rTW/strings.xml b/packages/SettingsLib/ProfileSelector/res/values-zh-rTW/strings.xml
index 823ce80..4da7cf5 100644
--- a/packages/SettingsLib/ProfileSelector/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/ProfileSelector/res/values-zh-rTW/strings.xml
@@ -19,6 +19,5 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="settingslib_category_personal" msgid="1142302328104700620">"個人"</string>
     <string name="settingslib_category_work" msgid="4867750733682444676">"工作"</string>
-    <!-- no translation found for settingslib_category_private (5039276873477591386) -->
-    <skip />
+    <string name="settingslib_category_private" msgid="5039276873477591386">"私人"</string>
 </resources>
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/values-ar/strings.xml b/packages/SettingsLib/RestrictedLockUtils/res/values-ar/strings.xml
index 42cf761..581b914 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/values-ar/strings.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/values-ar/strings.xml
@@ -18,5 +18,5 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="enabled_by_admin" msgid="6630472777476410137">"يفعِّل المشرف هذا الإعداد."</string>
-    <string name="disabled_by_admin" msgid="4023569940620832713">"أوقف المشرف هذا الإعداد."</string>
+    <string name="disabled_by_admin" msgid="4023569940620832713">"أوقف المشرف هذا الإعداد"</string>
 </resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-or/strings.xml b/packages/SettingsLib/SearchWidget/res/values-or/strings.xml
index 4f92d02..07f090f 100644
--- a/packages/SettingsLib/SearchWidget/res/values-or/strings.xml
+++ b/packages/SettingsLib/SearchWidget/res/values-or/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="search_menu" msgid="1914043873178389845">"ସେଟିଂସରେ ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
+    <string name="search_menu" msgid="1914043873178389845">"ସର୍ଚ୍ଚ ସେଟିଂସ"</string>
 </resources>
diff --git a/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml b/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml
new file mode 100644
index 0000000..01dfd7d
--- /dev/null
+++ b/packages/SettingsLib/SettingsTheme/res/values-v35/themes.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2024 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<resources>
+    <style name="Theme.SettingsBase" parent="Theme.SettingsBase_v31" >
+        <item name="android:spinnerStyle">@style/Spinner.SettingsLib</item>
+        <item name="android:spinnerItemStyle">@style/SpinnerItem.SettingsLib</item>
+        <item name="android:spinnerDropDownItemStyle">@style/SpinnerDropDownItem.SettingsLib</item>
+
+        <item name="android:colorAccent">@color/settingslib_materialColorPrimary</item>
+        <!-- component module background -->
+        <item name="android:colorBackground">@color/settingslib_materialColorSurfaceContainer</item>
+        <item name="android:textColorPrimary">@color/settingslib_materialColorOnSurface</item>
+        <item name="android:textColorSecondary">@color/settingslib_materialColorOnSurfaceVariant</item>
+        <item name="android:textColorTertiary">@color/settingslib_materialColorOutline</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsDropdownCheckBoxProvider.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsDropdownCheckBoxProvider.kt
index 33ab75d..466ccf8 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsDropdownCheckBoxProvider.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/editor/SettingsDropdownCheckBoxProvider.kt
@@ -73,8 +73,8 @@
                 label = "With disabled item",
                 options = remember {
                     listOf(
-                        SettingsDropdownCheckOption("Item 1"),
-                        SettingsDropdownCheckOption("Item 2"),
+                        SettingsDropdownCheckOption("Enabled item 1"),
+                        SettingsDropdownCheckOption("Enabled item 2"),
                         SettingsDropdownCheckOption(
                             text = "Disabled item 1",
                             changeable = false,
@@ -101,8 +101,8 @@
                 remember {
                     listOf(
                         SettingsDropdownCheckOption("All", isSelectAll = true, changeable = false),
-                        SettingsDropdownCheckOption("Item 1"),
-                        SettingsDropdownCheckOption("Item 2"),
+                        SettingsDropdownCheckOption("Enabled item 1"),
+                        SettingsDropdownCheckOption("Enabled item 2"),
                         SettingsDropdownCheckOption(
                             text = "Disabled item 1",
                             changeable = false,
diff --git a/packages/SettingsLib/Spa/spa/res/values/themes.xml b/packages/SettingsLib/Spa/spa/res/values/themes.xml
index b55dd1b..a6d8ca4 100644
--- a/packages/SettingsLib/Spa/spa/res/values/themes.xml
+++ b/packages/SettingsLib/Spa/spa/res/values/themes.xml
@@ -23,7 +23,10 @@
         <item name="android:windowNoTitle">true</item>
     </style>
 
-    <style name="Theme.SpaLib.Dialog" parent="Theme.Material3.DayNight.Dialog"/>
+    <style name="Theme.SpaLib.Dialog" parent="Theme.Material3.DayNight.Dialog">
+        <item name="android:windowBackground">@android:color/transparent</item>
+    </style>
+
     <style name="Theme.SpaLib.BottomSheetDialog" parent="Theme.SpaLib">
         <item name="android:windowBackground">@android:color/transparent</item>
         <item name="android:windowIsTranslucent">true</item>
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/SpaDialogWindowTypeActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/SpaDialogWindowTypeActivity.kt
new file mode 100644
index 0000000..46975f5
--- /dev/null
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/SpaDialogWindowTypeActivity.kt
@@ -0,0 +1,78 @@
+/*
+ * 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.settingslib.spa
+
+import android.content.Context
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.appcompat.app.AlertDialog
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.ComposeView
+import com.android.settingslib.spa.framework.common.LogCategory
+import com.android.settingslib.spa.framework.common.SpaEnvironmentFactory
+import com.android.settingslib.spa.framework.theme.SettingsTheme
+
+/**
+ * Dialog activity when the dialog window type need to be override.
+ *
+ * Please use [SpaBaseDialogActivity] for all other use cases.
+ */
+abstract class SpaDialogWindowTypeActivity : ComponentActivity() {
+    private val spaEnvironment get() = SpaEnvironmentFactory.instance
+    private var dialog: AlertDialogWithType? = null
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        spaEnvironment.logger.message(TAG, "onCreate", category = LogCategory.FRAMEWORK)
+
+        dialog = AlertDialogWithType(this).apply { show() }
+    }
+
+    override fun finish() {
+        dialog?.dismiss()
+        super.finish()
+    }
+
+    abstract val dialogWindowType: Int?
+
+    @Composable
+    abstract fun Content()
+
+    inner class AlertDialogWithType(context: Context) :
+        AlertDialog(context, R.style.Theme_SpaLib_Dialog) {
+
+        init {
+            setView(ComposeView(context).apply {
+                setContent {
+                    SettingsTheme {
+                        this@SpaDialogWindowTypeActivity.Content()
+                    }
+                }
+            })
+            setOnDismissListener { finish() }
+        }
+
+        override fun onCreate(savedInstanceState: Bundle?) {
+            dialogWindowType?.let { window?.setType(it) }
+            super.onCreate(savedInstanceState)
+        }
+    }
+
+    companion object {
+        private const val TAG = "SpaBaseDialogActivity"
+    }
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt
index d72ec26..69aba71 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt
@@ -33,10 +33,6 @@
     val secondaryText: Color = Color.Unspecified,
     val primaryContainer: Color = Color.Unspecified,
     val onPrimaryContainer: Color = Color.Unspecified,
-    val spinnerHeaderContainer: Color = Color.Unspecified,
-    val onSpinnerHeaderContainer: Color = Color.Unspecified,
-    val spinnerItemContainer: Color = Color.Unspecified,
-    val onSpinnerItemContainer: Color = Color.Unspecified,
 )
 
 internal val LocalColorScheme = staticCompositionLocalOf { SettingsColorScheme() }
@@ -76,10 +72,6 @@
         secondaryText = tonalPalette.neutralVariant30,
         primaryContainer = tonalPalette.primary90,
         onPrimaryContainer = tonalPalette.neutral10,
-        spinnerHeaderContainer = tonalPalette.primary90,
-        onSpinnerHeaderContainer = tonalPalette.neutral10,
-        spinnerItemContainer = tonalPalette.secondary90,
-        onSpinnerItemContainer = tonalPalette.neutralVariant30,
     )
 }
 
@@ -103,10 +95,6 @@
         secondaryText = tonalPalette.neutralVariant80,
         primaryContainer = tonalPalette.secondary90,
         onPrimaryContainer = tonalPalette.neutral10,
-        spinnerHeaderContainer = tonalPalette.primary90,
-        onSpinnerHeaderContainer = tonalPalette.neutral10,
-        spinnerItemContainer = tonalPalette.secondary90,
-        onSpinnerItemContainer = tonalPalette.neutralVariant30,
     )
 }
 
@@ -121,10 +109,6 @@
         secondaryText = tonalPalette.neutralVariant80,
         primaryContainer = tonalPalette.secondary90,
         onPrimaryContainer = tonalPalette.neutral10,
-        spinnerHeaderContainer = tonalPalette.primary90,
-        onSpinnerHeaderContainer = tonalPalette.neutral10,
-        spinnerItemContainer = tonalPalette.secondary90,
-        onSpinnerItemContainer = tonalPalette.neutralVariant30,
     )
 }
 
@@ -139,9 +123,5 @@
         secondaryText = tonalPalette.neutralVariant30,
         primaryContainer = tonalPalette.primary90,
         onPrimaryContainer = tonalPalette.neutral10,
-        spinnerHeaderContainer = tonalPalette.primary90,
-        onSpinnerHeaderContainer = tonalPalette.neutral10,
-        spinnerItemContainer = tonalPalette.secondary90,
-        onSpinnerItemContainer = tonalPalette.neutralVariant30,
     )
 }
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlterDialogContent.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlterDialogContent.kt
new file mode 100644
index 0000000..bef0bca
--- /dev/null
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/dialog/SettingsAlterDialogContent.kt
@@ -0,0 +1,309 @@
+/*
+ * 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.settingslib.spa.widget.dialog
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.WarningAmber
+import androidx.compose.material3.AlertDialogDefaults
+import androidx.compose.material3.Button
+import androidx.compose.material3.Icon
+import androidx.compose.material3.LocalContentColor
+import androidx.compose.material3.LocalTextStyle
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.OutlinedButton
+import androidx.compose.material3.Surface
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.layout.Placeable
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastForEach
+import androidx.compose.ui.util.fastForEachIndexed
+import com.android.settingslib.spa.framework.theme.SettingsShape
+import kotlin.math.max
+
+@Composable
+fun SettingsAlertDialogContent(
+    confirmButton: AlertDialogButton?,
+    dismissButton: AlertDialogButton?,
+    title: String?,
+    icon: @Composable (() -> Unit)? = {
+        Icon(
+            Icons.Default.WarningAmber,
+            contentDescription = null
+        )
+    },
+    text: @Composable (() -> Unit)?,
+) {
+    SettingsAlertDialogContent(
+        buttons = {
+            AlertDialogFlowRow(
+                mainAxisSpacing = ButtonsMainAxisSpacing,
+                crossAxisSpacing = ButtonsCrossAxisSpacing
+            ) {
+                dismissButton?.let {
+                    OutlinedButton(onClick = it.onClick) {
+                        Text(it.text)
+                    }
+                }
+                confirmButton?.let {
+                    Button(
+                        onClick = {
+                            it.onClick()
+                        },
+                    ) {
+                        Text(it.text)
+                    }
+                }
+            }
+        },
+        icon = icon,
+        modifier = Modifier.width(getDialogWidth()),
+        title = title?.let {
+            {
+                Text(
+                    it,
+                    modifier = Modifier.fillMaxWidth(),
+                    textAlign = TextAlign.Center
+                )
+            }
+        },
+        text = text?.let {
+            {
+                Column(Modifier.verticalScroll(rememberScrollState())) {
+                    text()
+                }
+            }
+        },
+    )
+}
+
+@Composable
+internal fun SettingsAlertDialogContent(
+    buttons: @Composable () -> Unit,
+    modifier: Modifier = Modifier,
+    icon: (@Composable () -> Unit)?,
+    title: (@Composable () -> Unit)?,
+    text: @Composable (() -> Unit)?,
+) {
+    Surface(
+        modifier = modifier,
+        shape = SettingsShape.CornerExtraLarge,
+        color = MaterialTheme.colorScheme.surfaceContainerHigh,
+    ) {
+        Column(
+            modifier = Modifier.padding(DialogPadding)
+        ) {
+            icon?.let {
+                CompositionLocalProvider(
+                    LocalContentColor provides AlertDialogDefaults.iconContentColor,
+                ) {
+                    Box(
+                        Modifier
+                            .padding(IconPadding)
+                            .align(Alignment.CenterHorizontally)
+                    ) {
+                        icon()
+                    }
+                }
+            }
+            title?.let {
+                ProvideContentColorTextStyle(
+                    contentColor = AlertDialogDefaults.titleContentColor,
+                    textStyle = MaterialTheme.typography.headlineSmall,
+                ) {
+                    Box(
+                        // Align the title to the center when an icon is present.
+                        Modifier
+                            .padding(TitlePadding)
+                            .align(
+                                if (icon == null) {
+                                    Alignment.Start
+                                } else {
+                                    Alignment.CenterHorizontally
+                                }
+                            )
+                    ) {
+                        title()
+                    }
+                }
+            }
+            text?.let {
+                ProvideContentColorTextStyle(
+                    contentColor = AlertDialogDefaults.textContentColor,
+                    textStyle = MaterialTheme.typography.bodyMedium
+                ) {
+                    Box(
+                        Modifier
+                            .weight(weight = 1f, fill = false)
+                            .padding(TextPadding)
+                            .align(Alignment.Start)
+                    ) {
+                        text()
+                    }
+                }
+            }
+            Box(modifier = Modifier.align(Alignment.End)) {
+                ProvideContentColorTextStyle(
+                    contentColor = MaterialTheme.colorScheme.primary,
+                    textStyle = MaterialTheme.typography.labelLarge,
+                    content = buttons
+                )
+            }
+        }
+    }
+}
+
+@Composable
+internal fun AlertDialogFlowRow(
+    mainAxisSpacing: Dp,
+    crossAxisSpacing: Dp,
+    content: @Composable () -> Unit
+) {
+    Layout(content) { measurables, constraints ->
+        val sequences = mutableListOf<List<Placeable>>()
+        val crossAxisSizes = mutableListOf<Int>()
+        val crossAxisPositions = mutableListOf<Int>()
+
+        var mainAxisSpace = 0
+        var crossAxisSpace = 0
+
+        val currentSequence = mutableListOf<Placeable>()
+        var currentMainAxisSize = 0
+        var currentCrossAxisSize = 0
+
+        // Return whether the placeable can be added to the current sequence.
+        fun canAddToCurrentSequence(placeable: Placeable) =
+            currentSequence.isEmpty() || currentMainAxisSize + mainAxisSpacing.roundToPx() +
+                placeable.width <= constraints.maxWidth
+
+        // Store current sequence information and start a new sequence.
+        fun startNewSequence() {
+            if (sequences.isNotEmpty()) {
+                crossAxisSpace += crossAxisSpacing.roundToPx()
+            }
+            // Ensures that confirming actions appear above dismissive actions.
+            @Suppress("ListIterator")
+            sequences.add(0, currentSequence.toList())
+            crossAxisSizes += currentCrossAxisSize
+            crossAxisPositions += crossAxisSpace
+
+            crossAxisSpace += currentCrossAxisSize
+            mainAxisSpace = max(mainAxisSpace, currentMainAxisSize)
+
+            currentSequence.clear()
+            currentMainAxisSize = 0
+            currentCrossAxisSize = 0
+        }
+
+        measurables.fastForEach { measurable ->
+            // Ask the child for its preferred size.
+            val placeable = measurable.measure(constraints)
+
+            // Start a new sequence if there is not enough space.
+            if (!canAddToCurrentSequence(placeable)) startNewSequence()
+
+            // Add the child to the current sequence.
+            if (currentSequence.isNotEmpty()) {
+                currentMainAxisSize += mainAxisSpacing.roundToPx()
+            }
+            currentSequence.add(placeable)
+            currentMainAxisSize += placeable.width
+            currentCrossAxisSize = max(currentCrossAxisSize, placeable.height)
+        }
+
+        if (currentSequence.isNotEmpty()) startNewSequence()
+
+        val mainAxisLayoutSize = max(mainAxisSpace, constraints.minWidth)
+
+        val crossAxisLayoutSize = max(crossAxisSpace, constraints.minHeight)
+
+        val layoutWidth = mainAxisLayoutSize
+
+        val layoutHeight = crossAxisLayoutSize
+
+        layout(layoutWidth, layoutHeight) {
+            sequences.fastForEachIndexed { i, placeables ->
+                val childrenMainAxisSizes = IntArray(placeables.size) { j ->
+                    placeables[j].width +
+                        if (j < placeables.lastIndex) mainAxisSpacing.roundToPx() else 0
+                }
+                val arrangement = Arrangement.End
+                val mainAxisPositions = IntArray(childrenMainAxisSizes.size) { 0 }
+                with(arrangement) {
+                    arrange(
+                        mainAxisLayoutSize, childrenMainAxisSizes,
+                        layoutDirection, mainAxisPositions
+                    )
+                }
+                placeables.fastForEachIndexed { j, placeable ->
+                    placeable.place(
+                        x = mainAxisPositions[j],
+                        y = crossAxisPositions[i]
+                    )
+                }
+            }
+        }
+    }
+}
+
+// Paddings for each of the dialog's parts.
+private val DialogPadding = PaddingValues(all = 24.dp)
+private val IconPadding = PaddingValues(bottom = 16.dp)
+private val TitlePadding = PaddingValues(bottom = 16.dp)
+private val TextPadding = PaddingValues(bottom = 24.dp)
+
+private val ButtonsMainAxisSpacing = 8.dp
+private val ButtonsCrossAxisSpacing = 12.dp
+
+/**
+ * ProvideContentColorTextStyle
+ *
+ * A convenience method to provide values to both LocalContentColor and LocalTextStyle in
+ * one call. This is less expensive than nesting calls to CompositionLocalProvider.
+ *
+ * Text styles will be merged with the current value of LocalTextStyle.
+ */
+@Composable
+private fun ProvideContentColorTextStyle(
+    contentColor: Color,
+    textStyle: TextStyle,
+    content: @Composable () -> Unit
+) {
+    val mergedStyle = LocalTextStyle.current.merge(textStyle)
+    CompositionLocalProvider(
+        LocalContentColor provides contentColor,
+        LocalTextStyle provides mergedStyle,
+        content = content
+    )
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/DropdownTextBox.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/DropdownTextBox.kt
index 679c562..b471e50 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/DropdownTextBox.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/DropdownTextBox.kt
@@ -44,6 +44,7 @@
     text: String,
     enabled: Boolean = true,
     errorMessage: String? = null,
+    singleLine: Boolean = true,
     content: @Composable DropdownTextBoxScope.() -> Unit,
 ) {
     var expanded by remember { mutableStateOf(false) }
@@ -70,7 +71,7 @@
             onValueChange = { },
             label = { Text(text = label) },
             trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
-            singleLine = true,
+            singleLine = singleLine,
             readOnly = true,
             enabled = enabled,
             isError = errorMessage != null,
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsDropdownCheckBox.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsDropdownCheckBox.kt
index 2de73c0..a3ad402 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsDropdownCheckBox.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsDropdownCheckBox.kt
@@ -74,6 +74,7 @@
         text = getDisplayText(options) ?: emptyText,
         enabled = enabled && options.changeable,
         errorMessage = errorMessage,
+        singleLine = false,
     ) {
         for (option in options) {
             CheckboxItem(option) {
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt
index 514ad669..c48a147 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt
@@ -33,6 +33,7 @@
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
@@ -74,8 +75,8 @@
             modifier = Modifier.semantics { role = Role.DropdownList },
             onClick = { expanded = true },
             colors = ButtonDefaults.buttonColors(
-                containerColor = SettingsTheme.colorScheme.spinnerHeaderContainer,
-                contentColor = SettingsTheme.colorScheme.onSpinnerHeaderContainer,
+                containerColor = MaterialTheme.colorScheme.primaryContainer,
+                contentColor = MaterialTheme.colorScheme.onPrimaryContainer,
             ),
             contentPadding = contentPadding,
         ) {
@@ -85,7 +86,7 @@
         DropdownMenu(
             expanded = expanded,
             onDismissRequest = { expanded = false },
-            modifier = Modifier.background(SettingsTheme.colorScheme.spinnerItemContainer),
+            modifier = Modifier.background(MaterialTheme.colorScheme.secondaryContainer),
         ) {
             for (option in options) {
                 DropdownMenuItem(
@@ -93,7 +94,7 @@
                         SpinnerText(
                             option = option,
                             modifier = Modifier.padding(end = 24.dp),
-                            color = SettingsTheme.colorScheme.onSpinnerItemContainer,
+                            color = MaterialTheme.colorScheme.onSecondaryContainer,
                         )
                     },
                     onClick = {
@@ -138,7 +139,7 @@
 @Composable
 private fun SpinnerPreview() {
     SettingsTheme {
-        var selectedId by rememberSaveable { mutableStateOf(1) }
+        var selectedId by rememberSaveable { mutableIntStateOf(1) }
         Spinner(
             options = (1..3).map { SpinnerOption(id = it, text = "Option $it") },
             selectedId = selectedId,
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/theme/SettingsColorsTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/theme/SettingsColorsTest.kt
index 5ea92ab..625663d 100644
--- a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/theme/SettingsColorsTest.kt
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/framework/theme/SettingsColorsTest.kt
@@ -37,15 +37,11 @@
         assertThat(ls.categoryTitle).isNotEqualTo(ls.background)
         assertThat(ls.secondaryText).isNotEqualTo(ls.background)
         assertThat(ls.primaryContainer).isNotEqualTo(ls.onPrimaryContainer)
-        assertThat(ls.spinnerHeaderContainer).isNotEqualTo(ls.onSpinnerHeaderContainer)
-        assertThat(ls.spinnerItemContainer).isNotEqualTo(ls.onSpinnerItemContainer)
 
         val ds = dynamicDarkColorScheme(context)
         assertThat(ds.categoryTitle).isNotEqualTo(ds.background)
         assertThat(ds.secondaryText).isNotEqualTo(ds.background)
         assertThat(ds.primaryContainer).isNotEqualTo(ds.onPrimaryContainer)
-        assertThat(ds.spinnerHeaderContainer).isNotEqualTo(ds.onSpinnerHeaderContainer)
-        assertThat(ds.spinnerItemContainer).isNotEqualTo(ds.onSpinnerItemContainer)
     }
 
     @Test
@@ -58,10 +54,6 @@
         assertThat(ls.secondaryText).isEqualTo(Color(red = 73, green = 69, blue = 79))
         assertThat(ls.primaryContainer).isEqualTo(Color(red = 234, green = 221, blue = 255))
         assertThat(ls.onPrimaryContainer).isEqualTo(Color(red = 28, green = 27, blue = 31))
-        assertThat(ls.spinnerHeaderContainer).isEqualTo(Color(red = 234, green = 221, blue = 255))
-        assertThat(ls.onSpinnerHeaderContainer).isEqualTo(Color(red = 28, green = 27, blue = 31))
-        assertThat(ls.spinnerItemContainer).isEqualTo(Color(red = 232, green = 222, blue = 248))
-        assertThat(ls.onSpinnerItemContainer).isEqualTo(Color(red = 73, green = 69, blue = 79))
 
         val ds = darkColorScheme()
         assertThat(ds.background).isEqualTo(Color(red = 28, green = 27, blue = 31))
@@ -71,9 +63,5 @@
         assertThat(ds.secondaryText).isEqualTo(Color(red = 202, green = 196, blue = 208))
         assertThat(ds.primaryContainer).isEqualTo(Color(red = 232, green = 222, blue = 248))
         assertThat(ds.onPrimaryContainer).isEqualTo(Color(red = 28, green = 27, blue = 31))
-        assertThat(ds.spinnerHeaderContainer).isEqualTo(Color(red = 234, green = 221, blue = 255))
-        assertThat(ds.onSpinnerHeaderContainer).isEqualTo(Color(red = 28, green = 27, blue = 31))
-        assertThat(ds.spinnerItemContainer).isEqualTo(Color(red = 232, green = 222, blue = 248))
-        assertThat(ds.onSpinnerItemContainer).isEqualTo(Color(red = 73, green = 69, blue = 79))
     }
 }
diff --git a/packages/SettingsLib/SpaPrivileged/res/values-pt-rBR/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-pt-rBR/strings.xml
index ba92ebb6..6ae2928 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values-pt-rBR/strings.xml
@@ -21,7 +21,7 @@
     <string name="menu_show_system" msgid="906304605807554788">"Mostrar sistema"</string>
     <string name="menu_hide_system" msgid="374571689914923020">"Ocultar sistema"</string>
     <string name="app_permission_summary_allowed" msgid="6115213465364138103">"Permitido"</string>
-    <string name="app_permission_summary_not_allowed" msgid="58396132188553920">"Não permitido"</string>
+    <string name="app_permission_summary_not_allowed" msgid="58396132188553920">"Sem permissão"</string>
     <string name="version_text" msgid="4001669804596458577">"Versão <xliff:g id="VERSION_NUM">%1$s</xliff:g>"</string>
     <string name="cloned_app_info_label" msgid="1765651167024478391">"Clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/SpaPrivileged/res/values-pt/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-pt/strings.xml
index ba92ebb6..6ae2928 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values-pt/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values-pt/strings.xml
@@ -21,7 +21,7 @@
     <string name="menu_show_system" msgid="906304605807554788">"Mostrar sistema"</string>
     <string name="menu_hide_system" msgid="374571689914923020">"Ocultar sistema"</string>
     <string name="app_permission_summary_allowed" msgid="6115213465364138103">"Permitido"</string>
-    <string name="app_permission_summary_not_allowed" msgid="58396132188553920">"Não permitido"</string>
+    <string name="app_permission_summary_not_allowed" msgid="58396132188553920">"Sem permissão"</string>
     <string name="version_text" msgid="4001669804596458577">"Versão <xliff:g id="VERSION_NUM">%1$s</xliff:g>"</string>
     <string name="cloned_app_info_label" msgid="1765651167024478391">"Clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SettingsLib/aconfig/settingslib.aconfig b/packages/SettingsLib/aconfig/settingslib.aconfig
index 54c5a14..e09ab00 100644
--- a/packages/SettingsLib/aconfig/settingslib.aconfig
+++ b/packages/SettingsLib/aconfig/settingslib.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.settingslib.flags"
+container: "system"
 
 flag {
     name: "new_status_bar_icons"
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/res/drawable/avatar_choose_photo_circled.xml b/packages/SettingsLib/res/drawable/avatar_choose_photo_circled.xml
deleted file mode 100644
index 97aec74..0000000
--- a/packages/SettingsLib/res/drawable/avatar_choose_photo_circled.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-  ~ Copyright (C) 2022 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item>
-        <shape android:shape="oval">
-            <stroke
-                android:width="2dp"
-                android:color="?android:attr/colorPrimary"/>
-        </shape>
-    </item>
-    <item
-        android:left="@dimen/avatar_picker_icon_inset"
-        android:right="@dimen/avatar_picker_icon_inset"
-        android:top="@dimen/avatar_picker_icon_inset"
-        android:bottom="@dimen/avatar_picker_icon_inset"
-        android:drawable="@drawable/ic_avatar_choose_photo"/>
-</layer-list>
diff --git a/packages/SettingsLib/res/drawable/avatar_take_photo_circled.xml b/packages/SettingsLib/res/drawable/avatar_take_photo_circled.xml
deleted file mode 100644
index 7033aae..0000000
--- a/packages/SettingsLib/res/drawable/avatar_take_photo_circled.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!--
-  ~ Copyright (C) 2022 The Android Open Source Project
-  ~
-  ~ Licensed under the Apache License, Version 2.0 (the "License");
-  ~ you may not use this file except in compliance with the License.
-  ~ You may obtain a copy of the License at
-  ~
-  ~      http://www.apache.org/licenses/LICENSE-2.0
-  ~
-  ~ Unless required by applicable law or agreed to in writing, software
-  ~ distributed under the License is distributed on an "AS IS" BASIS,
-  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-  ~ See the License for the specific language governing permissions and
-  ~ limitations under the License.
-  -->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item>
-        <shape android:shape="oval">
-            <stroke
-                android:width="2dp"
-                android:color="?android:attr/colorPrimary"/>
-        </shape>
-    </item>
-    <item
-        android:left="@dimen/avatar_picker_icon_inset"
-        android:right="@dimen/avatar_picker_icon_inset"
-        android:top="@dimen/avatar_picker_icon_inset"
-        android:bottom="@dimen/avatar_picker_icon_inset"
-        android:drawable="@drawable/ic_avatar_take_photo"/>
-</layer-list>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 9b98e55fa..eb3d4af 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktief, net links"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktief, net regs"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktief, links en regs"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Media-oudio"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Foonoproepe"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Lêeroordrag"</string>
@@ -117,7 +139,7 @@
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Teksboodskappe"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM-toegang"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-oudio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
-    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD oudio"</string>
+    <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-oudio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="2607867572569689732">"Gehoortoestelle"</string>
     <string name="bluetooth_profile_le_audio" msgid="1725521360076451751">"LE-oudio"</string>
     <string name="bluetooth_hearing_aid_profile_summary_connected" msgid="5757754050938807276">"Gekoppel aan gehoortoestelle"</string>
@@ -265,7 +287,7 @@
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Wys \'n knoppie in die kragkieslys om \'n foutverslag te doen"</string>
     <string name="keep_screen_on" msgid="1187161672348797558">"Bly wakker"</string>
     <string name="keep_screen_on_summary" msgid="1510731514101925829">"Skerm sal nooit slaap terwyl dit laai nie"</string>
-    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Aktiveer Bluetooth HCI-loerloglêer"</string>
+    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Aktiveer Bluetooth HCI-snuffelloglêer"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Vang Bluetooth-pakkette vas. (Wissel Bluetooth nadat jy hierdie instelling verander het)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"OEM-ontsluit"</string>
     <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Laat toe dat die selflaaiprogram ontsluit word"</string>
@@ -396,7 +418,7 @@
     <string name="transition_animation_scale_title" msgid="1278477690695439337">"Oorganganimasieskaal"</string>
     <string name="animator_duration_scale_title" msgid="7082913931326085176">"Animator-tydsduurskaal"</string>
     <string name="overlay_display_devices_title" msgid="5411894622334469607">"Simuleer sekondêre uitstallings"</string>
-    <string name="debug_applications_category" msgid="5394089406638954196">"Programme"</string>
+    <string name="debug_applications_category" msgid="5394089406638954196">"Apps"</string>
     <string name="immediately_destroy_activities" msgid="1826287490705167403">"Moenie aktiwiteite behou nie"</string>
     <string name="immediately_destroy_activities_summary" msgid="6289590341144557614">"Vernietig elke aktiwiteit sodra die gebruiker dit verlaat"</string>
     <string name="app_process_limit_title" msgid="8361367869453043007">"Agtergrondproseslimiet"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Aanvaar dat programme moderne formate steun"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Wys kodewisselingkennisgewings"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Deaktiveer kodewisselingkas"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine-instellings"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Forseer terugskakeling na L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Kies vir geforseerde terugskakeling na L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Lopende dienste"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Sien en beheer dienste wat tans aktief is"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementering"</string>
@@ -518,7 +537,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Gebruik stelseltale"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Kon nie instellings vir <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> oopmaak nie"</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"Die invoermetode kan dalk alle teks wat jy invoer, versamel, insluitend persoonlike data soos wagwoorde en kredietkaartnommers. Dit kom van die program <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Wil jy dié invoermetode gebruik?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Let wel: Ná \'n herselflaai kan hierdie program nie begin voordat jy jou foon ontsluit het nie"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Let wel: Ná \'n herselflaai kan hierdie app nie begin voordat jy jou foon ontsluit het nie"</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"IMS-registrasiestaat"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"Geregistreer"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Nie geregistreer nie"</string>
@@ -630,7 +649,7 @@
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Verwyder"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Stel tans gassessie terug …"</string>
     <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Stel gastesessie terug?"</string>
-    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Dit sal ’n nuwe gastesessie begin en alle programme en data van die huidige sessie uitvee"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Dit sal ’n nuwe gastesessie begin en alle apps en data van die huidige sessie uitvee"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Verlaat gasmodus?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Dit sal programme en data in die huidige gastesessie uitvee"</string>
     <string name="grant_admin" msgid="4323199171790522574">"Ja, maak hulle ’n admin"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Alle aktiwiteit sal uitgevee word wanneer jy uitgaan"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Jy kan jou aktiwiteit stoor of uitvee wanneer jy uitgaan"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Stel terug om aktiwiteit nou uit te vee, of stoor of vee aktiwiteit uit wanneer jy uitgaan"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Neem \'n foto"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Kies \'n prent"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Kies foto"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Te veel verkeerde pogings. Hierdie toestel se data sal uitgevee word."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Te veel verkeerde pogings. Hierdie gebruiker sal uitgevee word."</string>
@@ -657,7 +674,7 @@
     <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Gedeaktiveer"</string>
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Geaktiveer"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Jou toestel moet herselflaai om hierdie verandering toe te pas. Herselflaai nou of kanselleer."</string>
-    <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Bedraade oorfoon"</string>
+    <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Bedrade oorfone"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Aan"</string>
     <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Af"</string>
     <string name="carrier_network_change_mode" msgid="4257621815706644026">"Diensverskaffernetwerk verander tans"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet is ontkoppel."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Geen oproepe nie."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Kies \'n profielprent"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Verstekgebruikerikoon"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fisieke sleutelbord"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Kies sleutelborduitleg"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Verstek"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index bfcdab4..bda0277 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"ገቢር፣ ግራ ብቻ"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"ገቢር፣ ቀኝ ብቻ"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"ገቢር፣ ግራ እና ቀኝ"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"የማህደረ መረጃ ኦዲዮ"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"የስልክ ጥሪዎች"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ፋይል ማስተላለፍ"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"መተግበሪያዎች ዘመናዊ ቅርጸቶችን እንደሚደግፉ አድርገው ይቁጠሩ"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ትራንስኮዲንግ ማሳወቂያዎችን አሳይ"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"የትራንስኮዲንግ መሸጎጫን አሰናክል"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"የWidevine ቅንብሮች"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"የL3 ተመልሶ ወዳቂ ግዳጅ"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"የL3 ተመልሶ ወዳቂን ለማስገደድ ይምረጡ"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"አሂድ አገልግሎቶች"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"በአሁኑጊዜ እየሄዱ ያሉ አገልግሎቶችን ተቆጣጠር እና እይ"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"የWebView ትግበራ"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"በሚወጡበት ጊዜ ሁሉም እንቅስቃሴዎች ይሰረዛሉ"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"በሚወጡበት ጊዜ እንቅስቃሴዎን ማስቀመጥ ወይም መሰረዝ ይችላሉ"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"የክፍለ-ጊዜ እንቅስቃሴን አሁን ለመሰረዝ ዳግም ያስጀምሩ፣ ወይም በሚወጡበት ጊዜ እንቅስቃሴን ማስቀመጥ ወይም መሰረዝ ይችላሉ"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ፎቶ አንሳ"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"ምስል ይምረጡ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ፎቶ ይምረጡ"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"በጣም ብዙ ትክክል ያልሆኑ ሙከራዎች። የዚህ መሣሪያ ውሂብ ይሰረዛል።"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"በጣም ብዙ ትክክል ያልሆኑ ሙከራዎች። ይህ ተጠቃሚ ይሰረዛል።"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ኤተርኔት ተነቅሏል።"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ኢተርኔት።"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"መደወል የለም።"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"የመገለጫ ሥዕል ይምረጡ"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"ነባሪ የተጠቃሚ አዶ"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"አካላዊ ቁልፍ ሰሌዳ"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"የቁልፍ ሰሌዳ አቀማመጥን ይምረጡ"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ነባሪ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 68a19fc..ba93f65 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"السمّاعة الطبية اليسرى فقط مفعَّلة"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"السمّاعة الطبية اليمنى فقط مفعَّلة"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"السمّاعتان اليسرى واليمنى مفعَّلتان"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"الإعدادات الصوتية للوسائط"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"المكالمات الهاتفية"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"نقل الملف"</string>
@@ -411,7 +433,7 @@
     <string name="enable_freeform_support" msgid="7599125687603914253">"تفعيل النوافذ الحرة"</string>
     <string name="enable_freeform_support_summary" msgid="1822862728719276331">"إتاحة استخدام النوافذ الحرة التجريبية"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"كلمة مرور احتياطية للكمبيوتر"</string>
-    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"النُسخ الاحتياطية الكاملة لسطح المكتب غير محمية في الوقت الحالي."</string>
+    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"النُسخ الاحتياطية الكاملة لسطح المكتب غير محمية في الوقت الحالي"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"انقر لتغيير كلمة مرور النسخ الاحتياطية الكاملة لسطح المكتب أو إزالتها."</string>
     <string name="local_backup_password_toast_success" msgid="4891666204428091604">"تم ضبط كلمة مرور احتياطية جديدة"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"كلمة المرور الجديدة وتأكيدها لا يتطابقان"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"افتراض أن التطبيق يتوافق مع التنسيقات الحديثة"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"إظهار إشعارات تحويل الترميز"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"إيقاف ذاكرة التخزين المؤقت لميزة \"تحويل الترميز\""</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"‏إعدادات Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"‏فرض الرجوع إلى المستوى L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"‏اختيار فرض الرجوع إلى المستوى L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"الخدمات قيد التشغيل"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"عرض الخدمات قيد التشغيل في الوقت الحالي والتحكم فيها"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"‏تطبيق WebView"</string>
@@ -475,7 +494,7 @@
     <string name="power_remaining_more_than_subtext" msgid="446388082266121894">"سيبقى شحن البطارية أكثر من <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)."</string>
     <string name="power_remaining_only_more_than_subtext" msgid="4873750633368888062">"سيبقى شحن البطارية أكثر من <xliff:g id="TIME_REMAINING">%1$s</xliff:g>."</string>
     <string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
-    <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"يتبقّى <xliff:g id="TIME">%1$s</xliff:g> حتى اكتمال شحن البطارية."</string>
+    <string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"يتبقّى <xliff:g id="TIME">%1$s</xliff:g> حتى اكتمال شحن البطارية"</string>
     <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - يتبقّى <xliff:g id="TIME">%2$s</xliff:g> حتى اكتمال شحن البطارية."</string>
     <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - تم تحسين الشحن"</string>
     <string name="power_charging_future_paused" msgid="1809543660923642799">"‫<xliff:g id="LEVEL">%1$s</xliff:g>: جارٍ الشحن"</string>
@@ -518,7 +537,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"استخدام لغات النظام"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"تعذّر فتح الإعدادات لـ <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"يمكن أن يكون أسلوب الإدخال هذا قادرًا على جمع كل النصوص التي تكتبها، بما في ذلك البيانات الشخصية مثل كلمات المرور وأرقام بطاقات الائتمان. يتم الحصول على هذا الأسلوب من التطبيق <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. هل تريد استخدام أسلوب الإدخال هذا؟"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"ملاحظة: بعد إعادة التشغيل، يتعذر بدء هذا التطبيق إلى أن تلغي قفل هاتفك."</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"ملاحظة: بعد إعادة التشغيل، يتعذر بدء هذا التطبيق إلى أن تلغي قفل هاتفك"</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"‏حالة تسجيل IMS"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"مُسجَّل"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"غير مُسجَّل"</string>
@@ -619,7 +638,7 @@
     <string name="add_user_failed" msgid="4809887794313944872">"تعذّر إنشاء مستخدم جديد."</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"تعذّر إنشاء جلسة ضيف جديدة."</string>
     <string name="user_nickname" msgid="262624187455825083">"اللقب"</string>
-    <string name="edit_user_info_message" msgid="6677556031419002895">"سيظهر الاسم والصورة اللذين تختارهما لأي شخص يستخدم هذا الجهاز."</string>
+    <string name="edit_user_info_message" msgid="6677556031419002895">"بإمكان أي شخص يستخدم هذا الجهاز رؤية الاسم والصورة اللذين تختارهما."</string>
     <string name="user_add_user" msgid="7876449291500212468">"إضافة مستخدم"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"إضافة ضيف"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"إزالة جلسة الضيف"</string>
@@ -643,11 +662,9 @@
     <string name="guest_exit_button" msgid="5774985819191803960">"الخروج من وضع الضيف"</string>
     <string name="guest_reset_button" msgid="2515069346223503479">"إعادة ضبط جلسة الضيف"</string>
     <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"الخروج من وضع الضيف"</string>
-    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"سيتم حذف جميع الأنشطة عند الخروج من وضع الضيف."</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"سيتم حذف جميع الأنشطة عند الخروج من وضع الضيف"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"يمكنك حفظ نشاطك أو حذفه عند الخروج من وضع الضيف."</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"يمكنك إجراء إعادة ضبط لحذف نشاط الجلسة الآن، أو حِفظ النشاط أو حذفه عند الخروج من وضع الضيف."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"التقاط صورة"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"اختيار صورة"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"اختيار صورة"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"لقد استنفدت عدد المحاولات غير الصحيحة وسيتم حذف بيانات هذا الجهاز."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"لقد استنفدت عدد المحاولات غير الصحيحة وسيتم حذف حساب هذا المستخدم."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"‏تم قطع اتصال Ethernet."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"إيثرنت"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"لا يتم الاتصال."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"اختيار صورة الملف الشخصي"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"رمز المستخدم التلقائي"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"لوحة المفاتيح الخارجية"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"اختيار تنسيق لوحة مفاتيح"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"التنسيق التلقائي"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index e8caf32..ef53faf 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"কেৱল বাঁওফালৰটো সক্ৰিয় হৈছে"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"কেৱল সোঁফালৰটো সক্ৰিয় হৈছে"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"বাওঁ আৰু সোঁ দুয়োফালৰ সক্ৰিয় হৈছে"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"মিডিয়াৰ অডিঅ’"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"ফ\'ন কলসমূহ"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ফাইল স্থানান্তৰণ"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"এপে আধুনিক ফৰ্মেট সমৰ্থন কৰে বুলি ধৰি লওক"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ট্ৰান্সক\'ডিঙৰ জাননী দেখুৱাওক"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ট্ৰান্সক\'ডিঙৰ কেশ্ব অক্ষম কৰক"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevineৰ ছেটিং"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Force L3 fallback"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"force L3 fallback সক্ষম কৰিবলৈ বাছনি কৰক"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"চলিত সেৱা"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"বৰ্তমান চলি থকা সেৱাসমূহ চাওক আৰু নিয়ন্ত্ৰণ কৰক"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"ৱেবভিউ প্ৰয়োগ"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"বাহিৰ হওঁতে আটাইবোৰ কাৰ্যকলাপ মচা হ’ব"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"আপুনি বাহিৰ হওঁতে নিজৰ কাৰ্যকলাপ ছেভ কৰিব অথবা মচিব পাৰে"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"এতিয়াই ছেশ্বনৰ কাৰ্যকলাপ ৰিছেট কৰক অথবা মচক অথবা আপুনি বাহিৰ হওঁতে কাৰ্যকলাপ ছেভ কৰিব অথবা মচিব পাৰে"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"এখন ফট’ তোলক"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"এখন প্ৰতিচ্ছবি বাছনি কৰক"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ফট’ বাছনি কৰক"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"অতি বেছি ভুল প্ৰয়াস। ডিভাইচটোৰ ডেটা মচা হ’ব।"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"অতি বেছি ভুল প্ৰয়াস। এই ব্যৱহাৰকাৰীক মচা হ’ব।"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ইথাৰনেট সংযোগ বিচ্ছিন্ন হৈছে।"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ইথাৰনেট।"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"কল কৰা নহয়"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"এখন প্ৰ’ফাইল চিত্ৰ বাছনি কৰক"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"ডিফ’ল্ট ব্যৱহাৰকাৰীৰ চিহ্ন"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"কায়িক কীব’ৰ্ড"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"কীব\'ৰ্ডৰ চানেকি বাছক"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ডিফ’ল্ট"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index d37aaf1..48c68f4 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, yalnız sol"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, yalnız sağ"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, sol və sağ"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Media audio"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefon zəngləri"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fayl transferi"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Tətbiqlərin müasir formatları dəstəklədiyini qəbul edin"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Kod dəyişmə bildirişlərini göstərin"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Keşin kodlaşdırılmasını deaktiv edin"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine ayarları"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 alternativini məcburi tətbiq edin"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 alternativinin məcburi tətbiqi üçün seçim edin"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"İşləyən xidmətlər"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"İşlək xidmətlərə baxış və onların idarəedilməsi"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView servisi"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Çıxış zamanı bütün fəaliyyətlər silinəcək"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Çıxışda fəaliyyətinizi saxlaya və ya silə bilərsiniz"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Sessiya fəaliyyətini indi silmək üçün sıfırlayın və ya çıxışda fəaliyyəti saxlaya və ya silə bilərsiniz"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Foto çəkin"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Şəkil seçin"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Foto seçin"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Həddindən artıq yanlış cəhd. Bu cihazın datası silinəcək."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Həddindən artıq yanlış cəhd. Bu istifadəçi silinəcək."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet bağlantısı kəsilib."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Zəng yoxdur."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Profil şəkli seçin"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Defolt istifadəçi ikonası"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fiziki klaviatura"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Klaviatura düzənini seçin"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Defolt"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 24a13cc..04c6d94 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -106,11 +106,33 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivno, samo s leve strane"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivno, s desne strane"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivno, s leve i desne strane"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Zvuk medija"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonski pozivi"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos datoteke"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ulazni uređaj"</string>
-    <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Pristup Internetu"</string>
+    <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Pristup internetu"</string>
     <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Dozvoli kontakte i istoriju poziva"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Informacije će se koristiti za obaveštenja o pozivima i drugo"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Deljenje internet veze"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Podrazumevaj da aplikacije podržavaju moderne formate"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Prikazuj obaveštenja o transkodiranju"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Onemogući keš transkodiranja"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine podešavanja"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Prinudno primeni L3 rezervu"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Izaberite da biste prinudno primenili L3 rezervu"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Pokrenute usluge"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Prikaz i kontrola trenutno pokrenutih usluga"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Primena WebView-a"</string>
@@ -611,8 +630,8 @@
     <string name="user_new_profile_name" msgid="2405500423304678841">"Novi profil"</string>
     <string name="user_info_settings_title" msgid="6351390762733279907">"Podaci o korisniku"</string>
     <string name="profile_info_settings_title" msgid="105699672534365099">"Podaci o profilu"</string>
-    <string name="user_need_lock_message" msgid="4311424336209509301">"Da biste mogli da napravite ograničeni profil, treba da podesite zaključavanje ekrana da biste zaštitili aplikacije i lične podatke."</string>
-    <string name="user_set_lock_button" msgid="1427128184982594856">"Podesi zaključavanje"</string>
+    <string name="user_need_lock_message" msgid="4311424336209509301">"Da biste mogli da napravite ograničeni profil, treba da podesite otključavanje ekrana da biste zaštitili aplikacije i lične podatke."</string>
+    <string name="user_set_lock_button" msgid="1427128184982594856">"Podesi otključavanje"</string>
     <string name="user_switch_to_user" msgid="6975428297154968543">"Pređi na korisnika <xliff:g id="USER_NAME">%s</xliff:g>"</string>
     <string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Pravi se novi korisnik…"</string>
     <string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"Pravi se novi gost…"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Sve aktivnosti će biti izbrisane pri izlazu"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Možete da sačuvate ili izbrišete aktivnosti pri izlazu"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Resetujete za brisanje aktivnosti sesije, ili sačuvajte ili izbrišite aktivnosti pri izlazu"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Slikaj"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Izaberite sliku"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Previše netačnih pokušaja. Izbrisaćemo podatke sa ovog uređaja."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Previše netačnih pokušaja. Izbrisaćemo ovog korisnika."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Veza sa eternetom je prekinuta."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Eternet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Bez pozivanja."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Odaberite sliku profila"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Podrazumevana ikona korisnika"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fizička tastatura"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Odaberite raspored tastature"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Podrazumevano"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 2fb2b4c..f8c88e6 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Уключана, толькі для левага вуха"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Уключана, толькі для правага вуха"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Уключана, для левага і правага вуха"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Аўдыя медыяфайлаў"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Тэлефонныя выклікі"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Перадача файлаў"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Лічыца, што праграмы падтрымліваюць сучасныя фарматы"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Паказваць апавяшчэнні пра перакадзіраванне"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Адключыць кэш перакадзіравання"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Налады Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Прымусовы пераход на ўзровень бяспекі 3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Выберыце, каб прымусова пераходзіць на ўзровень бяспекі 3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Запушчаныя службы"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Прагляд запушчаных службаў i кіраванне iмi"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Рэалізацыя WebView"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Падчас выхаду будуць выдалены ўсе звесткі пра дзеянні"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Падчас выхаду можна захаваць ці выдаліць звесткі пра дзеянні"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Скіньце звесткі пра дзеянні падчас сеанса зараз. Вы таксама можаце захаваць ці выдаліць іх у час выхаду."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Зрабіць фота"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Выбраць відарыс"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Выбраць фота"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Занадта шмат няўдалых спроб. Даныя з гэтай прылады будуць выдалены."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Занадта шмат няўдалых спроб. Гэты карыстальнік будзе выдалены."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet адлучаны."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Ніякіх выклікаў."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Выберыце відарыс профілю"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Стандартны карыстальніцкі значок"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Фізічная клавіятура"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Выбар раскладкі клавіятуры"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Стандартна"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 247b45b..0457f10 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Активно – само лявото"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Активно – само дясното"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Активно – лявото и дясното"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Мултимедийно аудио"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Телефонни обаждания"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Прехвърляне на файл"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Предполагане, че приложенията поддържат съвременни формати"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Показване на известията за прекодиране"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Деактивиране на кеша за прекодиране"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Настройки за Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Налагане на резервния вариант за L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Избиране на налагане на резервния вариант за L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Изпълнявани услуги"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Преглед и контрол върху изпълняващите се понастоящем услуги"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Внедряване на WebView"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Цялата активност ще бъде изтрита при изход"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"При изход можете да запазите активността или да я изтриете"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Нулирайте, за да изтриете активността в сесията сега. Можете също да я запазите или изтриете при изход"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Правене на снимка"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Избиране на изображение"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Избиране на снимката"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Твърде много неправилни опити. Данните от това устройство ще бъдат изтрити."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Твърде много неправилни опити. Този потребител ще бъде изтрит."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Връзката с Ethernet е прекратена."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Без обаждания."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Изберете снимка на потребителския профил"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Икона за основния потребител"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Физическа клавиатура"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Избор на клавиатурна подредба"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"По подразбиране"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index e6822d9..e9367ff 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"শুধুমাত্র বাঁদিকের হিয়ারিং এড অ্যাক্টিভ"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"শুধুমাত্র ডানদিকের হিয়ারিং এড অ্যাক্টিভ"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"বাঁ ও ডানদিকের হিয়ারিং এড, অ্যাক্টিভ"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"মিডিয়া অডিও"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"ফোন কল"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ফাইল স্থানান্তর"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"অ্যাপ মর্ডার্ন ফর্ম্যাটে কাজ করবে বলে ধরে নিন"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ট্রান্সকোডিং বিজ্ঞপ্তি দেখুন"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ক্যাশে ট্রান্সকোডিং বন্ধ করুন"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"ওয়াইডভাইন সেটিংস"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"ফোর্স L3 ফলব্যাক"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"ফোর্স L3 ফলব্যাক চালু করবেন কিনা তা বেছে নিন"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"এখন চলছে যে পরিষেবাগুলি"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"বর্তমান চলমান পরিষেবাগুলি দেখুন এবং নিয়ন্ত্রণ করুন"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"ওয়েবভিউ প্রয়োগ"</string>
@@ -609,7 +628,7 @@
     <string name="user_add_user_type_title" msgid="551279664052914497">"যোগ করুন"</string>
     <string name="user_new_user_name" msgid="60979820612818840">"নতুন ব্যবহারকারী"</string>
     <string name="user_new_profile_name" msgid="2405500423304678841">"নতুন প্রোফাইল"</string>
-    <string name="user_info_settings_title" msgid="6351390762733279907">"ব্যবহারকারী তথ্য"</string>
+    <string name="user_info_settings_title" msgid="6351390762733279907">"ব্যবহারকারীর তথ্য"</string>
     <string name="profile_info_settings_title" msgid="105699672534365099">"প্রোফাইল তথ্য"</string>
     <string name="user_need_lock_message" msgid="4311424336209509301">"আপনি একটি সীমাবদ্ধযুক্ত প্রোফাইল তৈরি করার আগে, আপনাকে আপনার অ্যাপ্লিকেশন এবং ব্যক্তিগত ডেটা সুরক্ষিত করার জন্য একটি স্ক্রিন লক সেট-আপ করতে হবে।"</string>
     <string name="user_set_lock_button" msgid="1427128184982594856">"লক সেট করুন"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ছেড়ে বেরিয়ে যাওয়ার সময় সব অ্যাক্টিভিটি মুছে দেওয়া হবে"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ছেড়ে বেরিয়ে যাওয়ার সময় আপনি অ্যাক্টিভিটি সেভ করতে পারবেন বা মুছতে পারবেন"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"সেশন অ্যাক্টিভিটি মুছে দিতে এখন রিসেট করুন বা ছেড়ে বেরিয়ে আসার সময় আপনি অ্যাক্টিভিটি সেভ করতে বা মুছতে পারবেন"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ফটো তুলুন"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"একটি ইমেজ বেছে নিন"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ফটো বেছে নিন"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"একাধিকবার ভুল ইনপুট দিয়েছেন। এই ডিভাইসের ডেটা মুছে ফেলা হবে।"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"একাধিকবার ভুল ইনপুট দিয়েছেন। এই ব্যবহারকারীর প্রোফাইল মুছে ফেলা হবে।"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ইথারনেটের সংযোগ বিচ্ছিন্ন হয়েছে৷"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ইথারনেট।"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"কল করবেন না।"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"একটি প্রোফাইল ছবি বেছে নিন"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"ডিফল্ট ব্যবহারকারীর আইকন"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"ফিজিক্যাল কীবোর্ড"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"কীবোর্ড লেআউট বেছে নিন"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ডিফল্ট"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 7eff2f1..7fb5225 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivno, samo lijevi"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivno, samo desni"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivno, lijevi i desni"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Zvuk medija"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonski pozivi"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenošenje fajla"</string>
@@ -265,7 +287,7 @@
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Vidite dugme za prijavu grešaka u meniju napajanja"</string>
     <string name="keep_screen_on" msgid="1187161672348797558">"Ne zaključavaj"</string>
     <string name="keep_screen_on_summary" msgid="1510731514101925829">"Ekran neće prelaziti u stanje mirovanja tokom punjenja"</string>
-    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Omogući Bluetooth HCI snoop zapis"</string>
+    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Omogući Bluetooth HCI snoop zapisnik"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Snimite Bluetooth pakete. (Uključite/isključite Bluetooth nakon što promijenite ovu postavku)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"OEM otključavanje"</string>
     <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Dozvoli otključavanje bootloadera"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Pretpostavi da aplikacije podržavaju moderne formate"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Prikaži obavještenja o transkodiranju"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Onemogućite keš memoriju za transkodiranje"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Postavke za Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Nametnite zamjenu L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Odaberite da nametnete zamjenu L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Pokrenute usluge"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Prikaz i kontrola trenutno pokrenutih usluga"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Postavljanje WebViewa"</string>
@@ -518,7 +537,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Koristi jezik sistema"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Otvaranje postavki za <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> nije uspjelo"</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"Ovaj način unosa može prikupiti sav tekst koji upišete, uključujući lične podatke kao što su lozinke i brojevi kreditnih kartica. Način omogućava aplikacija <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Da li želite koristiti ovaj način unosa?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Napomena: Nakon ponovnog pokretanja, ova aplikacija se neće moći pokrenuti dok ne otključate telefon"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Napomena: nakon ponovnog pokretanja ova aplikacija se neće moći pokrenuti dok ne otključate telefon"</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"Stanje IMS registracije"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"Registrirano"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Nije registrirano"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Sva aktivnost će se izbrisati pri napuštanju"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Možete sačuvati ili izbrisati svoju aktivnost pri izlasku"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Poništite da odmah izbrišete aktivnost iz sesije ili je možete sačuvati ili izbrisati pri izlasku"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Snimite fotografiju"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberite sliku"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Odabir fotografije"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Previše je neispravnih pokušaja. Podaci ovog uređaja će se izbrisati."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Previše je neispravnih pokušaja. Ovaj korisnik će se izbrisati."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Veza sa Ethernetom je prekinuta."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Nema pozivanja."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Odaberite sliku profila"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Zadana ikona korisnika"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fizička tastatura"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Odaberite raspored tastature"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Zadano"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 2fbc044..18da1be 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Actiu, només l\'esquerre"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Actiu, només el dret"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Actiu, esquerre i dret"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Àudio multimèdia"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Trucades telefòniques"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferència de fitxers"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Assumeix que les aplicacions són compatibles amb formats moderns"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Mostra les notificacions de transcodificació"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Desactiva la memòria cau per a la transcodificació"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Configuració de Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Força l\'alternativa L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Selecciona per forçar l\'alternativa L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Serveis en execució"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Visualitza i controla els serveis en execució"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementació de WebView"</string>
@@ -481,9 +500,9 @@
     <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g>: s\'està carregant"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Desconegut"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"S\'està carregant"</string>
-    <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Carregant ràpidament"</string>
+    <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Càrrega ràpida"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Carregant lentament"</string>
-    <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Carregant sense fil"</string>
+    <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Càrrega sense fil"</string>
     <string name="battery_info_status_charging_dock" msgid="8573274094093364791">"S\'està carregant"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"No s\'està carregant"</string>
     <string name="battery_info_status_not_charging" msgid="1103084691314264664">"Connectat, però sense carregar"</string>
@@ -491,7 +510,7 @@
     <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Totalment carregada"</string>
     <string name="battery_info_status_charging_on_hold" msgid="6364355145521694438">"Càrrega en espera"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlat per l\'administrador"</string>
-    <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlat per la configuració restringida"</string>
+    <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlat per l\'opció de configuració restringida"</string>
     <string name="disabled" msgid="8017887509554714950">"Desactivat"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Amb permís"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Sense permís"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Se suprimirà tota l\'activitat en sortir"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Pots desar o suprimir l\'activitat en sortir"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restableix la sessió per suprimir l\'activitat ara, o desa o suprimeix l\'activitat en sortir."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Fes una foto"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Tria una imatge"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selecciona una foto"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Has superat el nombre d\'intents incorrectes permesos. Les dades d\'aquest dispositiu se suprimiran."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Has superat el nombre d\'intents incorrectes permesos. Aquest usuari se suprimirà."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"S\'ha desconnectat l\'Ethernet."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Sense trucades."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Tria una foto de perfil"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Icona d\'usuari predeterminat"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Teclat físic"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Tria una disposició de teclat"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Predeterminat"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 334abc7..f4bfe505c 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivní, pouze levé"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivní, pouze pravé"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivní, levé a pravé"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Zvuk médií"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonní hovory"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Přenos souborů"</string>
@@ -301,7 +323,7 @@
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Spustit zvukový kodek Bluetooth LDAC\nVýběr kodeku: kvalita přehrávání"</string>
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Streamování: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"Soukromý DNS"</string>
-    <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Vyberte soukromý režim DNS"</string>
+    <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Režim výběru soukromého DNS"</string>
     <string name="private_dns_mode_off" msgid="7065962499349997041">"Vypnuto"</string>
     <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Automaticky"</string>
     <string name="private_dns_mode_provider" msgid="3619040641762557028">"Název hostitele poskytovatele soukromého DNS"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Předpokládat, že aplikace podporují moderní formáty"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Zobrazit oznámení o překódování"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Deaktivovat mezipaměť pro překódování"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Nastavení Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Vynucení L3 fallback"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Vybrat vynucení L3 fallback"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Spuštěné služby"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Umožňuje zobrazit a ovládat aktuálně spuštěné služby"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementace WebView"</string>
@@ -555,7 +574,7 @@
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Tento tablet"</string>
     <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
     <skip />
-    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Dok s reproduktorem"</string>
+    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Reproduktor doku"</string>
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Externí zařízení"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Připojené zařízení"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Tento telefon"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Veškerá aktivita bude při ukončení smazána"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Aktivitu můžete při ukončení uložit nebo smazat"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Aktivitu relace můžete ihned smazat resetováním, případně ji můžete uložit nebo smazat při ukončení"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Pořídit fotku"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrat obrázek"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Vybrat fotku"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Příliš mnoho neplatných pokusů. Data v tomto zařízení budou smazána."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Příliš mnoho neplatných pokusů. Tento uživatel bude smazán."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Síť ethernet je odpojena."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Bez volání."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Vyberte profilový obrázek"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Výchozí uživatelská ikona"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fyzická klávesnice"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Zvolte rozložení klávesnice"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Výchozí"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index e102b7e..d51f8b9 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, kun venstre"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, kun højre"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, venstre og højre"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Medielyd"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonopkald"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Filoverførsel"</string>
@@ -145,7 +167,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Annuller"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Parring giver adgang til dine kontakter og din opkaldshistorik, når enhederne er forbundet."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"Der kunne ikke parres med <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Kunne ikke parre med <xliff:g id="DEVICE_NAME">%1$s</xliff:g> pga. forkert pinkode eller adgangsnøgle."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"Parring med <xliff:g id="DEVICE_NAME">%1$s</xliff:g> mislykkedes på grund af en forkert pinkode eller adgangsnøgle."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"Der kan ikke kommunikeres med <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"Parring afvist af <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"Computer"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Gå ud fra, at apps understøtter moderne formater"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Vis notifikationer for omkodning"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Deaktiver omkodningscache"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine-indstillinger"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Fremtving L3-alternativ"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Vælg for at fremtvinge L3-alternativ"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Kørende tjenester"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Vis og administrer kørende tjenester"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementering"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Al aktivitet slettes ved afslutning"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Du kan gemme eller slette din aktivitet ved afslutning"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Nulstil for at slette sessionsaktiviteten nu, eller gem eller slet aktivitet ved afslutning"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Tag et billede"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Vælg et billede"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Vælg billede"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"For mange forkerte forsøg. Dataene på denne enhed slettes."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"For mange forkerte forsøg. Denne bruger slettes."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet er ikke tilsluttet."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Opkald er deaktiveret."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Vælg et profilbillede"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Ikon for standardbruger"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fysisk tastatur"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Vælg tastaturlayout"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Standard"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 245ff80..08ca14a 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -66,7 +66,7 @@
     <string name="connected_via_app" msgid="3532267661404276584">"Verbunden über <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="tap_to_sign_up" msgid="5356397741063740395">"Zum Anmelden tippen"</string>
     <string name="wifi_connected_no_internet" msgid="5087420713443350646">"Kein Internet"</string>
-    <string name="private_dns_broken" msgid="1984159464346556931">"Auf den privaten DNS-Server kann nicht zugegriffen werden"</string>
+    <string name="private_dns_broken" msgid="1984159464346556931">"Auf den Server des privaten DNS kann nicht zugegriffen werden"</string>
     <string name="wifi_limited_connection" msgid="1184778285475204682">"Eingeschränkte Verbindung"</string>
     <string name="wifi_status_no_internet" msgid="3799933875988829048">"Kein Internet"</string>
     <string name="wifi_status_sign_in_required" msgid="2236267500459526855">"Anmeldung erforderlich"</string>
@@ -106,12 +106,34 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, nur links"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, nur rechts"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, links und rechts"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Medien-Audio"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonanrufe"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Dateiübertragung"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Eingabegerät"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Internetzugriff"</string>
-    <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Zugriff auf Kontakte und Anrufliste geben"</string>
+    <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Zugriff auf Kontakte und Anrufliste gewähren"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Die Daten werden z. B. für Anrufbenachrichtigungen verwendet"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Freigabe der Internetverbindung"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS"</string>
@@ -301,10 +323,10 @@
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"Bluetooth-Audio-LDAC-Codec auslösen\nAuswahl: Wiedergabequalität"</string>
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"Streaming: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"Privates DNS"</string>
-    <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Privaten DNS-Modus auswählen"</string>
+    <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Modus des privaten DNS auswählen"</string>
     <string name="private_dns_mode_off" msgid="7065962499349997041">"Aus"</string>
     <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Automatisch"</string>
-    <string name="private_dns_mode_provider" msgid="3619040641762557028">"Hostname des privaten DNS-Anbieters"</string>
+    <string name="private_dns_mode_provider" msgid="3619040641762557028">"Hostname des Anbieters des privaten DNS"</string>
     <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Hostname des DNS-Anbieters eingeben"</string>
     <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Verbindung nicht möglich"</string>
     <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Optionen zur Zertifizierung für kabellose Übertragung anzeigen"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Voraussetzen, dass Apps moderne Formate unterstützen"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Benachrichtigungen zur Transcodierung anzeigen"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Cache für Transcodierung deaktivieren"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine-Einstellungen"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3-Fallback erzwingen"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Auswählen, um L3-Fallback zu erzwingen"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Aktive Dienste"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Momentan ausgeführte Dienste anzeigen und steuern"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-Implementierung"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Beim Beenden werden alle Aktivitäten gelöscht"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Speichere oder lösche deine Aktivitäten beim Beenden"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Zurücksetzen, um jetzt die Sitzungsaktivitäten zu löschen, oder Aktivitäten beim Beenden speichern oder löschen"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Foto machen"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Bild auswählen"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Foto auswählen"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Zu viele Fehlversuche. Die Daten auf diesem Gerät werden gelöscht."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Zu viele Fehlversuche. Dieser Nutzer wird gelöscht."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet nicht verbunden"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Keine Anrufe."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Profilbild auswählen"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Standardmäßiges Nutzersymbol"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Physische Tastatur"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Tastaturlayout wählen"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Standard"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 5e41992..c38034a 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ενεργό, μόνο το αριστερό"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ενεργό, μόνο το δεξί"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ενεργό, αριστερό και δεξί"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Ήχος πολυμέσων"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Τηλεφωνικές κλήσεις"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Μεταφορά αρχείου"</string>
@@ -411,7 +433,7 @@
     <string name="enable_freeform_support" msgid="7599125687603914253">"Ενεργοποίηση παραθύρων ελεύθερης μορφής"</string>
     <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Ενεργοποίηση υποστήριξης για πειραματικά παράθυρα ελεύθερης μορφής."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Εφ/κός κωδικός desktop"</string>
-    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Τα πλήρη αντίγραφα ασφαλείας επιφάνειας εργασίας δεν προστατεύονται αυτήν τη στιγμή"</string>
+    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Τα πλήρη αντίγραφα ασφαλείας επιφάνειας εργασίας δεν προστατεύονται αυτή τη στιγμή"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Πατήστε για αλλαγή ή κατάργηση του κωδικού πρόσβασης για τα πλήρη αντίγραφα ασφαλείας επιφάνειας εργασίας"</string>
     <string name="local_backup_password_toast_success" msgid="4891666204428091604">"Ορίστηκε νέος εφεδρικός κωδικός πρόσβασης"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"Ο νέος κωδικός πρόσβασης και η επιβεβαίωση δεν ταιριάζουν"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Να θεωρείται ότι οι εφαρμογές χρησιμοποιούν σύγχρονες μορφές"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Εμφάνιση ειδοποιήσεων διακωδικοποίησης"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Απενεργοποίηση κρυφής μνήμης για διακωδικοποίηση"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Ρυθμίσεις Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Επιβολή εναλλακτικής L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Επιλογή για επιβολή εναλλακτικής L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Υπηρεσίες που εκτελούνται"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Προβολή και έλεγχος των εφαρμογών που εκτελούνται αυτή τη στιγμή"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Υλοποίηση WebView"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Όλη η δραστηριότητα θα διαγραφεί κατά την έξοδο"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Αποθηκεύστε ή διαγράψτε τη δραστηριότητά σας κατά την έξοδο"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Επαναφορά για διαγραφή της δραστηριότητας της περιόδου σύνδεσης ή αποθήκευση ή διαγραφή κατά την έξοδο."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Λήψη φωτογραφίας"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Επιλογή εικόνας"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Επιλογή φωτογραφίας"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Πάρα πολλές ανεπιτυχείς προσπάθειες. Τα δεδομένα αυτής της συσκευής θα διαγραφούν."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Πάρα πολλές ανεπιτυχείς προσπάθειες. Αυτός ο χρήστης θα διαγραφεί."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Το Ethernet αποσυνδέθηκε."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Χωρίς κλήσεις."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Επιλογή φωτογραφ­ίας προφίλ"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Προεπιλεγμένο εικονίδιο χρήστη"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Φυσικό πληκτρολόγιο"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Επιλέξτε διάταξη πληκτρολογίου"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Προεπιλογή"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 253cbc5..c787c63 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Active, left only"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, right only"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, left and right"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Media audio"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Phone calls"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"File transfer"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Assume apps support modern formats"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Show transcoding notifications"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Disable transcoding cache"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine settings"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Force L3 fallback"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Select to force L3 fallback"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Running services"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"View and control currently running services"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView implementation"</string>
@@ -619,7 +638,7 @@
     <string name="add_user_failed" msgid="4809887794313944872">"Failed to create a new user"</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"Failed to create a new guest"</string>
     <string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
-    <string name="edit_user_info_message" msgid="6677556031419002895">"The name and picture you choose will be visible to anyone who uses this device."</string>
+    <string name="edit_user_info_message" msgid="6677556031419002895">"The name and picture that you choose will be visible to anyone who uses this device."</string>
     <string name="user_add_user" msgid="7876449291500212468">"Add user"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All activity will be deleted on exit"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"You can save or delete your activity on exit"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset to delete session activity now, or you can save or delete activity on exit"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Too many incorrect attempts. This device\'s data will be deleted."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Too many incorrect attempts. This user will be deleted."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet disconnected."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"No calling."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Choose a profile picture"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Default user icon"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Physical keyboard"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Choose keyboard layout"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Default"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 4a03f34..e5d2e29 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -106,6 +106,17 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Active, left only"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, right only"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, left and right"</string>
+    <string name="bluetooth_active_media_only_battery_level" msgid="1164678961213251365">"Active (media only), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
+    <string name="bluetooth_active_media_only_battery_level_untethered" msgid="1345174295097854560">"Active (media only), L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> battery, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery"</string>
+    <string name="bluetooth_battery_level_lea_support" msgid="8580950145907305436">"Connected (supports audio sharing), <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g> battery"</string>
+    <string name="bluetooth_battery_level_untethered_lea_support" msgid="8534816721698743015">"Connected (supports audio sharing), L: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g> battery, R: <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g> battery"</string>
+    <string name="bluetooth_battery_level_untethered_left_lea_support" msgid="6605320955858788855">"Connected (supports audio sharing), left <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_battery_level_untethered_right_lea_support" msgid="5717356160322149355">"Connected (supports audio sharing), right <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
+    <string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"Active (media only)"</string>
+    <string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"Supports audio sharing"</string>
+    <string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"Active (media only), left only"</string>
+    <string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"Active (media only), right only"</string>
+    <string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"Active (media only), left and right"</string>
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Media audio"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Phone calls"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"File transfer"</string>
@@ -437,9 +448,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Assume apps support modern formats"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Show transcoding notifications"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Disable transcoding cache"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine settings"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Force L3 fallback"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Select to force L3 fallback"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Running services"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"View and control currently running services"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView implementation"</string>
@@ -646,8 +654,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All activity will be deleted on exit"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"You can save or delete your activity on exit"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset to delete session activity now, or you can save or delete activity on exit"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Too many incorrect attempts. This device\'s data will be deleted."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Too many incorrect attempts. This user will be deleted."</string>
@@ -687,8 +693,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet disconnected."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"No calling."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Choose a profile picture"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Default user icon"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Physical keyboard"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Choose keyboard layout"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Default"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 253cbc5..c787c63 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Active, left only"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, right only"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, left and right"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Media audio"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Phone calls"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"File transfer"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Assume apps support modern formats"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Show transcoding notifications"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Disable transcoding cache"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine settings"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Force L3 fallback"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Select to force L3 fallback"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Running services"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"View and control currently running services"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView implementation"</string>
@@ -619,7 +638,7 @@
     <string name="add_user_failed" msgid="4809887794313944872">"Failed to create a new user"</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"Failed to create a new guest"</string>
     <string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
-    <string name="edit_user_info_message" msgid="6677556031419002895">"The name and picture you choose will be visible to anyone who uses this device."</string>
+    <string name="edit_user_info_message" msgid="6677556031419002895">"The name and picture that you choose will be visible to anyone who uses this device."</string>
     <string name="user_add_user" msgid="7876449291500212468">"Add user"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All activity will be deleted on exit"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"You can save or delete your activity on exit"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset to delete session activity now, or you can save or delete activity on exit"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Too many incorrect attempts. This device\'s data will be deleted."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Too many incorrect attempts. This user will be deleted."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet disconnected."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"No calling."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Choose a profile picture"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Default user icon"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Physical keyboard"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Choose keyboard layout"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Default"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 253cbc5..c787c63 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Active, left only"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, right only"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, left and right"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Media audio"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Phone calls"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"File transfer"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Assume apps support modern formats"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Show transcoding notifications"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Disable transcoding cache"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine settings"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Force L3 fallback"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Select to force L3 fallback"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Running services"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"View and control currently running services"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView implementation"</string>
@@ -619,7 +638,7 @@
     <string name="add_user_failed" msgid="4809887794313944872">"Failed to create a new user"</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"Failed to create a new guest"</string>
     <string name="user_nickname" msgid="262624187455825083">"Nickname"</string>
-    <string name="edit_user_info_message" msgid="6677556031419002895">"The name and picture you choose will be visible to anyone who uses this device."</string>
+    <string name="edit_user_info_message" msgid="6677556031419002895">"The name and picture that you choose will be visible to anyone who uses this device."</string>
     <string name="user_add_user" msgid="7876449291500212468">"Add user"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Add guest"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Remove guest"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All activity will be deleted on exit"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"You can save or delete your activity on exit"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset to delete session activity now, or you can save or delete activity on exit"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Take a photo"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Choose an image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Select photo"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Too many incorrect attempts. This device\'s data will be deleted."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Too many incorrect attempts. This user will be deleted."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet disconnected."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"No calling."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Choose a profile picture"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Default user icon"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Physical keyboard"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Choose keyboard layout"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Default"</string>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index b7e0cda..5e14648 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -106,6 +106,17 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‏‎‎‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‏‎‎‎‏‎Active, left only‎‏‎‎‏‎"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‎‎‎‏‎‎‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‏‏‎‎Active, right only‎‏‎‎‏‎"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‏‎‎‏‎‎‎‎‎‏‏‏‎‎‎‏‎‏‎Active, left and right‎‏‎‎‏‎"</string>
+    <string name="bluetooth_active_media_only_battery_level" msgid="1164678961213251365">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‏‏‏‎‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‏‎‎‏‎‏‎Active (media only), ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ battery‎‏‎‎‏‎"</string>
+    <string name="bluetooth_active_media_only_battery_level_untethered" msgid="1345174295097854560">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‎‎‏‎‏‎‎‏‏‎‎‎‎‎‎Active (media only), L: ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎ battery, R: ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎ battery‎‏‎‎‏‎"</string>
+    <string name="bluetooth_battery_level_lea_support" msgid="8580950145907305436">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‎‎‏‎‏‏‎‎‎‏‏‎‏‎‎‎‏‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎Connected (supports audio sharing), ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎ battery‎‏‎‎‏‎"</string>
+    <string name="bluetooth_battery_level_untethered_lea_support" msgid="8534816721698743015">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‏‏‎‎‎‎‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‏‏‏‎‎‏‏‏‎Connected (supports audio sharing), L: ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_0">%1$s</xliff:g>‎‏‎‎‏‏‏‎ battery, R: ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE_1">%2$s</xliff:g>‎‏‎‎‏‏‏‎ battery‎‏‎‎‏‎"</string>
+    <string name="bluetooth_battery_level_untethered_left_lea_support" msgid="6605320955858788855">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎Connected (supports audio sharing), left ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="bluetooth_battery_level_untethered_right_lea_support" msgid="5717356160322149355">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‎‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‎Connected (supports audio sharing), right ‎‏‎‎‏‏‎<xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="bluetooth_active_media_only_no_battery_level" msgid="71106861912593126">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‎‏‏‎‎Active (media only)‎‏‎‎‏‎"</string>
+    <string name="bluetooth_saved_device_lea_support" msgid="7231323139968285768">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‎‏‎‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‎‎‏‎‎‎‎Supports audio sharing‎‏‎‎‏‎"</string>
+    <string name="bluetooth_hearing_aid_media_only_left_active" msgid="1632152540901488645">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‏‎‎‎‏‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎‎‎‏‎‏‎Active (media only), left only‎‏‎‎‏‎"</string>
+    <string name="bluetooth_hearing_aid_media_only_right_active" msgid="3854140683042617230">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‎Active (media only), right only‎‏‎‎‏‎"</string>
+    <string name="bluetooth_hearing_aid_media_only_left_and_right_active" msgid="1299913413062528417">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‎‎‎‏‎Active (media only), left and right‎‏‎‎‏‎"</string>
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‎‎Media audio‎‏‎‎‏‎"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‎‎‎‏‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‎‏‏‏‎‎‎‎‏‏‎Phone calls‎‏‎‎‏‎"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‎‎‎‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‎File transfer‎‏‎‎‏‎"</string>
@@ -437,9 +448,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‎‎‏‎‏‎‎‏‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‎‏‏‎‎‏‏‏‎‏‎‎‎‎‏‏‏‎‏‏‏‎‎‏‏‎Assume apps support modern formats‎‏‎‎‏‎"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‏‏‏‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‏‏‎‎‎‎‎‏‎‎‎‎Show transcoding notifications‎‏‎‎‏‎"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‏‏‏‏‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎‏‏‏‎‏‏‎‏‎‎‏‎‏‎‏‎‎‏‎‏‎Disable transcoding cache‎‏‎‎‏‎"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‎Widevine settings‎‏‎‎‏‎"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‎‎‏‏‎‏‎‏‏‎‏‎‏‏‏‎‏‏‏‎‏‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‎Force L3 fallback‎‏‎‎‏‎"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‎‏‎‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎Select to force L3 fallback‎‏‎‎‏‎"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‏‎‎‏‏‎Running services‎‏‎‎‏‎"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‏‎‏‎‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‏‏‎View and control currently running services‎‏‎‎‏‎"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‏‏‏‎‎‏‎‏‎‏‎‏‏‏‏‏‏‏‏‎WebView implementation‎‏‎‎‏‎"</string>
@@ -646,8 +654,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‏‎‏‏‏‏‏‎All activity will be deleted on exit‎‏‎‎‏‎"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‏‎‎‎‎‎‎‎‏‎‎You can save or delete your activity on exit‎‏‎‎‏‎"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‎‏‏‎‏‎‏‎‏‎‏‎‏‏‏‎‎‎Reset to delete session activity now, or you can save or delete activity on exit‎‏‎‎‏‎"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‎‎‎‏‏‎‎‎‎‏‎‎‎‎‎‏‎‎Take a photo‎‏‎‎‏‎"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‎Choose an image‎‏‎‎‏‎"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‎‏‎‏‎‎‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‏‎‏‎‏‎Select photo‎‏‎‎‏‎"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‎‎‎‎‏‎Too many incorrect attempts. This device\'s data will be deleted.‎‏‎‎‏‎"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‏‎‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎‏‎‎Too many incorrect attempts. This user will be deleted.‎‏‎‎‏‎"</string>
@@ -687,8 +693,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎‏‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‏‎Ethernet disconnected.‎‏‎‎‏‎"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‏‏‎‏‏‎Ethernet.‎‏‎‎‏‎"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‏‎‎‎‏‎‏‏‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‏‎‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‏‎‎‎‏‎‎‎No calling.‎‏‎‎‏‎"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‏‎‏‏‏‎‎‎Choose a profile picture‎‏‎‎‏‎"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‎‏‎‎‏‎‏‎‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‏‎‏‎‎‎‎‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎Default user icon‎‏‎‎‏‎"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‏‏‏‎‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‎‎‎‎‎‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‏‎‏‎‏‎‏‎‎‎Physical keyboard‎‏‎‎‏‎"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‎‎‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‎‎‏‎‏‎‎‎‏‎‎Choose keyboard layout‎‏‎‎‏‎"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‎‏‎‎‎‎‏‏‎‏‎Default‎‏‎‎‏‎"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index b0dc37c..1903c6b 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -106,13 +106,35 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Activo; solo oído izquierdo"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Activo; solo oído derecho"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Activo; oídos izquierdo y derecho"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Audio multimedia"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Llamadas telefónicas"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferencia de archivos"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acceso a Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Acceso a contactos e historial de llamadas"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Se usará la inf. para anuncios de llamadas y otras funciones"</string>
+    <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Se usará la información para anuncios de llamadas y más"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Compartir conexión a Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensajes de texto"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Acceso a SIM"</string>
@@ -264,7 +286,7 @@
     <string name="bugreport_in_power" msgid="8664089072534638709">"Acceso directo para informes de errores"</string>
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Muestra un botón en el menú de encendido para realizar un informe de errores"</string>
     <string name="keep_screen_on" msgid="1187161672348797558">"Permanecer activo"</string>
-    <string name="keep_screen_on_summary" msgid="1510731514101925829">"La pantalla nunca quedará inactiva mientras el dispositivo se esté cargando."</string>
+    <string name="keep_screen_on_summary" msgid="1510731514101925829">"La pantalla nunca quedará inactiva mientras el dispositivo se esté cargando"</string>
     <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Registro de Bluetooth HCI"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Capturar paquetes de Bluetooth (activa/desactiva el Bluetooth después de cambiar esta configuración)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"Desbloqueo de OEM"</string>
@@ -305,7 +327,7 @@
     <string name="private_dns_mode_off" msgid="7065962499349997041">"Desactivado"</string>
     <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Automático"</string>
     <string name="private_dns_mode_provider" msgid="3619040641762557028">"Nombre de host del proveedor de DNS privado"</string>
-    <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Ingresa el host del proveedor de DNS"</string>
+    <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Ingresa el nombre de host del proveedor de DNS"</string>
     <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"No se pudo establecer conexión"</string>
     <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Muestra opciones de certificación de pantalla inalámbrica"</string>
     <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Aumenta el nivel de registro Wi-Fi y se muestra por SSID RSSI en el selector de Wi-Fi"</string>
@@ -411,7 +433,7 @@
     <string name="enable_freeform_support" msgid="7599125687603914253">"Habilitar ventanas de forma libre"</string>
     <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Permite la compatibilidad con ventanas de forma libre experimentales."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"Contraseñas"</string>
-    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Tus copias de seguridad de escritorio no están protegidas por contraseña."</string>
+    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Tus copias de seguridad de escritorio no están protegidas por contraseña"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Presiona para cambiar o quitar la contraseña de las copias de seguridad completas de tu escritorio."</string>
     <string name="local_backup_password_toast_success" msgid="4891666204428091604">"Nueva contraseña de copia de seguridad definida"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"La nueva contraseña y la de confirmación no coinciden."</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Suponer que las apps admiten formatos modernos"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Mostrar notificaciones de transcodificación"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Inhabilitar caché de transcodificación"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Parámetros de configuración de Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Forzar resguardo de nivel 3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Seleccionar para forzar un resguardo de nivel 3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"En ejecución"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ver y controlar servicios actuales en ejecución"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementación de WebView"</string>
@@ -491,7 +510,7 @@
     <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Carga completa"</string>
     <string name="battery_info_status_charging_on_hold" msgid="6364355145521694438">"Se detuvo la carga"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Controlada por el administrador"</string>
-    <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlada por la configuración restringida"</string>
+    <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Función controlada por configuración restringida"</string>
     <string name="disabled" msgid="8017887509554714950">"Inhabilitada"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Con permiso"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"No permitida"</string>
@@ -555,7 +574,7 @@
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Esta tablet"</string>
     <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
     <skip />
-    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Conector de la bocina"</string>
+    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Bocina de la estación de carga"</string>
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo conectado"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
@@ -619,7 +638,7 @@
     <string name="add_user_failed" msgid="4809887794313944872">"No se pudo crear el usuario nuevo"</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"No se pudo crear un nuevo invitado"</string>
     <string name="user_nickname" msgid="262624187455825083">"Sobrenombre"</string>
-    <string name="edit_user_info_message" msgid="6677556031419002895">"El nombre y la imagen que uses será visible para todas las personas que utilicen este dispositivo."</string>
+    <string name="edit_user_info_message" msgid="6677556031419002895">"Cualquier persona que use este dispositivo podrá ver el nombre y la imagen que elijas."</string>
     <string name="user_add_user" msgid="7876449291500212468">"Agregar usuario"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Agregar invitado"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Quitar invitado"</string>
@@ -629,7 +648,7 @@
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Restablecer"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Quitar"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Restableciendo invitado…"</string>
-    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"¿Quieres restablecer la sesión de invitado?"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"¿Restablecer la sesión de invitado?"</string>
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Esta acción comenzará una nueva sesión de invitado y borrará todas las apps y los datos de la sesión actual."</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"¿Salir del modo de invitado?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Esta acción borrará todas las apps y los datos de la sesión de invitado actual."</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Cuando salgas, se borrará toda la actividad"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Puedes guardar o borrar la actividad cuando salgas"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restablece la sesión para eliminar la actividad ahora; o guarda o borra la actividad cuando salgas"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Tomar una foto"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Elegir una imagen"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Hubo demasiados intentos incorrectos. Se borrarán los datos de este dispositivo."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Hubo demasiados intentos incorrectos. Se borrará este usuario."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet desconectada"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Sin llamadas."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Elige una foto de perfil"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Ícono de usuario predeterminado"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Teclado físico"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Elige el diseño de teclado"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Predeterminada"</string>
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index 5046194..1489e5f 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -186,11 +186,11 @@
   </string-array>
   <string-array name="select_logd_size_summaries">
     <item msgid="409235464399258501">"Desactivado"</item>
-    <item msgid="4195153527464162486">"64 K/búfer registro"</item>
-    <item msgid="7464037639415220106">"256 K/búfer registro"</item>
-    <item msgid="8539423820514360724">"1 M/búfer registro"</item>
-    <item msgid="1984761927103140651">"4 M/búfer registro"</item>
-    <item msgid="2983219471251787208">"8 MB por búfer de registro"</item>
+    <item msgid="4195153527464162486">"64 K/búfer de registro"</item>
+    <item msgid="7464037639415220106">"256 K/búfer de registro"</item>
+    <item msgid="8539423820514360724">"1 M/búfer de registro"</item>
+    <item msgid="1984761927103140651">"4 M/búfer de registro"</item>
+    <item msgid="2983219471251787208">"8 MB/búfer de registro"</item>
   </string-array>
   <string-array name="select_logpersist_titles">
     <item msgid="704720725704372366">"Desactivado"</item>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 9f88c4a..29b29b6 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Activo, solo oído izquierdo"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Activo, solo oído derecho"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Activo, oídos izquierdo y derecho"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Audio multimedia"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Llamadas de teléfono"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferencia de archivos"</string>
@@ -263,8 +285,8 @@
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, depuración, desarrollo"</string>
     <string name="bugreport_in_power" msgid="8664089072534638709">"Acceso directo a informe de errores"</string>
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Muestra un botón en el menú de encendido para crear un informe de errores"</string>
-    <string name="keep_screen_on" msgid="1187161672348797558">"Pantalla siempre encendida al cargar"</string>
-    <string name="keep_screen_on_summary" msgid="1510731514101925829">"La pantalla nunca entra en modo de suspensión si el dispositivo se está cargando"</string>
+    <string name="keep_screen_on" msgid="1187161672348797558">"Pantalla activa"</string>
+    <string name="keep_screen_on_summary" msgid="1510731514101925829">"La pantalla nunca entra en modo Suspensión si el dispositivo se está cargando"</string>
     <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Habilitar registro de Bluetooth HCI"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Capturar paquetes de Bluetooth (después de cambiar esta opción, desactiva y activa el Bluetooth)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"Desbloqueo de OEM"</string>
@@ -313,7 +335,7 @@
     <string name="wifi_non_persistent_mac_randomization_summary" msgid="2159794543105053930">"Si este modo está habilitado, es posible que la dirección MAC del dispositivo cambie cada vez que se conecte a una red que tenga habilitada la aleatorización de MAC."</string>
     <string name="wifi_metered_label" msgid="8737187690304098638">"Medida"</string>
     <string name="wifi_unmetered_label" msgid="6174142840934095093">"No medida"</string>
-    <string name="select_logd_size_title" msgid="1604578195914595173">"Tamaños del búfer de registro"</string>
+    <string name="select_logd_size_title" msgid="1604578195914595173">"Tamaños de los búferes de registro"</string>
     <string name="select_logd_size_dialog_title" msgid="2105401994681013578">"Elige el tamaño del Logger por búfer"</string>
     <string name="dev_logpersist_clear_warning_title" msgid="8631859265777337991">"¿Borrar almacenamiento continuo del registrador?"</string>
     <string name="dev_logpersist_clear_warning_message" msgid="6447590867594287413">"Cuando ya no supervisamos la actividad con el registrador de forma continua, estamos obligados a borrar los datos del registrador almacenados en el dispositivo."</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Considerar que las aplicaciones admiten formatos modernos"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Mostrar notificaciones de transcodificación"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Inhabilitar almacenamiento en caché para transcodificaciones"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Ajustes de Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Forzar respaldo a L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Selecciona para forzar el respaldo a L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Servicios en ejecución"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Consulta y controla los servicios en ejecución"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementación de WebView"</string>
@@ -498,9 +517,9 @@
     <string name="install_other_apps" msgid="3232595082023199454">"Instalar aplicaciones desconocidas"</string>
     <string name="home" msgid="973834627243661438">"Página principal de ajustes"</string>
   <string-array name="battery_labels">
-    <item msgid="7878690469765357158">"0%"</item>
-    <item msgid="8894873528875953317">"50%"</item>
-    <item msgid="7529124349186240216">"100%"</item>
+    <item msgid="7878690469765357158">"0 %"</item>
+    <item msgid="8894873528875953317">"50 %"</item>
+    <item msgid="7529124349186240216">"100 %"</item>
   </string-array>
     <string name="charge_length_format" msgid="6941645744588690932">"Hace <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="4310625772926171089">"Tiempo restante: <xliff:g id="ID_1">%1$s</xliff:g>"</string>
@@ -555,7 +574,7 @@
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Esta tablet"</string>
     <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
     <skip />
-    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Altavoz base"</string>
+    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Altavoz de la base"</string>
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo conectado"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Toda la actividad se eliminará cuando salgas"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Puedes guardar o eliminar tu actividad al salir"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restablece la sesión para eliminar la actividad ahora, o guarda o borra la actividad al salir"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Hacer foto"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Seleccionar una imagen"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Ha habido demasiados intentos fallidos. Los datos de este dispositivo se eliminarán."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Ha habido demasiados intentos fallidos. Este usuario se eliminará."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Conexión Ethernet desconectada."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Sin llamadas."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Elige una imagen de perfil"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Icono de usuario predeterminado"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Teclado físico"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Elige el diseño del teclado"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Predeterminado"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index fe62b37..9f77bd9 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiivne, ainult vasak"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiivne, ainult parem"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiivne, vasak ja parem"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Meediaheli"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonikõned"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Failiedastus"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Oleta, et rakendused toetavad kaasaegseid vorminguid"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Kuva transkodeerimise märguanded"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Transkodeerimise vahemälu keelamine"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine\'i seaded"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Sundtaane tasemele L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Valige sundtaandeks tasemele L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Käitatud teenused"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Praegu käitatud teenuste vaatamine ja juhtimine"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView\' rakendamine"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Kõik tegevused kustutatakse väljumisel"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Võite tegevused väljumisel salvestada või kustutada."</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Seansi tegevuste kohe kustutamiseks lähtestage; või salvestage või kustutage need väljumisel."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Pildistage"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Valige pilt"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Valige foto"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Liiga palju valesid katseid. Selle seadme andmed kustutatakse."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Liiga palju valesid katseid. See kasutaja kustutatakse."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Etherneti-ühendus on katkestatud."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Helistamine pole võimalik."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Valige profiilipilt"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Vaikekasutajaikoon"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Füüsiline klaviatuur"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Klaviatuuri paigutuse valimine"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Vaikimisi"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 7d288f0..05f3ac7 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktibo, ezkerrekoa soilik"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktibo, eskuinekoa soilik"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktibo, ezkerreko eta eskuineko audifonoak"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Euskarriaren audioa"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefono-deiak"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fitxategi-transferentzia"</string>
@@ -403,7 +425,7 @@
     <string name="show_all_anrs" msgid="9160563836616468726">"Erakutsi atzeko planoko ANRak"</string>
     <string name="show_all_anrs_summary" msgid="8562788834431971392">"Erakutsi aplikazioak ez erantzutearen (ANR) leihoa atzeko planoan dabiltzan aplikazioen kasuan"</string>
     <string name="show_notification_channel_warnings" msgid="3448282400127597331">"Erakutsi jakinarazpenen kanalen abisuak"</string>
-    <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Bistaratu abisuak aplikazioek baliozko kanalik gabeko jakinarazpenak argitaratzean"</string>
+    <string name="show_notification_channel_warnings_summary" msgid="68031143745094339">"Bistaratu abisuak aplikazioek kanal baliodunik gabeko jakinarazpenak argitaratzean"</string>
     <string name="force_allow_on_external" msgid="9187902444231637880">"Behartu aplikazioak onartzera kanpoko memorian"</string>
     <string name="force_allow_on_external_summary" msgid="8525425782530728238">"Aplikazioek kanpoko memorian idatz dezakete, ezarritako balioak kontuan izan gabe"</string>
     <string name="force_resizable_activities" msgid="7143612144399959606">"Behartu jardueren tamaina doitu ahal izatera"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Arduratu aplikazioek formatu modernoak onartzeaz"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Erakutsi transkodetze-jakinarazpenak"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Desgaitu transkodetze-cachea"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine-ren ezarpenak"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Behartu L3 ordezko aukera"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Hautatu L3 ordezko aukera behartu nahi duzun"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Abian diren zerbitzuak"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ikusi eta kontrolatu une honetan abian diren zerbitzuak"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView inplementazioa"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Irtetean, jarduera guztiak ezabatuko dira"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Irtetean, jarduerak gorde edo ezabatu egin ditzakezu"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Berrezarri saioa jarduerak ezabatzeko; bestela, aukeratu jarduerak irtetean gordetzea edo ezabatzea"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Atera argazki bat"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Aukeratu irudi bat"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Hautatu argazki bat"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Saiakera oker gehiegi egin dituzu. Gailu honetako datuak ezabatu egingo dira."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Saiakera oker gehiegi egin dituzu. Erabiltzailea ezabatu egingo da."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet bidezko konexioa eten da."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Deirik ez."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Aukeratu profileko argazki bat"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Erabiltzaile lehenetsiaren ikonoa"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Teklatu fisikoa"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Aukeratu teklatuaren diseinua"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Lehenetsia"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 3945050..658fb0f 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"فعال، فقط چپ"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"فعال، فقط راست"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"فعال، چپ و راست"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"رسانه صوتی"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"تماس‌های تلفنی"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"انتقال فایل"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"فرض شود برنامه‌ها از قالب‌های مدرن پشتیبانی می‌کنند"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"نمایش اعلان‌های تراتبدیل"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"غیرفعال کردن حافظه پنهان تراتبدیل"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"‏تنظیمات Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"‏اجرای اجباری «بازگشت به L3»"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"‏برای اجرای اجباری «بازگشت به L3»، انتخاب کنید"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"سرویس‌های در حال اجرا"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"مشاهده و کنترل سرویس‌های در حال اجرای فعلی"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"اجرای وب‌نما"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"همه فعالیت‌ها هنگام خروج حذف خواهد شد"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"می‌توانید فعالیتتان را هنگام خروج ذخیره یا حذف کنید"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"برای حذف فعالیت جلسه در این لحظه، بازنشانی کنید یا می‌توانید فعالیت را هنگام خروج ذخیره یا حذف کنید"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"عکس گرفتن"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"انتخاب تصویر"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"انتخاب عکس"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"تلاش‌های نادرست بسیار زیادی انجام شده است. داده‌های این دستگاه حذف خواهد شد."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"تلاش‌های اشتباه بسیار زیادی انجام شده است. این کاربر حذف خواهد شد."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"اترنت قطع شد."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"اترنت."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"تماس گرفته نشود."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"انتخاب عکس نمایه"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"نماد کاربر پیش‌فرض"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"صفحه‌کلید فیزیکی"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"انتخاب جانمایی صفحه‌کلید"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"پیش‌فرض"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 6f9dabc..14b1701 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiivinen, vain vasen"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiivinen, vain oikea"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiivinen, vasen ja oikea"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Median ääni"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Puhelut"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Tiedostonsiirto"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Oleta, että sovellukset tukevat nykyaikaisia formaatteja"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Näytä transkoodausilmoituksia"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Poista välimuistin transkoodaus käytöstä"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine-asetukset"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Pakota L3-varavaihtoehto"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Pakota L3-varavaihtoehto valitsemalla tämä"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Käynnissä olevat palvelut"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Tarkastele ja hallitse käynnissä olevia palveluita"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-käyttöönotto"</string>
@@ -539,7 +558,7 @@
     <string name="alarms_and_reminders_footer_title" msgid="6302587438389079695">"Anna sovelluksen lisätä herätyksiä ja ajoittaa kiireellisiä tapahtumia. Näin sovellus voi toimia taustalla, mikä voi kuluttaa enemmän virtaa.\n\nIlman tätä lupaa sovelluksen ajoittamat herätykset ja aikaan perustuvat tapahtumat eivät toimi."</string>
     <string name="keywords_alarms_and_reminders" msgid="6633360095891110611">"ajoitus, herätys, muistutus, kello"</string>
     <string name="zen_mode_enable_dialog_turn_on" msgid="6418297231575050426">"Ota käyttöön"</string>
-    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Ota Älä häiritse ‑tila käyttöön"</string>
+    <string name="zen_mode_settings_turn_on_dialog_title" msgid="2760567063190790696">"Laita Älä häiritse ‑tila päälle"</string>
     <string name="zen_mode_settings_summary_off" msgid="3832876036123504076">"Ei koskaan"</string>
     <string name="zen_interruption_level_priority" msgid="5392140786447823299">"Vain tärkeät"</string>
     <string name="zen_mode_and_condition" msgid="8877086090066332516">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
@@ -597,7 +616,7 @@
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"Rajoitettu profiili"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"Lisätäänkö uusi käyttäjä?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"Voit jakaa tämän laitteen muiden kanssa luomalla lisää käyttäjiä. Kullakin käyttäjällä on oma tilansa, jota he voivat muokata esimerkiksi omilla sovelluksilla ja taustakuvilla. Käyttäjät voivat myös muokata laiteasetuksia, kuten Wi‑Fi-asetuksia, jotka vaikuttavat laitteen kaikkiin käyttäjiin.\n\nKun lisäät uuden käyttäjän, hänen tulee määrittää oman tilansa asetukset.\n\nKaikki käyttäjät voivat päivittää muiden käyttäjien sovelluksia. Saavutettavuusominaisuuksia tai ‑palveluita ei välttämättä siirretä uudelle käyttäjälle."</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"Kun lisäät uuden käyttäjän, hänen tulee määrittää oman tilansa asetukset.\n\nKaikki käyttäjät voivat päivittää sovelluksia muille käyttäjille."</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"Kun lisäät uuden käyttäjän, hänen tulee valita oman tilansa asetukset.\n\nKaikki käyttäjät voivat päivittää sovelluksia muille käyttäjille."</string>
     <string name="user_grant_admin_title" msgid="5157031020083343984">"Tehdäänkö tästä käyttäjästä järjestelmänvalvoja?"</string>
     <string name="user_grant_admin_message" msgid="1673791931033486709">"Järjestelmänvalvojilla on enemmän oikeuksia kuin muilla. Järjestelmänvalvoja voi hallinnoida kaikkia käyttäjiä, päivittää tai nollata tämän laitteen, muokata asetuksia, nähdä asennetut sovellukset ja antaa tai peruuttaa järjestelmänvalvojan oikeudet muilta."</string>
     <string name="user_grant_admin_button" msgid="5441486731331725756">"Muuta järjestelmänvalvojaksi"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Kaikki toiminta poistetaan uloskirjaamisen aikana"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Voit tallentaa tai poistaa toiminnan poistuessasi"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Nollaa poistaaksesi istunnon toiminnan nyt, tai voit tallentaa tai poistaa toimintaa poistuessasi"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Ota kuva"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Valitse kuva"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Valitse kuva"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Liian monta virheellistä yritystä. Laitteen data poistetaan."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Liian monta virheellistä yritystä. Tämä käyttäjä poistetaan."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet on irrotettu."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Ei puheluita."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Valitse profiilikuva"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Oletuskäyttäjäkuvake"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fyysinen näppäimistö"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Valitse näppäimistöasettelu"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Oletus"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 56e6900..e4ae145 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Actif, gauche seulement"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Active, droite seulement"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Active, gauche et droite"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Paramètres audio du support"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Appels téléphoniques"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transfert de fichier"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Présumer que les applications prennent en charge les formats modernes"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Afficher les notifications de transcodage"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Désactiver le cache de transcodage"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Paramètres de Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Forcer le traitement de secours L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Sélectionnez pour forcer le traitement de secours L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Services en cours d\'exécution"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Afficher et contrôler les services en cours d\'exécution"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Mise en œuvre WebView"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Toute l\'activité sera supprimée à la fin de la session"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Vous pouvez enregistrer ou supprimer votre activité à la fin"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Réinitialisez pour supprimer l\'activité de la session maintenant, ou vous pouvez enregistrer ou supprimer l\'activité à la fin de la session"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Prendre une photo"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Sélectionner une image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Sélectionnez une photo"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Trop de tentatives incorrectes. Les données de cet appareil seront supprimées."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Trop de tentatives incorrectes. Cet utilisateur sera supprimé."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet déconnecté."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Aucun appel."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Choisir une photo de profil"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Icône d\'utilisateur par défaut"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Clavier physique"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Sélectionner disposition du clavier"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Par défaut"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index b48f637..09b40ac 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -106,13 +106,35 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Actif, gauche uniquement"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Actif, droit uniquement"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Actifs, gauche et droit"</string>
-    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Multimédia"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
+    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Audio multimédia"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Appels téléphoniques"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transfert de fichiers"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Périphérique d\'entrée"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Accès Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Autoriser l\'accès aux contacts et à l\'historique des appels"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Les infos seront utilisées pour les notifications d\'appels, entre autres"</string>
+    <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Ces infos seront utilisées pour les notifications d\'appels, entre autres"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Partage de connexion Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Accès à la SIM"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Supposer que les applications sont compatibles avec les formats modernes"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Afficher les notifications de transcodage"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Désactiver la cache de transcodage"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Paramètres Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Forcer le retour en arrière vers le niveau 3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Sélectionner pour forcer le retour en arrière vers le niveau 3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Services en cours d\'exécution"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Afficher et contrôler les services en cours d\'exécution"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Mise en œuvre WebView"</string>
@@ -518,7 +537,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Utiliser les langues du système"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Échec de l\'ouverture des paramètres de l\'application <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>."</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"Ce mode de saisie est susceptible d\'enregistrer le texte que vous saisissez, y compris vos données personnelles, telles que les mots de passe et les numéros de carte de paiement. Il provient de l\'application <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Voulez-vous vraiment l\'activer ?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Remarque : Après un redémarrage, vous ne pouvez pas lancer cette application tant que vous n\'avez pas déverrouillé votre téléphone."</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Remarque : Après un redémarrage, cette application ne peut pas démarrer tant que vous n\'avez pas déverrouillé votre téléphone."</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"État de l\'enregistrement IMS"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"Enregistré"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Non enregistré"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Toute l\'activité sera supprimée à la fin de la session"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Vous pouvez enregistrer ou supprimer l\'activité en quittant"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Réinitialisez la session pour supprimer immédiatement l\'activité. Vous pourrez aussi l\'enregistrer ou la supprimer en quittant la session."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Prendre une photo"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Choisir une image"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Sélectionner une photo"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Trop de tentatives incorrectes. Les données de cet appareil vont être supprimées."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Trop de tentatives incorrectes. Ce compte utilisateur va être supprimé."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet déconnecté"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Pas d\'appels."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Choisissez une photo de profil"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Icône de l\'utilisateur par défaut"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Clavier physique"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Sélectionner disposition du clavier"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Par défaut"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 0fe4a40..db40500 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Activo (só o esquerdo)"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Activo (só o dereito)"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Activos (o esquerdo e o dereito)"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Audio multimedia"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Chamadas telefónicas"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferencia de ficheiros"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Considerar que as aplicacións admiten formatos modernos"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Mostrar notificacións de transcodificación"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Desactivar memoria caché para a transcodificación"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Configuración de Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Forzar alternativa a L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Seleccionar para forzar a alternativa a L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Servizos en uso"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Comproba e controla os servizos actualmente en uso"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementación de WebView"</string>
@@ -518,7 +537,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Usar idiomas do sistema"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Non se puido abrir a configuración de <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"Este método de introdución de texto pode recompilar todo o que escribas, incluídos os datos persoais como os contrasinais e os números de tarxetas de crédito. Provén da aplicación <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Queres usar este método de introdución de texto?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Nota: Tras un reinicio, non se pode iniciar esta aplicación ata que desbloquees o teléfono"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Nota: Tras un reinicio, non se poderá iniciar esta aplicación ata que se desbloquee o teléfono"</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"Estado de rexistro de IMS"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"Rexistrado"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Non rexistrado"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Eliminarase toda a actividade ao saír"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Podes gardar ou eliminar a túa actividade ao saír"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Restablece a sesión para eliminar a actividade agora, ou ben gárdaa ou elimínaa ao saír"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Tirar foto"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Escoller imaxe"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Seleccionar foto"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Realizaches demasiados intentos incorrectos. Eliminaranse os datos deste dispositivo."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Realizaches demasiados intentos incorrectos. Eliminarase este usuario."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Desconectouse a Ethernet."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Sen chamadas."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Escolle unha imaxe do perfil"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Icona do usuario predeterminado"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Teclado físico"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Seleccionar deseño do teclado"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Predeterminado"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index 829171c..c1eeca5 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"સક્રિય, માત્ર ડાબું"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"સક્રિય, માત્ર જમણું"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"સક્રિય, ડાબું અને જમણું બન્ને"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"મીડિયા ઑડિયો"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"ફોન કૉલ"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ફાઇલ સ્થાનાંતરણ"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"ધારો કે ઍપ આધુનિક ફૉર્મેટ પર કામ કરે છે"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ફૉર્મેટ બદલવાની પ્રક્રિયાના નોટિફિકેશન બતાવો"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ફૉર્મેટ બદલવાની પ્રક્રિયાની કૅશ મેમરી બંધ કરો"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevineના સેટિંગ"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 ફૉલબૅકને ફરજ પાડો"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 ફૉલબૅકને ફરજ પાડવા માટે પસંદ કરો"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"ચાલુ સેવાઓ"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"હાલમાં ચાલતી સેવાઓ જુઓ અને નિયંત્રિત કરો"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView અમલીકરણ"</string>
@@ -643,11 +662,9 @@
     <string name="guest_exit_button" msgid="5774985819191803960">"અતિથિ મોડમાંથી બહાર નીકળો"</string>
     <string name="guest_reset_button" msgid="2515069346223503479">"અતિથિ સત્ર રીસેટ કરો"</string>
     <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"અતિથિ મોડમાંથી બહાર નીકળો"</string>
-    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"બહાર નીકળતી વખતે તમામ પ્રવૃત્તિ ડિલીટ કરવામાં આવશે"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"બહાર નીકળતી વખતે તમામ ઍક્ટિવિટી ડિલીટ કરવામાં આવશે"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"બહાર નીકળતી વખતે તમે પ્રવૃત્તિ સાચવી કે ડિલીટ કરી શકશો"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"સત્રની પ્રવૃત્તિ હમણાં ડિલીટ કરવા માટે રીસેટ કરો અથવા બહાર નીકળતી વખતે તમે પ્રવૃત્તિ સાચવી કે ડિલીટ કરી શકશો"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ફોટો લો"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"છબી પસંદ કરો"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ફોટો પસંદ કરો"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"ઘણા બધા ખોટા પ્રયત્નો. આ ડિવાઇસનો ડેટા ડિલીટ કરવામાં આવશે."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"ઘણા બધા ખોટા પ્રયત્નો. આ વપરાશકર્તાને ડિલીટ કરવામાં આવશે."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ઇથરનેટ ડિસ્કનેક્ટ થયું."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ઇથરનેટ."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"કોઈ કૉલિંગ નહીં."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"પ્રોફાઇલ ફોટો પસંદ કરો"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"ડિફૉલ્ટ વપરાશકર્તાનું આઇકન"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"ભૌતિક કીબોર્ડ"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"કીબોર્ડ લેઆઉટ પસંદ કરો"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ડિફૉલ્ટ"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 2ce8f9b..a5b3c88 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -106,16 +106,38 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"सिर्फ़ बाईं तरफ़ वाला चालू है"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"सिर्फ़ दाईं तरफ़ वाला चालू है"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"बाईं और दाईं तरफ़ वाला चालू है"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"मीडिया ऑडियो"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"फ़ोन कॉल"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"फ़ाइल स्थानांतरण"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"इनपुट डिवाइस"</string>
-    <string name="bluetooth_profile_pan" msgid="1006235139308318188">"इंटरनेट ऐक्सेस"</string>
+    <string name="bluetooth_profile_pan" msgid="1006235139308318188">"इंटरनेट का ऐक्सेस"</string>
     <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"संपर्क और कॉल इतिहास का ऐक्सेस दें"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"जानकारी का इस्तेमाल कॉल की सूचना देने वगैरह के लिए होगा"</string>
+    <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"इस जानकारी का इस्तेमाल, कॉल की सूचना देने और दूसरी चीज़ों के लिए किया जाएगा"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"इंटरनेट कनेक्शन साझाकरण"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"लेख संदेश"</string>
-    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"सिम ऐक्सेस"</string>
+    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"सिम का ऐक्सेस"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"एचडी ऑडियो: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"एचडी ऑडियो"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="2607867572569689732">"कान की मशीनें"</string>
@@ -180,7 +202,7 @@
     <string name="launch_defaults_some" msgid="3631650616557252926">"कुछ डिफ़ॉल्‍ट सेट हैं"</string>
     <string name="launch_defaults_none" msgid="8049374306261262709">"कोई डिफ़ॉल्‍ट सेट नहीं है"</string>
     <string name="tts_settings" msgid="8130616705989351312">"लेख से बोली सेटिंग"</string>
-    <string name="tts_settings_title" msgid="7602210956640483039">"लिखाई को बोली में बदलने की सुविधा"</string>
+    <string name="tts_settings_title" msgid="7602210956640483039">"लिखे गए शब्दों को सुनने की सुविधा"</string>
     <string name="tts_default_rate_title" msgid="3964187817364304022">"बोलने की दर"</string>
     <string name="tts_default_rate_summary" msgid="3781937042151716987">"बोलने की गति तय करें"</string>
     <string name="tts_default_pitch_title" msgid="6988592215554485479">"पिच"</string>
@@ -264,7 +286,7 @@
     <string name="bugreport_in_power" msgid="8664089072534638709">"गड़बड़ी की रिपोर्ट का शॉर्टकट"</string>
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"गड़बड़ी की रिपोर्ट लेने के लिए पावर मेन्यू में कोई बटन दिखाएं"</string>
     <string name="keep_screen_on" msgid="1187161672348797558">"स्क्रीन को चालू रखें"</string>
-    <string name="keep_screen_on_summary" msgid="1510731514101925829">"चार्ज करते समय स्‍क्रीन कभी भी बंद नहीं होगी"</string>
+    <string name="keep_screen_on_summary" msgid="1510731514101925829">"चार्ज होते समय स्‍क्रीन कभी भी बंद नहीं होगी"</string>
     <string name="bt_hci_snoop_log" msgid="7291287955649081448">"ब्लूटूथ HCI स्‍नूप लॉग चालू करें"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"ब्लूटूथ पैकेट कैप्चर करें. (यह सेटिंग बदलने के बाद ब्लूटूथ टॉगल करें)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"OEM अनलॉक करें"</string>
@@ -304,8 +326,8 @@
     <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"निजी डीएनएस मोड चुनें"</string>
     <string name="private_dns_mode_off" msgid="7065962499349997041">"बंद"</string>
     <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"अपने-आप"</string>
-    <string name="private_dns_mode_provider" msgid="3619040641762557028">"निजी डीएनएस सेवा देने वाले का होस्टनेम"</string>
-    <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"डीएनएस सेवा देने वाले का होस्टनेम डालें"</string>
+    <string name="private_dns_mode_provider" msgid="3619040641762557028">"निजी डीएनएस प्रोवाइडर का होस्टनेम"</string>
+    <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"डीएनएस प्रोवाइडर का होस्टनेम डालें"</string>
     <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"कनेक्‍ट नहीं हो सका"</string>
     <string name="wifi_display_certification_summary" msgid="8111151348106907513">"वायरलेस डिसप्ले सर्टिफ़िकेशन के विकल्प दिखाएं"</string>
     <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"वाई-फ़ाई लॉगिंग लेवल बढ़ाएं, वाई-फ़ाई पिकर में हर SSID के लिए RSSI दिखाएं"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"मानकर चलें कि ऐप्लिकेशन, नए फ़ॉर्मैट के साथ काम करेंगे"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ट्रांसकोडिंग की सूचनाएं दिखाएं"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"कैश को ट्रांसकोड करने की सुविधा बंद करें"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine की सेटिंग"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 फ़ॉलबैक लागू करें"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"कॉन्टेंट पर L3 फ़ॉलबैक लागू करने की सेटिंग चुनें"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"चालू सेवाएं"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"इस समय चल रही सेवाओं को देखें और कंट्रोल करें"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"वेबव्यू लागू करें"</string>
@@ -618,7 +637,7 @@
     <string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"नया मेहमान खाता बनाया जा रहा है…"</string>
     <string name="add_user_failed" msgid="4809887794313944872">"नया उपयोगकर्ता जोड़ा नहीं जा सका"</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"नया मेहमान खाता नहीं बनाया जा सका"</string>
-    <string name="user_nickname" msgid="262624187455825083">"प्रचलित नाम"</string>
+    <string name="user_nickname" msgid="262624187455825083">"निकनेम"</string>
     <string name="edit_user_info_message" msgid="6677556031419002895">"आपकी चुनी गई फ़ोटो और नाम, उन सभी लोगों को दिखेगा जो इस डिवाइस का इस्तेमाल करते हैं."</string>
     <string name="user_add_user" msgid="7876449291500212468">"उपयोगकर्ता जोड़ें"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"मेहमान जोड़ें"</string>
@@ -630,7 +649,7 @@
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"हटाएं"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"मेहमान के तौर पर ब्राउज़ करने का सेशन रीसेट किया जा रहा है…"</string>
     <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"क्या मेहमान मोड के मौजूदा सेशन को रीसेट करना है?"</string>
-    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"ऐसा करने पर, मेहमान के तौर पर ब्राउज़ करने का एक नया सेशन शुरू हो जाएगा. साथ ही, मौजूदा सेशन का डेटा और इस्तेमाल किए जा रहे ऐप्लिकेशन को मिटा दिया जाएगा"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"इससे मेहमान के तौर पर ब्राउज़ करने का नया सेशन शुरू हो जाएगा. इसके अलावा, इस्तेमाल किए जा रहे ऐप्लिकेशन पर की गई गतिविधि और मौजूदा सेशन का डेटा मिटा दिया जाएगा"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"मेहमान मोड से बाहर निकलना है?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"इससे, मेहमान मोड के मौजूदा सेशन का डेटा और इसमें इस्तेमाल हो रहे ऐप्लिकेशन मिट जाएंगे"</string>
     <string name="grant_admin" msgid="4323199171790522574">"हां, इन्हें एडमिन बनाएं"</string>
@@ -643,11 +662,9 @@
     <string name="guest_exit_button" msgid="5774985819191803960">"मेहमान मोड से बाहर निकलें"</string>
     <string name="guest_reset_button" msgid="2515069346223503479">"मेहमान मोड के सेशन को रीसेट करें"</string>
     <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"मेहमान मोड से बाहर निकलें"</string>
-    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"बाहर निकलने पर, सारी गतिविधि मिट जाएगी"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"बाहर निकलने पर, सभी गतिविधियां मिट जाएंगी"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"बाहर निकलने पर, गतिविधि को मिटाया या सेव किया जा सकता है"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"सेशन की गतिविधि को अभी मिटाने के लिए, रीसेट करें. इसके अलावा, बाहर निकलने पर, गतिविधि को मिटाया या सेव किया जा सकता है"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"फ़ोटो खींचें"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"कोई इमेज चुनें"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"फ़ोटो चुनें"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"कई बार गलत कोशिशें की गई हैं. इस डिवाइस का डेटा मिटा दिया जाएगा."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"कई बार गलत कोशिशें की गई हैं. इस उपयोगकर्ता को मिटा दिया जाएगा."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ईथरनेट डिस्‍कनेक्‍ट किया गया."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ईथरनेट."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"वॉइस कॉल की सुविधा उपलब्ध नहीं है."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"प्रोफ़ाइल फ़ोटो चुनें"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"उपयोगकर्ता के लिए डिफ़ॉल्ट आइकॉन"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"फ़िज़िकल कीबोर्ड"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"कीबोर्ड का लेआउट चुनें"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"डिफ़ॉल्ट"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 9c0ef25..a504c9a0 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -106,7 +106,29 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivno, samo lijevo"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivno, samo desno"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivno, lijevo i desno"</string>
-    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Medijski zvuk"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
+    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Zvuk medija"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonski pozivi"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prijenos datoteke"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ulazni uređaj"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Pretpostavi da aplikacije podržavaju moderne formate"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Prikaži obavijesti o konvertiranju"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Onemogući predmemoriju za konvertiranje"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Postavke Widevinea"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Prisilna L3 zamjena"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Odaberite za prisilnu L3 zamjenu"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Pokrenute usluge"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Pregledajte i kontrolirajte trenutačno pokrenute usluge"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementacija WebViewa"</string>
@@ -518,7 +537,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Upotrijebi jezike sustava"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Otvaranje postavki za aplikaciju <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> nije uspjelo"</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"Ovaj način unosa možda može prikupljati sav tekst koji unosite, uključujući osobne podatke poput zaporki i brojeva kreditnih kartica. To omogućuje aplikacija <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Upotrijebiti taj način unosa?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Napomena: ova se aplikacija ne može pokrenuti nakon ponovnog pokretanja dok ne otključate telefon"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Napomena: nakon ponovnog pokretanja, ovu aplikaciju ne možete pokrenuti dok ne otključate telefon"</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"Stanje registracije IMS-a"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"Registrirano"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Nije registrirano"</string>
@@ -640,14 +659,12 @@
     <string name="guest_exit_dialog_message_non_ephemeral" msgid="223385323235719442">"Možete spremiti aktivnosti iz ove sesije ili izbrisati sve aplikacije i podatke"</string>
     <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Izbriši"</string>
     <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Spremi"</string>
-    <string name="guest_exit_button" msgid="5774985819191803960">"Izlaz iz načina rada za goste"</string>
+    <string name="guest_exit_button" msgid="5774985819191803960">"Izađi iz načina rada za goste"</string>
     <string name="guest_reset_button" msgid="2515069346223503479">"Poništi gostujuću sesiju"</string>
     <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Izlaz iz gostujuće sesije"</string>
-    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Sve će se aktivnosti izbrisati na izlasku"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Sve će se aktivnosti izbrisati po izlasku"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Svoje aktivnosti možete spremiti ili izbrisati na izlasku"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Poništite da odmah izbrišete aktivnost sesije. Inače je možete spremiti ili izbrisati na izlasku."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Fotografiraj"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Odaberi sliku"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Odabir slike"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Previše netočnih pokušaja. S uređaja će se izbrisati podaci."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Previše netočnih pokušaja. Ovaj će se korisnik izbrisati."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Prekinuta je veza s ethernetom."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Bez poziva."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Odaberite profilnu sliku"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Ikona zadanog korisnika"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fizička tipkovnica"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Odaberite raspored tipkovnice"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Zadano"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index d2a959a..3838d7d0 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -106,7 +106,29 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktív, csak bal"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktív, csak jobb"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktív, bal és jobb"</string>
-    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Média audió"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
+    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Médiahang"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonhívások"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fájlátvitel"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Beviteli eszköz"</string>
@@ -263,9 +285,9 @@
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, debug, dev"</string>
     <string name="bugreport_in_power" msgid="8664089072534638709">"Hibabejelentési gomb"</string>
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Gomb megjelenítése a bekapcsolási menüben hibajelentés készítéséhez"</string>
-    <string name="keep_screen_on" msgid="1187161672348797558">"Nem kapcsolódik ki"</string>
+    <string name="keep_screen_on" msgid="1187161672348797558">"Ne kapcsoljon ki"</string>
     <string name="keep_screen_on_summary" msgid="1510731514101925829">"A képernyő soha nem kapcsol ki töltés során"</string>
-    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Bluetooth HCI snoop napló engedélyezése"</string>
+    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Bluetooth HCI kémlelésnapló engedélyezése"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Bluetooth-csomagok rögzítése. (Bluetooth be-, illetve kikapcsolása a beállítás módosítása után)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"OEM-feloldás"</string>
     <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"A rendszerbetöltő feloldásának engedélyezése"</string>
@@ -341,7 +363,7 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"Bekapcsolja az Enhanced Connectivity funkciót."</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"Helyi végpont"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"Végalkalmazás engedélyezése a helyi rendszerhéj eléréséhez"</string>
-    <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ellenőrzés"</string>
+    <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP-ellenőrzés"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCP-ellenőrzés beállítása"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"Hibakeresés"</string>
     <string name="debug_app" msgid="8903350241392391766">"Hibakereső alkalmazás kiválasztása"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Annak feltételezése, hogy az alkalmazások támogatják a modern formátumokat"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Átkódolási értesítések megjelenítése"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Átkódolási gyorsítótár kikapcsolása"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine-beállítások"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 fallback kényszerítése"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Jelölje ki az L3 fallback kényszerítéséhez"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Futó szolgáltatások"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"A jelenleg futó szolgáltatások megtekintése és vezérlése"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-megvalósítás"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"A kilépéssel minden tevékenység törlődik"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"A kilépéskor mentheti vagy törölheti a tevékenységeket"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Visszaállítással azonnal törölheti, illetve kilépéskor mentheti vagy törölheti a tevékenységeket"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Fotó készítése"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Kép kiválasztása"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Fotó kiválasztása"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Túl sok sikertelen próbálkozás. A rendszer törli az adatokat az eszközről."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Túl sok sikertelen próbálkozás. A rendszer törli ezt a felhasználót."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet leválasztva."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Nem kezdeményezhet hanghívást."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Profilkép választása"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Alapértelmezett felhasználó ikonja"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fizikai billentyűzet"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Billentyűzetkiosztás kiválasztása"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Alapértelmezett"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 80ff58e..0069175 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -106,12 +106,34 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ակտիվ, միայն ձախ"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ակտիվ, միայն աջ"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ակտիվ, ձախ և աջ"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Մեդիա աուդիո"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Հեռախոսազանգեր"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Ֆայլերի փոխանցում"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ներմուծման սարք"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Ինտերնետի հասանելիություն"</string>
-    <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Տրամադրել կոնտակտները և զանգերի պատմութ․"</string>
+    <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Կոնտակտների և զանգերի մատյանի հասանելիություն"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Տվյալները կօգտագործվեն զանգերի ծանուցումների համար և այլն"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Ինտերնետ կապի տարածում"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS հաղորդագրություններ"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Ենթադրել, որ հավելվածներն աջակցում են ժամանակակից ձևաչափեր"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Ցույց տալ տրանսկոդավորման մասին ծանուցումները"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Անջատել տրանսկոդավորման քեշը"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine-ի կարգավորումներ"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 պահուստային տարբերակի ստիպողական գործարկում"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Ընտրեք՝ L3 պահուստային տարբերակը ստիպողաբար գործարկելու համար"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Աշխատող ծառայություններ"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Դիտել և վերահսկել ընթացիկ աշխատող ծառայությունները"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ծառայություն"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Եթե դուրս գաք, ամբողջ պատմությունը կջնջվի"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Դուրս գալիս կարող եք պահել կամ ջնջել ձեր պատմությունը"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Վերակայեք աշխատաշրջանի պատմությունը հիմա կամ պահեք/ջնջեք այն դուրս գալիս"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Լուսանկարել"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Ընտրել պատկեր"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Ընտրեք լուսանկար"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Չափից շատ սխալ փորձեր են արվել։ Այս սարքի տվյալները կջնջվեն։"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Չափից շատ սխալ փորձեր են արվել։ Oգտատիրոջ պրոֆիլը կջնջվի։"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet-ը անջատված է:"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet։"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Զանգել հնարավոր չէ։"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Ընտրեք պրոֆիլի նկար"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Օգտատիրոջ կանխադրված պատկերակ"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Ֆիզիկական ստեղնաշար"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Ընտրեք ստեղնաշարի դասավորությունը"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Կանխադրված"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index d5ae5b8..6254f7b 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -106,13 +106,35 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktif, hanya kiri"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktif, hanya kanan"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktif, kiri dan kanan"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Audio media"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Panggilan telepon"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transfer file"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Perangkat masukan"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Akses Internet"</string>
     <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Izinkan akses ke kontak dan histori panggilan"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Info akan digunakan untuk pengumuman panggilan dan lainnya"</string>
+    <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Info akan digunakan untuk pengumuman panggilan dan lain-lain"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Berbagi koneksi internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"SMS"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Akses SIM"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Asumsikan aplikasi mendukung format modern"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Tampilkan notifikasi transcoding"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Nonaktifkan cache transcoding"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Setelan Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Paksa penggantian L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Pilih untuk memaksa penggantian L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Layanan yang sedang berjalan"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Lihat dan kontrol layanan yang sedang berjalan"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Penerapan WebView"</string>
@@ -518,7 +537,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Gunakan bahasa sistem"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Gagal membuka setelan untuk <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"Metode masukan ini mungkin dapat mengumpulkan semua teks yang Anda ketik, termasuk data pribadi seperti sandi dan nomor kartu kredit. Metode ini berasal dari aplikasi <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Gunakan metode masukan ini?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Catatan: Setelah boot ulang, aplikasi ini tidak dapat dimulai hingga kunci ponsel dibuka"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Catatan: Setelah perangkat dimulai ulang, aplikasi ini tidak dapat mulai berjalan hingga kunci ponsel dibuka"</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"Status pendaftaran IMS"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"Terdaftar"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Tidak terdaftar"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Semua aktivitas akan dihapus saat Anda keluar"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Anda dapat menyimpan atau menghapus aktivitas saat keluar"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reset untuk hapus aktivitas sesi sekarang, atau simpan atau hapus aktivitas saat keluar"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Ambil foto"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Pilih gambar"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Pilih foto"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Terlalu banyak percobaan yang salah. Data perangkat ini akan dihapus."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Terlalu banyak percobaan yang salah. Pengguna ini akan dihapus."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet terputus."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Tidak ada panggilan."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Pilih foto profil"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Ikon pengguna default"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Keyboard fisik"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Pilih tata letak keyboard"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Default"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 91fcb4c..0f57670 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Virkt, aðeins vinstra"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Virkt, aðeins hægra"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Virkt, vinstra og hægra"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Hljóð efnis"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Símtöl"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Skráaflutningur"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Gera ráð fyrir að forrit styðji nútímasnið"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Sýna umkóðunartilkynningar"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Slökkva á skyndiminni umkóðunar"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Stillingar Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Þvinga fram L3 varaleið"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Veldu til að þvinga fram L3 varaleið"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Þjónustur í gangi"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Skoða og stjórna þjónustum í gangi"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Innleiðing WebView"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Öllum aðgerðum verður eytt þegar lotu er lokað"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Þú getur vistað eða eytt aðgerðum þegar þú lokar"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Endurstilltu til að eyða aðgerðum lotu núna, eða vistaðu eða eyddu aðgerðum þegar þú lokar"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Taka mynd"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Velja mynd"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Velja mynd"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Of margar rangar tilraunir. Gögnum tækisins verður eytt."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Of margar rangar tilraunir. Þessum notanda verður eytt."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet aftengt."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Engin símtöl."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Veldu prófílmynd"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Tákn sjálfgefins notanda"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Vélbúnaðarlyklaborð"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Veldu lyklaskipan"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Sjálfgefið"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 865f451..9502374 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Attiva, solo sinistra"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Attiva, solo destra"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Attivo, destra e sinistra"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Audio multimediale"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonate"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Trasferimento file"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Presupponi che le app supportino i formati moderni"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Mostra notifiche relative alla transcodifica"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Disattiva memorizzazione nella cache per la transcodifica"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Impostazioni Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Forza riserva L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Seleziona per forzare riserva L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Servizi in esecuzione"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Visualizza e controlla i servizi attualmente in esecuzione"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementazione di WebView"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Quando esci verrà eliminata tutta l\'attività"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Quando esci puoi salvare o eliminare la tua attività"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reimposta la sessione per eliminare subito l\'attività, oppure salvala o eliminala quando esci"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Scatta una foto"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Scegli un\'immagine"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Seleziona la foto"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Troppi tentativi sbagliati. I dati del dispositivo verranno eliminati."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Troppi tentativi sbagliati. Questo utente verrà eliminato."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Connessione Ethernet annullata."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Chiamate non disponibili."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Scegli un\'immagine del profilo"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Icona dell\'utente predefinito"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Tastiera fisica"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Scegli layout tastiera"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Predefinito"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 3064f68..dea8ca3 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"פועל: שמאל בלבד"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"פועל: ימין בלבד"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"פועל: ימין ושמאל"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"אודיו של מדיה"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"שיחות טלפון"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"העברת קבצים"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"הנחת העבודה היא שאפליקציות תומכות בפורמטים מודרניים"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"הצגת התראות לגבי המרת קידוד"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"השבתת השמירה של המרת הקידוד במטמון"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"‏הגדרות Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"‏חלופה ל-Force L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"‏בחירה להפעלת חלופה ל-Force L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"שירותים פועלים"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"הצגת השירותים הפועלים כעת ושליטה בהם"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"‏יישום WebView"</string>
@@ -555,7 +574,7 @@
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"הטאבלט הזה"</string>
     <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
     <skip />
-    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"הרמקול של אביזר העגינה"</string>
+    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"רמקול של אביזר העגינה"</string>
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"מכשיר חיצוני"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"המכשיר המחובר"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"הטלפון הזה"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"כל הפעילות תימחק ביציאה"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"אפשר לשמור או למחוק את הפעילות שלך ביציאה"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"ניתן לאפס כדי למחוק את הפעילות מהסשן כעת, או לשמור או למחוק את הפעילות ביציאה"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"צילום תמונה"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"לבחירת תמונה"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"בחירת תמונה"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"נעשו יותר מדי ניסיונות שגויים. הנתונים במכשיר יימחקו."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"נעשו יותר מדי ניסיונות שגויים. המשתמש הזה יימחק."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"אתרנט מנותק."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"אתרנט."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"אין שיחות."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"בחירה של תמונת פרופיל"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"סמל המשתמש שמוגדר כברירת מחדל"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"מקלדת פיזית"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"בחירה של פריסת המקלדת"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ברירת מחדל"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index f3cddd3..c7f3c0a 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"有効、左のみ"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"有効、右のみ"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"有効、左と右"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"メディアの音声"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"電話"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ファイル転送"</string>
@@ -145,7 +167,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"キャンセル"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"ペア設定により、接続時に連絡先や通話履歴へのアクセスが許可されます。"</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>をペアに設定できません。"</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"PINまたはパスキーが正しくないため、<xliff:g id="DEVICE_NAME">%1$s</xliff:g>をペアに設定できませんでした。"</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"PIN またはパスキーが正しくないため、<xliff:g id="DEVICE_NAME">%1$s</xliff:g> をペアに設定できませんでした。"</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>と通信できません。"</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"ペア設定が<xliff:g id="DEVICE_NAME">%1$s</xliff:g>に拒否されました。"</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"コンピュータ"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"アプリによる最新形式のサポートを想定"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"コード変換に関する通知の表示"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"コード変換のキャッシュを無効にする"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine の設定"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 代替の強制"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 代替を強制するかどうか選択します"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"実行中のサービス"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"現在実行中のサービスを表示して制御する"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView の実装"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"終了時にすべてのアクティビティが削除されます"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"終了時にアクティビティを保存、削除できます"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"アクティビティは、リセットして今すぐ削除するか、終了時に保存または削除できます"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"写真を撮る"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"画像を選択"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"写真を選択"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"間違えた回数が上限を超えました。このデバイスのデータが削除されます。"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"間違えた回数が上限を超えました。このユーザーが削除されます。"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"イーサネット接続を解除しました。"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"イーサネット。"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"通話なし。"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"プロフィール写真の選択"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"デフォルト ユーザー アイコン"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"物理キーボード"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"キーボード レイアウトの選択"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"デフォルト"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 3a40b8e..a94a401 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"აქტიური, მხოლოდ მარცხნივ"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"აქტიური, მხოლოდ მარჯვნივ"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"აქტიური, მარცხნივ და მარჯვნივ"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"მედია აუდიო"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"სატელეფონო ზარები"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ფაილების გადაცემა"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"დაშვება, რომ აპებს აქვთ თანამედროვე ფორმატების მხარდაჭერა"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ტრანსკოდირების შეტყობინებების ჩვენება"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ტრანსკოდირების ქეშის გათიშვა"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine პარამეტრები"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Force L3 fallback"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"აირჩიეთ force L3 fallback"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"მიმდინარე სერვისები"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"ამჟამად მოქმედი სერვისების ნახვა და მართვა"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView რეალიზაცია"</string>
@@ -555,7 +574,7 @@
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ეს ტაბლეტი"</string>
     <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
     <skip />
-    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"დინამიკის სამაგრი"</string>
+    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"სამაგრის დინამიკი"</string>
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"გარე მოწყობილობა"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"დაკავშირებული მოწყობილობა"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"ეს ტელეფონი"</string>
@@ -619,7 +638,7 @@
     <string name="add_user_failed" msgid="4809887794313944872">"ახალი მომხმარებლის შექმნა ვერ მოხერხდა"</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"ახალი სტუმრის შექმნა ვერ მოხერხდა"</string>
     <string name="user_nickname" msgid="262624187455825083">"მეტსახელი"</string>
-    <string name="edit_user_info_message" msgid="6677556031419002895">"თქვენ მიერ არჩეული სახელი და სურათი ამ მოწყობილობით მოსარგებლე ნებისმიერი პირისთვის იქნება ხილვადი."</string>
+    <string name="edit_user_info_message" msgid="6677556031419002895">"სახელი და სურათი, რომელსაც აირჩევთ, ხილვადი იქნება ამ მოწყობილობით მოსარგებლე ნებისმიერი პირისთვის."</string>
     <string name="user_add_user" msgid="7876449291500212468">"მომხმარებლის დამატება"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"სტუმრის დამატება"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"სტუმრის ამოშლა"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"გასვლისას ყველა აქტივობა წაიშლება"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"გასვლისას შეგიძლიათ შეინახოთ ან წაშალოთ თქვენი აქტივობა"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"გადააყენეთ სესიის აქტივობის ახლა წასაშლელად. შენახვა/წაშლა გასვლისასაც შეიძლება."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ფოტოს გადაღება"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"აირჩიეთ სურათი"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ფოტოს არჩევა"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"დაფიქსირდა ზედმეტად ბევრი არასწორი მცდელობა. შედეგად, ამ მოწყობილობის მონაცემები წაიშლება."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"დაფიქსირდა ზედმეტად ბევრი არასწორი მცდელობა. შედეგად, ეს მომხმარებელი წაიშლება."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet კავშირი შეწყვეტილია."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"ზარების გარეშე."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"აირჩიეთ პროფილის სურათი"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"მომხმარებლის ნაგულისხმევი ხატულა"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"ფიზიკური კლავიატურა"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"აირჩიე კლავიატურის განლაგება"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ნაგულისხმევი"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 856a51e..1c80ad4 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -106,7 +106,29 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Тек сол жағы қосулы"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Тек оң жағы қосулы"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Екеуі де қосулы"</string>
-    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Meдиа аудиосы"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
+    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Mультимeдиа дыбысы"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Телефон қоңыраулары"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Файл жіберу"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Кіріс құрылғысы"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Қолданбалар қазіргі заманғы форматтарды қолдайды делік"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Қайта кодтау хабарландыруларын көрсету"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Қайта кодтау кэшін өшіру"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine параметрлері"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 баламасын мәжбүрлі түрде пайдалану"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 баламасын мәжбүрлі түрде пайдалануды таңдайсыз."</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Қосылып тұрған қызметтер"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Қазір істеп тұрған қызметтерді көру және басқару"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView қызметі"</string>
@@ -483,7 +502,7 @@
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Зарядталуда"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Жылдам зарядтау"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Баяу зарядталуда"</string>
-    <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Сымсыз зарядталуда"</string>
+    <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Сымсыз зарядталып жатыр"</string>
     <string name="battery_info_status_charging_dock" msgid="8573274094093364791">"Зарядталып жатыр."</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Зарядталу орындалып жатқан жоқ"</string>
     <string name="battery_info_status_not_charging" msgid="1103084691314264664">"Құрылғы жалғанған, бірақ зарядталып жатқан жоқ."</string>
@@ -518,7 +537,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Жүйелік тілдерді пайдалану"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> қолданбасы үшін параметрлерді ашу орындалмады"</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"Бұл енгізу әдісі сіз терген барлық мәтінді, кілтсөз және кредит карта нөмірлері сияқты жеке ақпаратты қоса, жинауы мүмкін. Бұл <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> қолданбасы арқылы жасалады. Осы әдіс қолданылсын ба?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Ескертпе: қайта жүктегеннен кейін, телефонның құлпын ашпайынша, бұл қолданба іске қосылмайды"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Ескертпе: қайта жүктегеннен кейін, телефонның құлпын ашпайынша, бұл қолданба іске қосылмайды."</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"IMS тіркеу күйі"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"Тіркелген"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Тіркелмеген"</string>
@@ -555,7 +574,7 @@
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Осы планшет"</string>
     <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
     <skip />
-    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Қондыру динамигі"</string>
+    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Динамигі бар қондыру станциясы"</string>
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Сыртқы құрылғы"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Жалғанған құрылғы"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Осы телефон"</string>
@@ -641,13 +660,11 @@
     <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Жою"</string>
     <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Сақтау"</string>
     <string name="guest_exit_button" msgid="5774985819191803960">"Қонақ режимінен шығу"</string>
-    <string name="guest_reset_button" msgid="2515069346223503479">"Қонақ режимін қалпына келтіру"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Қонақ режимін бастапқы күйге қайтару"</string>
     <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Қонақ режимінен шығу"</string>
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Шыққанда барлық әрекет жойылады."</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Шыққанда барлық әрекетті сақтай немесе жоя аласыз."</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Сеанс дерегін жою үшін оны бастапқы күйге қайтарыңыз. Деректі шығар кезде де сақтауға не жоюға болады."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Фотосуретке түсіру"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Сурет таңдау"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Фотосурет таңдау"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Тым көп қате әрекет жасалды. Бұл құрылғының деректері жойылады."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Тым көп қате әрекет жасалды. Бұл пайдаланушы жойылады."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet ажыратылған."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Қоңырау шалу мүмкін емес."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Профиль суретін таңдау"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Әдепкі пайдаланушы белгішесі"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Пернетақта"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Пернетақтаның орналасу ретін таңдау"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Әдепкі"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 719eed0..23bd55c 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"សកម្ម ខាងឆ្វេងតែប៉ុណ្ណោះ"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"សកម្មខាងស្ដាំតែប៉ុណ្ណោះ"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"សកម្មខាងឆ្វេង និងស្ដាំ"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"សំឡេង​មេឌៀ"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"ការហៅ​ទូរសព្ទ"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ផ្ទេរ​ឯកសារ"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"សន្មតថាកម្មវិធី​អាចប្រើ​ទម្រង់ទំនើបបាន"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"បង្ហាញការជូនដំណឹង​អំពីការបំប្លែងកូដ"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"បិទ​ឃ្លាំងបម្រុង​សម្រាប់​ការបំប្លែងកូដ"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"ការកំណត់ Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"បង្ខំជម្រើសជំនួស L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"ជ្រើសរើសដើម្បីបង្ខំជម្រើសជំនួស L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"សេវាកម្ម​កំពុង​ដំណើរការ"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"មើល និង​គ្រប់គ្រង​សេវាកម្ម​កំពុង​ដំណើរការ​បច្ចុប្បន្ន"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"ការអនុវត្ត WebView"</string>
@@ -555,7 +574,7 @@
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"ថេប្លេតនេះ"</string>
     <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
     <skip />
-    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"ឧបករណ៍បំពងសំឡេងដែលមានជើងភ្ជាប់"</string>
+    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"ឧបាល័រជើងទម្រ"</string>
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"ឧបករណ៍ខាងក្រៅ"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"​ឧបករណ៍ដែលបាន​ភ្ជាប់"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"ទូរសព្ទនេះ"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"សកម្មភាពទាំងអស់នឹងត្រូវលុបនៅពេលចាកចេញ"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"អ្នកអាចរក្សាទុក ឬលុបសកម្មភាពរបស់អ្នកនៅពេលចាកចេញ"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"កំណត់ឡើងវិញ ដើម្បីលុបសកម្មភាពក្នុងវគ្គឥឡូវនេះ ឬអ្នកអាចរក្សាទុកឬលុបសកម្មភាពនៅពេលចាកចេញ"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ថតរូប"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"ជ្រើសរើស​រូបភាព"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ជ្រើសរើស​​រូបថត"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"ដោយសារ​មានការព្យាយាម​ដោះសោ​មិនត្រឹមត្រូវ​ច្រើនដងពេក ទិន្នន័យ​របស់​ឧបករណ៍នេះ​នឹងត្រូវបាន​លុប។"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"ដោយសារមានការព្យាយាមដោះសោមិនត្រឹមត្រូវច្រើនដងពេក អ្នកប្រើប្រាស់នេះនឹងត្រូវបានលុប។"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"បានផ្តាច់អ៊ីសឺរណិត។"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"អ៊ីសឺរណិត។"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"គ្មាន​ការហៅ​ទូរសព្ទទេ​។"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"ជ្រើសរើស​រូបភាព​កម្រង​ព័ត៌មាន"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"រូបអ្នកប្រើប្រាស់លំនាំដើម"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"ក្ដារចុច​រូបវន្ត"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"ជ្រើសរើស​ប្លង់​ក្ដារចុច"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"លំនាំដើម"</string>
diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml
index 39c49a1..1c8112a 100644
--- a/packages/SettingsLib/res/values-kn/arrays.xml
+++ b/packages/SettingsLib/res/values-kn/arrays.xml
@@ -55,11 +55,11 @@
   </string-array>
   <string-array name="hdcp_checking_summaries">
     <item msgid="4045840870658484038">"HDCP ಪರಿಶೀಲನೆಯನ್ನು ಎಂದಿಗೂ ಬಳಸದಿರು"</item>
-    <item msgid="8254225038262324761">"DRM ವಿಷಯಗಳಿಗೆ ಮಾತ್ರ HDCP ಪರೀಕ್ಷಿಸುವಿಕೆಯನ್ನು ಬಳಸು"</item>
+    <item msgid="8254225038262324761">"DRM ಕಂಟೆಂಟ್‌ಗೆ ಮಾತ್ರ HDCP ಪರೀಕ್ಷಿಸುವಿಕೆಯನ್ನು ಬಳಸಿ"</item>
     <item msgid="6421717003037072581">"HDCP ಪರಿಶೀಲನೆಯನ್ನು ಯಾವಾಗಲೂ ಬಳಸು"</item>
   </string-array>
   <string-array name="bt_hci_snoop_log_entries">
-    <item msgid="695678520785580527">"ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ"</item>
+    <item msgid="695678520785580527">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</item>
     <item msgid="6336372935919715515">"ಫಿಲ್ಟರ್ ಮಾಡುವುದನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</item>
     <item msgid="2779123106632690576">"ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</item>
   </string-array>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index aa69689..c636dd5 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"ಎಡಕಿವಿಯ ಸಾಧನ ಮಾತ್ರ ಸಕ್ರಿಯವಾಗಿದೆ"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"ಬಲಕಿವಿಯ ಸಾಧನ ಮಾತ್ರ ಸಕ್ರಿಯವಾಗಿದೆ"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"ಎಡ ಮತ್ತು ಬಲಕಿವಿಯ ಸಾಧನಗಳು ಸಕ್ರಿಯವಾಗಿವೆ"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"ಮಾಧ್ಯಮ ಆಡಿಯೋ"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"ಫೋನ್ ಕರೆಗಳು"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ಫೈಲ್ ವರ್ಗಾವಣೆ"</string>
@@ -115,7 +137,7 @@
     <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"ಮಾಹಿತಿಯನ್ನು ಕರೆ ಪ್ರಕಟಣೆಗಳು ಹಾಗೂ ಇತ್ಯಾದಿಗಳಿಗಾಗಿ ಬಳಸಲಾಗುತ್ತದೆ"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕ ಹಂಚಿಕೊಳ್ಳುವಿಕೆ"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"ಪಠ್ಯ ಸಂದೇಶಗಳು"</string>
-    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"ಸಿಮ್ ಆ್ಯಕ್ಸೆಸ್"</string>
+    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"SIM ಆ್ಯಕ್ಸೆಸ್"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD ಆಡಿಯೋ: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD ಆಡಿಯೋ"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="2607867572569689732">"ಶ್ರವಣ ಸಾಧನಗಳು"</string>
@@ -180,7 +202,7 @@
     <string name="launch_defaults_some" msgid="3631650616557252926">"ಕೆಲವು ಡೀಫಾಲ್ಟ್‌ಗಳನ್ನು ಹೊಂದಿಸಲಾಗಿದೆ"</string>
     <string name="launch_defaults_none" msgid="8049374306261262709">"ಡೀಫಾಲ್ಟ್‌ಗಳನ್ನು ಹೊಂದಿಸಲಾಗಿಲ್ಲ"</string>
     <string name="tts_settings" msgid="8130616705989351312">"ಪಠ್ಯದಿಂದ ಧ್ವನಿಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
-    <string name="tts_settings_title" msgid="7602210956640483039">"ಪಠ್ಯದಿಂದ ಧ್ವನಿ ಔಟ್‌ಪುಟ್‌"</string>
+    <string name="tts_settings_title" msgid="7602210956640483039">"ಟೆಕ್ಸ್ಟ್-ಟು-ಸ್ಪೀಚ್ ಔಟ್‌ಪುಟ್‌"</string>
     <string name="tts_default_rate_title" msgid="3964187817364304022">"ಧ್ವನಿಯ ಪ್ರಮಾಣ"</string>
     <string name="tts_default_rate_summary" msgid="3781937042151716987">"ಪಠ್ಯವನ್ನು ಹೇಳಿದ ವೇಗ"</string>
     <string name="tts_default_pitch_title" msgid="6988592215554485479">"ಪಿಚ್"</string>
@@ -264,7 +286,7 @@
     <string name="bugreport_in_power" msgid="8664089072534638709">"ಬಗ್ ವರದಿಯ ಶಾರ್ಟ್‌ಕಟ್‌‌"</string>
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"ದೋಷ ವರದಿ ಮಾಡಲು ಪವರ್ ಮೆನುನಲ್ಲಿ ಬಟನ್ ತೋರಿಸು"</string>
     <string name="keep_screen_on" msgid="1187161672348797558">"ಎಚ್ಚರವಾಗಿರುವಿಕೆ"</string>
-    <string name="keep_screen_on_summary" msgid="1510731514101925829">"ಚಾರ್ಜ್ ಮಾಡುವಾಗ ಪರದೆಯು ಎಂದಿಗೂ ನಿದ್ರಾವಸ್ಥೆಗೆ ಹೋಗುವುದಿಲ್ಲ"</string>
+    <string name="keep_screen_on_summary" msgid="1510731514101925829">"ಚಾರ್ಜ್ ಮಾಡುತ್ತಿರುವಾಗ ಸ್ಕ್ರೀನ್ ಎಂದಿಗೂ ನಿದ್ರಾವಸ್ಥೆಗೆ ಹೋಗುವುದಿಲ್ಲ"</string>
     <string name="bt_hci_snoop_log" msgid="7291287955649081448">"ಬ್ಲೂಟೂತ್‌‌ HCI ಸ್ನೂಪ್‌ ಲಾಗ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"ಬ್ಲೂಟೂತ್ ಪ್ಯಾಕೆಟ್‌ಗಳನ್ನು ಕ್ಯಾಪ್ಚರ್‌ ಮಾಡಿ. (ಈ ಸೆಟ್ಟಿಂಗ್ ಅನ್ನು ಬದಲಾಯಿಸಿದ ನಂತರ ಬ್ಲೂಟೂತ್ ಟಾಗಲ್ ಮಾಡಿ)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"OEM ಅನ್‌ಲಾಕ್‌ ಮಾಡುವಿಕೆ"</string>
@@ -411,7 +433,7 @@
     <string name="enable_freeform_support" msgid="7599125687603914253">"ಮುಕ್ತಸ್ವರೂಪದ ವಿಂಡೊಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
     <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ಪ್ರಾಯೋಗಿಕ ಫ್ರೀಫಾರ್ಮ್ ವಿಂಡೊಗಳಿಗೆ ಬೆಂಬಲವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿ."</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"ಡೆಸ್ಕ್‌ಟಾಪ್ ಬ್ಯಾಕಪ್ ಪಾಸ್‌ವರ್ಡ್"</string>
-    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ಡೆಸ್ಕ್‌ಟಾಪ್‌‌ನ ಪೂರ್ಣ ಬ್ಯಾಕಪ್‌‌ಗಳನ್ನು ಪ್ರಸ್ತುತ ರಕ್ಷಿಸಲಾಗಿಲ್ಲ"</string>
+    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ಡೆಸ್ಕ್‌ಟಾಪ್‌‌ ಪೂರ್ಣ ಬ್ಯಾಕಪ್‌‌ಗಳನ್ನು ಪ್ರಸ್ತುತ ರಕ್ಷಿಸಲಾಗಿಲ್ಲ"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ಡೆಸ್ಕ್‌ಟಾಪ್‌ನ ಪೂರ್ಣ ಬ್ಯಾಕಪ್‌ಗಳಿಗೆ ಪಾಸ್‌ವರ್ಡ್‌ ಬದಲಾಯಿಸಲು ಅಥವಾ ತೆಗೆದುಹಾಕಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="local_backup_password_toast_success" msgid="4891666204428091604">"ಹೊಸ ಬ್ಯಾಕಪ್ ಪಾಸ್‌ವರ್ಡ್‌ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"ಹೊಸ ಪಾಸ್‌ವರ್ಡ್‌ ಮತ್ತು ದೃಢೀಕರಣ ಹೊಂದಾಣಿಕೆಯಾಗುತ್ತಿಲ್ಲ"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"ಆ್ಯಪ್‌ಗಳು ಆಧುನಿಕ ಫಾರ್ಮ್ಯಾಟ್‌ಗಳನ್ನು ಬೆಂಬಲಿಸುತ್ತದೆ ಎಂದು ಊಹಿಸಿ"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ಟ್ರಾನ್ಸ್‌ಕೋಡಿಂಗ್ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸಿ"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ಟ್ರಾನ್ಸ್‌ಕೋಡಿಂಗ್ ಕ್ಯಾಷ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Force L3 ಫಾಲ್‌ಬ್ಯಾಕ್"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Force L3 ಫಾಲ್‌ಬ್ಯಾಕ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"ರನ್‌ ಆಗುತ್ತಿರುವ ಸೇವೆಗಳು"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"ಈಗ ರನ್‌ ಆಗುತ್ತಿರುವ ಸೇವೆಗಳನ್ನು ವೀಕ್ಷಿಸಿ ಮತ್ತು ನಿಯಂತ್ರಿಸಿ"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ಹೊಂದಿಸಿ"</string>
@@ -597,7 +616,7 @@
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"ನಿರ್ಬಂಧಿಸಿದ ಪ್ರೊಫೈಲ್"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಬೇಕೆ?"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"ನೀವು ಹೆಚ್ಚುವರಿ ಬಳಕೆದಾರರನ್ನು ರಚಿಸುವ ಮೂಲಕ ಇತರ ಜನರ ಜೊತೆಗೆ ಈ ಸಾಧನವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು. ಪ್ರತಿ ಬಳಕೆದಾರರು ತಮ್ಮದೇ ಸ್ಥಳವನ್ನು ಹೊಂದಿರುತ್ತಾರೆ, ಇದರಲ್ಲಿ ಅವರು ತಮ್ಮದೇ ಆ್ಯಪ್‌ಗಳು, ವಾಲ್‌ಪೇಪರ್ ಮತ್ತು ಮುಂತಾದವುಗಳ ಮೂಲಕ ಕಸ್ಟಮೈಸ್ ಮಾಡಿಕೊಳ್ಳಬಹುದು. ಎಲ್ಲರ ಮೇಲೂ ಪರಿಣಾಮ ಬೀರುವಂತೆ ವೈ-ಫೈ ರೀತಿಯ ಸಾಧನ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಬಳಕೆದಾರರು ಸರಿಹೊಂದಿಸಬಹುದು.\n\nನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ತಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಟಪ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗೆ ಆ್ಯಪ್‌ಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು. ಆ್ಯಕ್ಸೆಸಿಬಿಲಿಟಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಸೇವೆಗಳು ಹೊಸ ಬಳಕೆದಾರರಿಗೆ ವರ್ಗಾವಣೆ ಆಗದಿರಬಹುದು."</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"ನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ತಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಟಪ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರೆ ಬಳಕೆದಾರರಿಗಾಗಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು."</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"ನೀವು ಒಬ್ಬ ಹೊಸ ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿದಾಗ, ಆ ವ್ಯಕ್ತಿಯು ತಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಟಪ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ.\n\nಯಾವುದೇ ಬಳಕೆದಾರರು ಎಲ್ಲಾ ಇತರ ಬಳಕೆದಾರರಿಗಾಗಿ ಆ್ಯಪ್‌ಗಳನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು."</string>
     <string name="user_grant_admin_title" msgid="5157031020083343984">"ಈ ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಾಹಕರನ್ನಾಗಿ ಮಾಡಬೇಕೆ?"</string>
     <string name="user_grant_admin_message" msgid="1673791931033486709">"ನಿರ್ವಾಹಕರು ಇತರ ಬಳಕೆದಾರರಿಗೆ ಇಲ್ಲದ ವಿಶೇಷ ಸೌಲಭ್ಯಗಳನ್ನು ಹೊಂದಿದ್ದಾರೆ. ನಿರ್ವಾಹಕರು ಎಲ್ಲಾ ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಹಿಸಬಹುದು, ಈ ಸಾಧನವನ್ನು ಅಪ್‌ಡೇಟ್‌ ಮಾಡಬಹುದು ಅಥವಾ ರೀಸೆಟ್ ಮಾಡಬಹುದು, ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಹೊಂದಿಸಬಹುದು, ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲಾದ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳನ್ನು ವೀಕ್ಷಿಸಬಹುದು ಮತ್ತು ಇತರರಿಗೆ ನಿರ್ವಾಹಕರಿಗೆ ನೀಡಿರುವ ಸೌಲಭ್ಯಗಳನ್ನು ನೀಡಬಹುದು ಅಥವಾ ಹಿಂತೆಗೆದುಕೊಳ್ಳಬಹುದು."</string>
     <string name="user_grant_admin_button" msgid="5441486731331725756">"ನಿರ್ವಾಹಕರನ್ನಾಗಿ ಮಾಡಿ"</string>
@@ -625,7 +644,7 @@
     <string name="guest_exit_guest" msgid="5908239569510734136">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಿ"</string>
     <string name="guest_reset_guest" msgid="6110013010356013758">"ಅತಿಥಿಯನ್ನು ಮರುಹೊಂದಿಸಿ"</string>
     <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"ಅತಿಥಿ ಬಳಕೆದಾರರನ್ನು ರೀಸೆಟ್ ಮಾಡಬೇಕೆ?"</string>
-    <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಬೇಕೇ?"</string>
+    <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"ಅತಿಥಿಯನ್ನು ತೆಗೆದುಹಾಕಬೇಕೆ?"</string>
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"ರೀಸೆಟ್ ಮಾಡಿ"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"ತೆಗೆದುಹಾಕಿ"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"ಅತಿಥಿ ಬಳಕೆದಾರರ ಸೆಟ್ಟಿಂಗ್ ಅನ್ನು ರೀಸೆಟ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ನಿರ್ಗಮಿಸುವಾಗ ಎಲ್ಲಾ ಚಟುವಟಿಕೆಯನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ನಿರ್ಗಮಿಸುವಾಗ ನಿಮ್ಮ ಚಟುವಟಿಕೆಯನ್ನು ನೀವು ಉಳಿಸಬಹುದು ಅಥವಾ ಅಳಿಸಬಹುದು"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"ಸೆಶನ್ ಚಟುವಟಿಕೆಯನ್ನು ಈಗ ಅಳಿಸಲು ರೀಸೆಟ್ ಮಾಡಿ ಅಥವಾ ನಿರ್ಗಮಿಸುವಾಗ ನೀವು ಚಟುವಟಿಕೆಯನ್ನು ಉಳಿಸಬಹುದು ಅಥವಾ ಅಳಿಸಬಹುದು"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ಫೋಟೋ ತೆಗೆದುಕೊಳ್ಳಿ"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"ಚಿತ್ರವನ್ನು ಆರಿಸಿ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ಫೋಟೋ ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"ಹಲವಾರು ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಈ ಸಾಧನದ ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"ಹಲವಾರು ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಈ ಬಳಕೆದಾರರನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ಇಥರ್ನೆಟ್ ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿದೆ."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ಇಥರ್ನೆಟ್."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"ಕರೆ ಮಾಡಲಾಗುವುದಿಲ್ಲ."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"ಪ್ರೊಫೈಲ್ ಚಿತ್ರವನ್ನು ಆಯ್ಕೆ ಮಾಡಿ"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"ಡೀಫಾಲ್ಟ್ ಬಳಕೆದಾರರ ಐಕಾನ್"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"ಕೀಬೋರ್ಡ್ ಲೇಔಟ್ ಆರಿಸಿ"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ಡೀಫಾಲ್ಟ್"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 79e119b..f193fef 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"활성, 왼쪽만"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"활성, 오른쪽만"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"활성, 왼쪽 및 오른쪽"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"미디어 오디오"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"전화 통화"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"파일 전송"</string>
@@ -145,7 +167,7 @@
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"취소"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"페어링하면 연결 시 연락처 및 통화 기록에 액세스할 수 있습니다."</string>
     <string name="bluetooth_pairing_error_message" msgid="6626399020672335565">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>와(과) 페어링하지 못했습니다."</string>
-    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"PIN 또는 패스키가 잘못되어 <xliff:g id="DEVICE_NAME">%1$s</xliff:g>와 페어링하지 못했습니다."</string>
+    <string name="bluetooth_pairing_pin_error_message" msgid="264422127613704940">"PIN 또는 패스키가 잘못되어 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 기기와 페어링할 수 없습니다."</string>
     <string name="bluetooth_pairing_device_down_error_message" msgid="2554424863101358857">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>와(과) 통신할 수 없습니다."</string>
     <string name="bluetooth_pairing_rejected_error_message" msgid="5943444352777314442">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>에서 페어링을 거부했습니다."</string>
     <string name="bluetooth_talkback_computer" msgid="3736623135703893773">"컴퓨터"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"앱이 최신 형식을 지원하는 것으로 가정"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"트랜스코딩 알림 표시"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"트랜스코딩 캐시 사용 중지"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine 설정"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 대체 강제"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 대체를 강제하려면 선택하세요."</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"실행 중인 서비스"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"현재 실행 중인 서비스 보기 및 제어"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView 구현"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"종료하면 모든 활동이 삭제됩니다."</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"종료 시 활동을 저장하거나 삭제할 수 있습니다."</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"지금 재설정하여 활동 세션을 삭제하거나 종료 시 활동을 저장 또는 삭제할 수 있습니다."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"사진 찍기"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"이미지 선택"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"사진 선택"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"잘못된 시도 횟수가 너무 많습니다. 이 기기의 데이터가 삭제됩니다."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"잘못된 시도 횟수가 너무 많습니다. 이 사용자가 삭제됩니다."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"이더넷에서 연결 해제되었습니다."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"이더넷에 연결되었습니다."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"통화 모드가 없습니다."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"프로필 사진 선택하기"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"기본 사용자 아이콘"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"물리적 키보드"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"키보드 레이아웃 선택"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"기본"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index c547bb8b..86426fa 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Иштеп жатат, сол кулак гана"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Жигердүү, оң кулакчын гана"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Жигердүү, сол жана оң кулакчын"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Аудио"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Телефон чалуулар"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Файл алмашуу"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Колдонмолордо заманбап форматтар колдоого алынат"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Транскоддоо билдирмелерин көрсөтүү"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Транскоддоо кешин өчүрүү"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine параметрлери"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 деңгээлин мажбурлап артка кайтаруу"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 деңгээлин мажбурлап артка кайтаруу үчүн тандаңыз"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Иштеп жаткан кызматтар"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Учурда иштеп жаткан кызматтарды көрүп, көзөмөлдөп турасыз"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView кызматы"</string>
@@ -555,7 +574,7 @@
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Ушул планшет"</string>
     <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
     <skip />
-    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Док бекети үчүн динамик"</string>
+    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Док бекеттин динамиги"</string>
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Тышкы түзмөк"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Туташкан түзмөк"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ушул телефон"</string>
@@ -624,12 +643,12 @@
     <string name="guest_new_guest" msgid="3482026122932643557">"Конок кошуу"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Конокту өчүрүү"</string>
     <string name="guest_reset_guest" msgid="6110013010356013758">"Конок сеансын баштапкы абалга келтирүү"</string>
-    <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Конок сеансын баштапкы абалга келтиресизби?"</string>
+    <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Конок сеансын кайра коёсузбу?"</string>
     <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Конокту өчүрөсүзбү?"</string>
-    <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Баштапкы абалга келтирүү"</string>
+    <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Ооба"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Өчүрүү"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Конок сеансы баштапкы абалга келтирилүүдө…"</string>
-    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Конок сеансын баштапкы абалга келтиресизби?"</string>
+    <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Конок сеансын кайра коёсузбу?"</string>
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Бул аракет жаңы конок сеансын баштап, учурдагы сеанстагы бардык колдонмолорду жана алардагы нерселерди жок кылат"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Конок режиминен чыгасызбы?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Учурдагы конок сеансындагы бардык колдонмолор менен алардагы нерселер өчүп калат"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Чыксаңыз, бардык аракеттер өчүп калат"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Чыгуудан мурун аракеттериңизди сактап же жок кылсаңыз болот"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Сеанстагы аракеттерди азыр өчүрсөңүз болот же чыгып баратып өчүрүп же сактап коюңуз"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Сүрөткө тартуу"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Сүрөт тандаңыз"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Сүрөт тандаңыз"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Өтө көп жолу туура эмес аракет кылынды. Бул түзмөктүн дайындары жок кылынат."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Өтө көп жолу жаңылдыңыз. Бул колдонуучу өчүрүлөт."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet ажырады."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Чалуу жок."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Профилдин сүрөтүн тандоо"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Демейки колдонуучунун сүрөтчөсү"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Аппараттык баскычтоп"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Тергичтин жайылмасын тандоо"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Демейки"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index c352c78..ad1529d 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"ນຳໃຊ້ຢູ່, ຊ້າຍເທົ່ານັ້ນ"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"ນຳໃຊ້ຢູ່, ຂວາເທົ່ານັ້ນ"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"ນຳໃຊ້ຢູ່, ຊ້າຍ ແລະ ຂວາ"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"ສຽງ"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"ການໂທ"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ການໂອນຍ້າຍໄຟລ໌"</string>
@@ -219,7 +241,7 @@
     <item msgid="6946761421234586000">"400%"</item>
   </string-array>
     <string name="choose_profile" msgid="343803890897657450">"ເລືອກໂປຣໄຟລ໌"</string>
-    <string name="category_personal" msgid="6236798763159385225">"​ສ່ວນ​ໂຕ"</string>
+    <string name="category_personal" msgid="6236798763159385225">"ສ່ວນຕົວ"</string>
     <string name="category_work" msgid="4014193632325996115">"​ບ່ອນ​ເຮັດ​ວຽກ"</string>
     <string name="category_private" msgid="4244892185452788977">"ສ່ວນຕົວ"</string>
     <string name="category_clone" msgid="1554511758987195974">"ໂຄລນ"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"ສົມມຸດວ່າແອັບຮອງຮັບຮູບແບບສະໄໝໃໝ່"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ສະແດງການແຈ້ງເຕືອນການ​ປ່ຽນ​ຮູບ​ແບບ​ລະ​ຫັດ"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ປິດການນຳໃຊ້ແຄສການ​ປ່ຽນ​ຮູບ​ແບບ​ລະ​ຫັດ"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"ການຕັ້ງຄ່າ Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"ບັງຄັບທາງເລືອກ L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"ເລືອກເພື່ອບັງຄັບທາງເລືອກ L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"ບໍລິການທີ່ເຮັດວຽກຢູ່"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"ເບິ່ງ ແລະ ຈັດການບໍລິການທີ່ກຳລັງເຮັດວຽກຢູ່ໃນປັດຈຸບັນ"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"ການຈັດຕັ້ງປະຕິບັດ WebView"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ການເຄື່ອນໄຫວທັງໝົດຈະຖືກລຶບໃນຕອນອອກ"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ທ່ານສາມາດບັນທຶກ ຫຼື ລຶບການເຄື່ອນໄຫວຂອງທ່ານໃນຕອນອອກໄດ້"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"ຣີເຊັດເພື່ອລຶບການເຄື່ອນໄຫວເຊດຊັນຕອນນີ້ ຫຼື ທ່ານສາມາດບັນທຶກ ຫຼື ລຶບການເຄື່ອນໄຫວໃນຕອນອອກໄດ້"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ຖ່າຍຮູບ"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"ເລືອກຮູບ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ເລືອກຮູບ"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"ພະຍາຍາມປົດລັອກບໍ່ສຳເລັດຫຼາຍເທື່ອເກີນໄປ. ຂໍ້ມູນຂອງອຸປະກອນນີ້ຈະຖືກລຶບອອກ."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"ພະຍາຍາມປົດລັອກບໍ່ສຳເລັດຫຼາຍເທື່ອເກີນໄປ. ຜູ້ໃຊ້ນີ້ຈະຖືກລຶບຂໍ້ມູນອອກ."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ອີ​ເທີ​ເນັດ​ຕັດ​ເຊື່ອມ​ຕໍ່​ແລ້ວ."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ອີເທີເນັດ."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"ບໍ່ສາມາດໂທສຽງໄດ້."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"ເລືອກຮູບໂປຣໄຟລ໌"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"ໄອຄອນຜູ້ໃຊ້ເລີ່ມຕົ້ນ"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"ແປ້ນພິມພາຍນອກ"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"ເລືອກຮູບແບບແປ້ນພິມ"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ຄ່າເລີ່ມຕົ້ນ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 21cd1d8..10ef2c4 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -106,7 +106,29 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktyvus, tik kairysis"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktyvus, tik dešinysis"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktyvus, kairysis ir dešinysis"</string>
-    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Laikmenos garsas"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
+    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Medijos garsas"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefono skambučiai"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Failo perkėlimas"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Įvesties įrenginys"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Manoma, kad programos palaiko modernius formatus"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Rodyti perkodavimo pranešimus"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Išjungti talpyklos perkodavimą"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"„Widevine“ nustatymai"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Priverstinai naudoti L3 kaip atsarginį variantą"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Pasirinkite, kad priverstinai naudoti L3 kaip atsarginį variantą"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Vykdomos paslaugos"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Žiūrėti ir valdyti dabar vykdomas paslaugas"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"„WebView“ diegimas"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Išėjus iš režimo visa veikla bus ištrinta"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Išeidami galite išsaugoti arba ištrinti savo veiklą"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Nustatykite iš naujo, jei norite ištrinti sesijos veiklą dabar, arba galite išeidami išsaugoti ar ištrinti veiklą"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Fotografuoti"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Pasirinkti vaizdą"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Pasirinkti nuotrauką"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Per daug netinkamų bandymų. Šio įrenginio duomenys bus ištrinti."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Per daug netinkamų bandymų. Šis naudotojas bus ištrintas."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Atsijungta nuo eterneto."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Eternetas."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Nekviečiama."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Pasirinkite profilio nuotrauką"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Numatytojo naudotojo piktograma"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fizinė klaviatūra"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Klaviatūros išdėstymo pasirinkimas"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Numatytasis"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index bcaaf2c..c52e9dd 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -106,12 +106,34 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ierīce aktīva, tikai kreisā auss"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ierīce aktīva, tikai labā auss"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ierīces aktīvas, kreisā un labā auss"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Multivides audio"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Tālruņa zvani"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Failu pārsūtīšana"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Ievades ierīce"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Piekļuve internetam"</string>
-    <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Atļaujiet piekļuvi kontaktpersonām un vēsturei."</string>
+    <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Atļaut piekļuvi kontaktpersonām un vēsturei"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Informācija tiks izmantota paziņojumiem par zvaniem u.c."</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Interneta savienojuma koplietošana"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Īsziņas"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Pieņemt, ka lietotnēs tiek atbalstīti moderni formāti"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Rādīt paziņojumus par pārkodēšanu"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Atspējot saglabāšanu kešatmiņā pārkodēšanai"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine iestatījumi"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Aktivizēt L3 atkāpšanos"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Atlasiet, lai aktivizētu L3 atkāpšanos"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Aktīvie pakalpojumi"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Pašreiz darbojošos pakalpojumu skatīšana un vadība"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ieviešana"</string>
@@ -630,7 +649,7 @@
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Noņemt"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Notiek viesa sesijas atiestatīšana…"</string>
     <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Vai atiestatīt viesa sesiju?"</string>
-    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Tādējādi tiks sākta jauna viesa sesijas un visas pašreizējās sesijas lietotnes un dati tiks dzēsti"</string>
+    <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Tādējādi tiks sākta jauna viesa sesija un visas pašreizējās sesijas lietotnes un dati tiks dzēsti"</string>
     <string name="guest_exit_dialog_title" msgid="1846494656849381804">"Vai iziet no viesa režīma?"</string>
     <string name="guest_exit_dialog_message" msgid="1743218864242719783">"Tādējādi tiks dzēstas pašreizējās viesa sesijas lietotnes un dati."</string>
     <string name="grant_admin" msgid="4323199171790522574">"Jā, iestatīt kā administratoru"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Izejot tiks dzēstas visas darbības"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Izejot varat saglabāt vai dzēst savas darbības"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Atiestatiet, lai tagad dzēstu sesijas darbības. Izejot varēsiet saglabāt vai dzēst darbības."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Uzņemt fotoattēlu"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Izvēlēties attēlu"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Atlasīt fotoattēlu"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Pārāk daudz nesekmīgu mēģinājumu. Dati šajā ierīcē tiks dzēsti."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Pārāk daudz nesekmīgu mēģinājumu. Šis lietotājs tiks dzēsts."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Pārtraukts savienojums ar tīklu Ethernet."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Tīkls Ethernet"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Zvanīšana nav pieejama."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Profila attēla izvēle"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Noklusējuma lietotāja ikona"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fiziskā tastatūra"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Tastatūras izkārtojuma izvēle"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Noklusējums"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index 4dc6be0..554b92e 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Активно, само лево"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Активно, само десно"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Активно, лево и десно"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Звук на аудио/видео"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Телефонски повици"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Пренос на датотека"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Претпостави дека апликациите поддржуваат модерни формати"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Прикажувај известувања за транскодирање"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Оневозможи го кешот на транскодирањето"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Поставки за Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Наметни алтернативно безбедносно ниво L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Изберете за да се наметне алтернативно безбедносно ниво L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Активни услуги"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Погледнете и контролирајте услуги што се моментално активни"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Примена на WebView"</string>
@@ -498,9 +517,9 @@
     <string name="install_other_apps" msgid="3232595082023199454">"Непознати апликации"</string>
     <string name="home" msgid="973834627243661438">"Почетна страница за поставки"</string>
   <string-array name="battery_labels">
-    <item msgid="7878690469765357158">"0%"</item>
-    <item msgid="8894873528875953317">"50%"</item>
-    <item msgid="7529124349186240216">"100%"</item>
+    <item msgid="7878690469765357158">"0 %"</item>
+    <item msgid="8894873528875953317">"50 %"</item>
+    <item msgid="7529124349186240216">"100 %"</item>
   </string-array>
     <string name="charge_length_format" msgid="6941645744588690932">"Пред <xliff:g id="ID_1">%1$s</xliff:g>"</string>
     <string name="remaining_length_format" msgid="4310625772926171089">"Преостануваат <xliff:g id="ID_1">%1$s</xliff:g>"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Целата активност ќе се избрише при излегувањето"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Може да ја зачувате или избришете вашата активност при излегувањето"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Ресетирајте за да ја избришете активноста на сесијата сега или може да ја зачувате или избришете активноста при излегувањето"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Фотографирајте"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Одберете слика"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Изберете фотографија"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Премногу неточни обиди. Податоците на уредов ќе се избришат."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Премногу погрешни обиди. Корисников ќе се избрише."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Етернетот е исклучен."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Етернет."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Без повици."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Изберете профилна слика"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Икона за стандарден корисник"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Физичка тастатура"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Избери распоред на тастатура"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Стандардно"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index f92f7b0..61bcc44 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"സജീവമാണ്, ഇടത്തേത് മാത്രം"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"സജീവമാണ്, വലത്തേത് മാത്രം"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"സജീവമാണ്, ഇടത്തേതും വലത്തേതും"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"മീഡിയ ഓഡിയോ"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"ഫോണ്‍‌ കോളുകൾ"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ഫയൽ കൈമാറൽ"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"ആപ്പുകൾ ആധുനിക ഫോർമാറ്റുകളെ പിന്തുണയ്ക്കുമെന്ന് കരുതുക"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ട്രാൻസ്കോഡ് ചെയ്യൽ അറിയിപ്പുകൾ കാണിക്കുക"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ട്രാൻസ്കോഡ് ചെയ്യൽ കാഷെ പ്രവർത്തനരഹിതമാക്കുക"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"വൈഡ്‌ലൈൻ ക്രമീകരണം"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 ഫോൾബാക്ക് ഫോഴ്‌സ് ചെയ്യുക"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 ഫോൾബാക്ക് ഫോഴ്‌സ് ചെയ്യാൻ തിരഞ്ഞെടുക്കുക"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"പ്രവർത്തിക്കുന്ന സേവനങ്ങൾ"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"നിലവിൽ പ്രവർത്തിക്കുന്ന സേവനങ്ങൾ കാണുക, നിയന്ത്രിക്കുക"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView നടപ്പാക്കൽ"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"പുറത്തുകടക്കുമ്പോൾ എല്ലാ ആക്‌റ്റിവിറ്റിയും ഇല്ലാതാക്കും"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"പുറത്തുകടക്കുമ്പോൾ ആക്‌റ്റിവിറ്റി സംരക്ഷിക്കുകയോ ഇല്ലാതാക്കുകയോ ചെയ്യാം"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"സെഷൻ ആക്‌റ്റിവിറ്റി ഇപ്പോൾ ഇല്ലാതാക്കാൻ റീസെറ്റ് ചെയ്യുക അല്ലെങ്കിൽ പുറത്തുകടക്കുമ്പോൾ ആക്‌റ്റിവിറ്റി സംരക്ഷിക്കുകയോ ഇല്ലാതാക്കുകയോ ചെയ്യാം"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ഒരു ഫോട്ടോ എടുക്കുക"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"ഒരു ചിത്രം തിരഞ്ഞെടുക്കുക"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ഫോട്ടോ തിരഞ്ഞെടുക്കുക"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"ഒരുപാട് തെറ്റായ ശ്രമങ്ങൾ. ഈ ഉപകരണത്തിലെ ഡാറ്റ ഇല്ലാതാക്കപ്പെടും."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"ഒരുപാട് തെറ്റായ ശ്രമങ്ങൾ. ഈ ഉപയോക്താവ് ഇല്ലാതാക്കപ്പെടും."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ഇതർനെറ്റ് വിച്ഛേദിച്ചു."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ഇതർനെറ്റ്."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"വോയ്‌സ് കോൾ ലഭ്യമല്ല."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"പ്രൊഫൈൽ ചിത്രം തിരഞ്ഞെടുക്കുക"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"ഡിഫോൾട്ട് ഉപയോക്തൃ ഐക്കൺ"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"ഫിസിക്കൽ കീബോർഡ്"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"കീബോർഡ് ലേഔട്ട് തിരഞ്ഞെടുക്കുക"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ഡിഫോൾട്ട്"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index 237f6a7..c2c22e6 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Идэвхтэй, зөвхөн зүүн тал"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Идэвхтэй, зөвхөн баруун тал"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Идэвхтэй, зүүн болон баруун тал"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Медиа аудио"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Утасны дуудлага"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Файл дамжуулалт"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Аппыг орчин үеийн форматыг дэмждэг гэж үздэг"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Хөрвүүлгийн мэдэгдэл харуулах"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Хөрвүүлгийн завсрын санах ойг идэвхгүй болгох"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine-н тохиргоо"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 нөөцийг хүчлэх"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 нөөцийг хүчлэхийг сонгоно уу"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Ажиллаж байгаа үйлчилгээнүүд"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Одоо ажиллаж байгаа үйлчилгээнүүдийг харах болон хянах"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView хэрэгжилт"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Бүх үйл ажиллагааг гарах үед устгана"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Та гарахдаа үйл ажиллагаагаа хадгалах эсвэл устгах боломжтой"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Харилцан үйлдлийн үйл ажиллагааг одоо устгахын тулд шинэчлэх эсвэл та гарахдаа үйл ажиллагааг хадгалах, устгах боломжтой"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Зураг авах"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Зураг сонгох"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Зураг сонгох"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Түгжээг хэт олон удаа буруу оруулсан тул энэ төхөөрөмжийн өгөгдлийг устгах болно."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Түгжээг хэт олон удаа буруу оруулсан тул энэ хэрэглэгчийг устгах болно."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet саллаа."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Этернэт."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Дуудлага байхгүй."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Профайл зураг сонгох"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Өгөгдмөл хэрэглэгчийн дүрс тэмдэг"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Биет гар"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Гарын бүдүүвчийг сонгох"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Өгөгдмөл"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 9edfd53..1e56118 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"फक्त डावे अ‍ॅक्टिव्ह आहे"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"फक्त उजवे अ‍ॅक्टिव्ह आहे"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"डावे आणि उजवे अ‍ॅक्टिव्ह आहे"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"मीडिया ऑडिओ"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"फोन कॉल"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"फाइल स्थानांतरण"</string>
@@ -264,7 +286,7 @@
     <string name="bugreport_in_power" msgid="8664089072534638709">"बग रिपोर्ट शॉर्टकट"</string>
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"बग रिपोर्ट घेण्यासाठी पॉवर मेनूमध्ये एक बटण दर्शवा"</string>
     <string name="keep_screen_on" msgid="1187161672348797558">"सक्रिय रहा"</string>
-    <string name="keep_screen_on_summary" msgid="1510731514101925829">"चार्ज होत असताना स्क्रीन कधीही निष्क्रिय होणार नाही"</string>
+    <string name="keep_screen_on_summary" msgid="1510731514101925829">"चार्ज होत असताना स्क्रीन कधीही स्लीप मोडवर जाणार नाही"</string>
     <string name="bt_hci_snoop_log" msgid="7291287955649081448">"ब्लूटूथ HCI स्नूप लॉग सुरू करा"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"ब्लूटूथ पॅकेट कॅप्चर करा (हे सेटिंग बदलल्यानंतर ब्ल्यूटूथ टॉगल करा)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"OEM अनलॉक करणे"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"असे गृहीत धरा की, ॲप्स आधुनिक फॉरमॅटना सपोर्ट करतात"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ट्रान्सकोडिंग सूचना दाखवा"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ट्रान्सकोडिंग कॅशे बंद करा"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine सेटिंग्ज"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 फॉलबॅकची सक्ती करा"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 फॉलबॅकची सक्ती करण्यासाठी निवडा"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"सुरू सेवा"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"सध्या सुरू असलेल्या सेवा पहा आणि नियंत्रित करा"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"वेबदृश्य अंमलबजावणी"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"बाहेर पडल्यावर सर्व अ‍ॅक्टिव्हिटी हटवली जाईल"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"बाहेर पडल्यावर तुमची अ‍ॅक्टिव्हिटी सेव्ह करू किंवा हटवू शकता"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"सत्र अ‍ॅक्टिव्हिटी आता हटवण्यासाठी रीसेट करा किंवा तुम्ही बाहेर पडल्यावर अ‍ॅक्टिव्हिटी सेव्ह करू अथवा हटवू शकता"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"फोटो काढा"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"इमेज निवडा"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"फोटो निवडा"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"बरेच चुकीचे प्रयत्‍न. या डिव्‍हाइसचा डेटा हटवला जाईल."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"बरेच चुकीचे प्रयत्‍न. हा वापरकर्ता हटवला जाईल."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"इथरनेट डिस्कनेक्ट केले."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"इथरनेट."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"कॉलिंग उपलब्ध नाही."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"प्रोफाइल फोटो निवडा"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"डीफॉल्ट वापरकर्ता आयकन"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"वास्तविक कीबोर्ड"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"किबोर्ड लेआउट निवडा"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"डीफॉल्ट"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index c21c39a..a93c459 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktif, kiri sahaja"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktif, kanan sahaja"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktif, kiri dan kanan"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Audio media"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Panggilan telefon"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Pemindahan fail"</string>
@@ -264,7 +286,7 @@
     <string name="bugreport_in_power" msgid="8664089072534638709">"Pintasan laporan pepijat"</string>
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Tunjukkan butang dalam menu kuasa untuk mengambil laporan pepijat"</string>
     <string name="keep_screen_on" msgid="1187161672348797558">"Tetap berjaga"</string>
-    <string name="keep_screen_on_summary" msgid="1510731514101925829">"Skrin tidak sekali-kali akan tidur semasa pengecasan"</string>
+    <string name="keep_screen_on_summary" msgid="1510731514101925829">"Skrin tidak akan tidur semasa pengecasan"</string>
     <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Dayakan log intip HCI Bluetooth"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Tangkap paket Bluetooth. (Togol Bluetooth selepas menukar tetapan ini)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"Pembukaan kunci OEM"</string>
@@ -304,8 +326,8 @@
     <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"Pilih Mod DNS Peribadi"</string>
     <string name="private_dns_mode_off" msgid="7065962499349997041">"Mati"</string>
     <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Automatik"</string>
-    <string name="private_dns_mode_provider" msgid="3619040641762557028">"Nama hos pembekal DNS peribadi"</string>
-    <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Masukkan nama hos pembekal DNS"</string>
+    <string name="private_dns_mode_provider" msgid="3619040641762557028">"Nama hos penyedia DNS peribadi"</string>
+    <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Masukkan nama hos penyedia DNS"</string>
     <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Tidak dapat menyambung"</string>
     <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Tunjukkan pilihan untuk pensijilan paparan wayarles"</string>
     <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Tingkatkan tahap pengelogan Wi-Fi, tunjuk setiap SSID RSSI dalam Pemilih Wi-Fi"</string>
@@ -410,8 +432,8 @@
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Bolehkan semua saiz aktiviti diubah untuk berbilang tetingkap, tanpa mengambil kira nilai manifes."</string>
     <string name="enable_freeform_support" msgid="7599125687603914253">"Dayakan tetingkap bentuk bebas"</string>
     <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Dayakan sokongan untuk tetingkap bentuk bebas percubaan."</string>
-    <string name="local_backup_password_title" msgid="4631017948933578709">"Kata laluan sandaran komputer meja"</string>
-    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Sandaran penuh komputer meja tidak dilindungi pada masa ini"</string>
+    <string name="local_backup_password_title" msgid="4631017948933578709">"Kata laluan sandaran desktop"</string>
+    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Sandaran penuh desktop tidak dilindungi pada masa ini"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Ketik untuk menukar atau mengalih keluar kata laluan untuk sandaran penuh desktop"</string>
     <string name="local_backup_password_toast_success" msgid="4891666204428091604">"Kata laluan sandaran baharu telah ditetapkan"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"Kata laluan baharu dan pengesahan tidak sepadan"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Mengambil alih sokongan apl format moden"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Tunjukkan pemberitahuan transpengekodan"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Lumpuhkan cache transpengekodan"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Tetapan Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Paksa sandaran L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Pilih untuk memaksa sandaran L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Perkhidmatan dijalankan"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Lihat dan kawal perkhidmatan yang sedang dijalankan"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Pelaksanaan WebView"</string>
@@ -481,7 +500,7 @@
     <string name="power_charging_future_paused" msgid="1809543660923642799">"<xliff:g id="LEVEL">%1$s</xliff:g> - Mengecas"</string>
     <string name="battery_info_status_unknown" msgid="268625384868401114">"Tidak diketahui"</string>
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Mengecas"</string>
-    <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mengecas dgn cepat"</string>
+    <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Mengecas pantas"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Mengecas perlahan"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Mengecas tanpa wayar"</string>
     <string name="battery_info_status_charging_dock" msgid="8573274094093364791">"Pengecasan"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Semua aktiviti akan dipadamkan semasa keluar"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Aktiviti anda boleh disimpan atau dipadam semasa keluar"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Tetapkan semula sesi untuk memadamkan aktiviti sesi sekarang atau anda boleh menyimpan atau memadamkan aktiviti semasa keluar"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Ambil foto"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Pilih imej"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Pilih foto"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Terlalu banyak percubaan yang salah. Data peranti ini akan dipadamkan."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Terlalu banyak percubaan yang salah. Pengguna ini akan dipadamkan."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet diputuskan sambungan."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Tiada panggilan."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Pilih gambar profil"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Ikon pengguna lalai"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Papan kekunci fizikal"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Pilih susun atur papan kekunci"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Lalai"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index 5943d78..7880c37 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"ဖွင့်ထားသည်၊ ဘယ်သီးသန့်"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"ဖွင့်ထားသည်၊ ညာသီးသန့်"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"ဖွင့်ထားသည်၊ ဘယ်နှင့် ညာ"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"မီဒီယာ အသံ"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"ဖုန်းခေါ်ဆိုမှုများ"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ဖိုင်လွဲပြောင်းခြင်း"</string>
@@ -389,7 +411,7 @@
     <string name="show_non_rect_clip" msgid="7499758654867881817">"စတုဂံပုံမကျသော ဖြတ်ပိုင်း လုပ်ဆောင်ချက်များကို အမှားဖယ်ရှားရန်"</string>
     <string name="track_frame_time" msgid="522674651937771106">"HWUI ပရိုဖိုင် ဆောင်ရွက်ခြင်း"</string>
     <string name="enable_gpu_debug_layers" msgid="4986675516188740397">"GPU အမှားရှာအလွှာဖွင့်ရန်"</string>
-    <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"အမှားရှာအက်ပ်များအတွက် GPU အမှားရှာအလွှာများ ထည့်သွင်းခွင့်ပြုပါ"</string>
+    <string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"အမှားရှာအက်ပ်များအတွက် GPU အမှားရှာအလွှာများ ဖွင့်ခွင့်ပြုသည်"</string>
     <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"အကျယ်ရှင်းလင်းချက်ပံ့ပိုးသူ မှတ်တမ်းဖွင့်ရန်"</string>
     <string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"ချွတ်ယွင်းမှု အစီရင်ခံချက်တွင် စက်ပစ္စည်းအလိုက် ထုတ်လုပ်သူမှတ်တမ်းများကို ထည့်သွင်းခြင်းဖြင့် ကိုယ်ရေးကိုယ်တာ အချက်အလက်များ ပါဝင်ခြင်း၊ ဘက်ထရီပိုသုံးခြင်း နှင့်/သို့မဟုတ် သိုလှောင်ခန်းပိုသုံးခြင်းတို့ ဖြစ်စေနိုင်သည်။"</string>
     <string name="window_animation_scale_title" msgid="5236381298376812508">"လှုပ်ရှားသက်ဝင်ပုံစကေး"</string>
@@ -411,7 +433,7 @@
     <string name="enable_freeform_support" msgid="7599125687603914253">"ပုံစံမျိုးစုံ ဝင်းဒိုးများ ဖွင့်ရန်"</string>
     <string name="enable_freeform_support_summary" msgid="1822862728719276331">"ပုံစံမျိုးစုံဝင်းဒိုးများ စမ်းသပ်ခြင်းအတွက် ပံ့ပိုးမှုကို ဖွင့်သည်"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"ဒက်စ်တော့ အရန်စကားဝှက်"</string>
-    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ဒက်စ်တော့ အရန်သိမ်းဆည်းခြင်းအားလုံးကို လောလောဆယ် ကာကွယ်မထားပါ"</string>
+    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"ဒက်စ်တော့ တစ်ခုလုံး အရန်သိမ်းဆည်းခြင်းကို လက်ရှိတွင် ကာကွယ်မထားပါ"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"ဒက်စ်တော့ အပြည့်အဝ အရန်သိမ်းခြင်းအတွက် စကားဝှက်ကို ပြောင်းရန် သို့မဟုတ် ဖယ်ရှားရန် တို့ပါ။"</string>
     <string name="local_backup_password_toast_success" msgid="4891666204428091604">"အရန်သိမ်းဆည်းခြင်းအတွက် စကားဝှက်အသစ်ကို သတ်မှတ်ပြီးပြီ။"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"စကားဝှက်အသစ်နှင့် အတည်ပြုချက် ကွဲလွဲနေသည်။"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"ဤအက်ပ်များက ဖော်မက်အသစ်များကို ပံ့ပိုးသည်"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"အမျိုးအစားပြောင်းခြင်း အကြောင်းကြားချက်များကို ပြရန်"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"အမျိူးအစားပြောင်းခြင်း ကက်ရှ်ကို ပိတ်ရန်"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine ဆက်တင်များ"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 နောက်ပြန်ဆုတ်မှု မဖြစ်မနေလုပ်ခြင်း"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 နောက်ပြန်ဆုတ်မှု မဖြစ်မနေလုပ်ရန် ရွေးပါ"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"အလုပ်လုပ်နေသောဝန်ဆောင်မှုများ"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"လက်ရှိ ဝန်ဆောင်မှုများကို ကြည့်ရှု ထိန်းသိမ်းသည်"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView အကောင်အထည်ဖော်မှု"</string>
@@ -491,7 +510,7 @@
     <string name="battery_info_status_full_charged" msgid="3536054261505567948">"အားအပြည့်သွင်းထားသည်"</string>
     <string name="battery_info_status_charging_on_hold" msgid="6364355145521694438">"အားသွင်းခြင်းကို ခဏရပ်ထားသည်"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"စီမံခန့်ခွဲသူမှ ထိန်းချုပ်ပါသည်"</string>
-    <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ကန့်သတ်ထားသော ဆက်တင်များဖြင့် ထိန်းချုပ်ထားသည်"</string>
+    <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ကန့်သတ်ဆက်တင်ဖြင့် ထိန်းချုပ်ထားသည်"</string>
     <string name="disabled" msgid="8017887509554714950">"ပိတ်ထားပြီး"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ခွင့်ပြုထားသည်"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ခွင့်မပြုပါ"</string>
@@ -597,7 +616,7 @@
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"ကန့်သတ်ထားသော ကိုယ်ရေးအချက်အလက်များ"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"အသုံးပြုသူအသစ် ထည့်မလား။"</string>
     <string name="user_add_user_message_long" msgid="1527434966294733380">"နောက်ထပ် အသုံးပြုသူများ ထည့်သွင်းခြင်းဖြင့် ဤစက်ပစ္စည်းကို အခြားသူများနှင့် မျှဝေအသုံးပြုနိုင်သည်။ အသုံးပြုသူတိုင်းသည် မိမိတို့ကိုယ်ပိုင်နေရာ ရရှိမည်ဖြစ်ပြီး အက်ပ်၊ နောက်ခံပုံနှင့် အခြားအရာတို့ဖြင့် စိတ်ကြိုက်ပြင်ဆင်နိုင်ပါမည်။ အားလုံးကို အကျိုးသက်ရောက်မှု ရှိစေနိုင်သည့် Wi-Fi ကဲ့သို့ ဆက်တင်များကိုလည်း ချိန်ညှိနိုင်ပါမည်။\n\nအသုံးပြုသူအသစ် ထည့်သည့်အခါ ထိုသူသည် မိမိ၏ကိုယ်ပိုင်နေရာကို သတ်မှတ်ရပါမည်။\n\nအသုံးပြုသူ မည်သူမဆို အခြားအသုံးပြုသူများအတွက် အက်ပ်များကို အပ်ဒိတ်လုပ်နိုင်သည်။ အများသုံးစွဲနိုင်မှုဆက်တင်များနှင့် ဝန်ဆောင်မှုများကို အသုံးပြုသူအသစ်ထံသို့ လွှဲပြောင်းပေးမည် မဟုတ်ပါ။"</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"သင်က အသုံးပြုသူအသစ် ထည့်လိုက်လျှင် ထိုသူသည် ၎င်း၏ နေရာကို သတ်မှတ်စီစဉ်ရပါမည်။\n\n အသုံးပြုသူတိုင်းက ကျန်အသုံးပြုသူ အားလုံးအတွက် အက်ပ်များကို အပ်ဒိတ်လုပ်နိုင်သည်။"</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"သင်ထည့်လိုက်သည့် အသုံးပြုသူအသစ်သည် ၎င်း၏ နေရာကို သတ်မှတ်စီစဉ်ရပါမည်။\n\n အသုံးပြုသူတိုင်းက ကျန်အသုံးပြုသူ အားလုံးအတွက် အက်ပ်များကို အပ်ဒိတ်လုပ်နိုင်သည်။"</string>
     <string name="user_grant_admin_title" msgid="5157031020083343984">"ဤအသုံးပြုသူကို စီမံခန့်ခွဲသူအဖြစ် သတ်မှတ်မလား။"</string>
     <string name="user_grant_admin_message" msgid="1673791931033486709">"စီမံခန့်ခွဲသူများ၌ အခြားအသုံးပြုသူများတွင်မရှိသော အထူးဆောင်ရွက်ခွင့်များရှိသည်။ စီမံခန့်ခွဲသူက အသုံးပြုသူအားလုံးကို စီမံခြင်း၊ ဤစက်ပစ္စည်းကို အပ်ဒိတ်လုပ်ခြင်း (သို့) ပြင်ဆင်သတ်မှတ်ခြင်း၊ ဆက်တင်များပြင်ဆင်ခြင်း၊ ထည့်သွင်းထားသောအက်ပ်အားလုံးကို ကြည့်ခြင်းနှင့် အခြားသူများအတွက် စီမံခန့်ခွဲသူ ဆောင်ရွက်ခွင့်များပေးခြင်း (သို့) ရုပ်သိမ်းခြင်းတို့ လုပ်နိုင်သည်။"</string>
     <string name="user_grant_admin_button" msgid="5441486731331725756">"စီမံခန့်ခွဲသူအဖြစ် သတ်မှတ်ရန်"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ထွက်သည့်အခါ လုပ်ဆောင်ချက်အားလုံးကို ဖျက်လိုက်မည်"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ထွက်သည့်အခါ လုပ်ဆောင်ချက်ကို သိမ်းနိုင် (သို့) ဖျက်နိုင်သည်"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"စက်ရှင်လုပ်ဆောင်ချက်ကို ယခုဖျက်ရန် ပြင်ဆင်သတ်မှတ်နိုင်သည် (သို့) ထွက်သည့်အခါ သိမ်းနိုင်၊ ဖျက်နိုင်သည်"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ဓာတ်ပုံရိုက်ရန်"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"ပုံရွေးရန်"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ဓာတ်ပုံရွေးရန်"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"မှားယွင်းသည့် အကြိမ်ရေ အလွန်များနေပါပြီ။ ဤစက်၏ ဒေတာကို ဖျက်လိုက်ပါမည်။"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"မှားယွင်းသည့် အကြိမ်ရေ အလွန်များနေပါပြီ။ ဤအသုံးပြုသူကို ဖျက်လိုက်ပါမည်။"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet နှင့်ချိတ်ဆက်မှုပြတ်တောက်"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"အီသာနက်။"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"ခေါ်ဆိုမှု မရှိပါ။"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"ပရိုဖိုင်ပုံ ရွေးပါ"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"မူရင်းအသုံးပြုသူ သင်္ကေတ"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"ပကတိ ကီးဘုတ်"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"လက်ကွက်အပြင်အဆင်ရွေးချယ်ခြင်း"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"မူရင်း"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 338623e..0eacc5e 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, bare venstre"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, bare høyre"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, venstre og høyre"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Medielyd"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonsamtaler"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Filoverføring"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Anta at apper støtter moderne formater"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Vis omkodingsvarsler"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Slå av omkodingsbuffer"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine-innstillinger"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Tving bruk av L3-reservealternativet"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Velg for å tvinge bruk av L3-reservealternativet"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Aktive tjenester"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Se og kontroller tjenester som kjører"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementering"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All aktivitet slettes når du avslutter"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Du kan lagre eller slette aktiviteten når du avslutter"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Tilbakestill for å slette øktaktivitet nå, eller du kan lagre eller slette aktivitet når du avslutter"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Ta et bilde"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Velg et bilde"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Velg et bilde"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"For mange mislykkede forsøk. Dataene på denne enheten blir slettet."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"For mange mislykkede forsøk. Denne brukeren blir slettet."</string>
@@ -657,7 +674,7 @@
     <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Slått av"</string>
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Slått på"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Enheten din må startes på nytt for at denne endringen skal tre i kraft. Start på nytt nå eller avbryt."</string>
-    <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Hodetelefoner med kabel"</string>
+    <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"hodetelefoner med kabel"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"På"</string>
     <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Av"</string>
     <string name="carrier_network_change_mode" msgid="4257621815706644026">"Bytting av operatørnettverk"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet er frakoblet."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Ingen ringing."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Velg et profilbilde"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Standard brukerikon"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fysisk tastatur"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Velg et tastaturoppsett"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Standard"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index c06e649..e2236cc 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"बायाँ मात्र अन छ"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"सक्रिय, दायाँ मात्र"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"सक्रिय, बायाँ र दायाँ"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"मिडिया अडियो"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"फोन कलहरू"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"फाइल स्थानान्तरण"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"एपहरूमा आधुनिक फर्म्याट प्रयोग गर्न मिल्छ भनी मान्नुहोस्"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ट्रान्सकोडिङसम्बन्धी सूचना देखाइयोस्"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ट्रान्सकोडिङको क्यास अफ गर्नुहोस्"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine को सेटिङ"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 फलब्याक बलपूर्वक अन गर्नुहोस्"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 फलब्याकमा बलपूर्वक अन गर्ने कि नगर्ने भन्ने विकल्प चयन गर्नुहोस्"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"चलिरहेका सेवाहरू"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"हाल चालु भइरहेका सेवाहरू हेर्नुहोस् र नियन्त्रण गर्नुहोस्"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView कार्यान्वयन"</string>
@@ -518,7 +537,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"सिष्टममा भएका भाषा प्रयोग गरियोस्"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"<xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>का लागि सेटिङहरू खोल्न विफल भयो।"</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"यस इनपुट विधिले तपाईँले टाइप गर्नुहुने सम्पूर्ण पाठ बटु्ल्न सक्छ, व्यक्तिगत डेटा जस्तै पासवर्ड र क्रेडिट कार्ड नम्बर लगायतका। यो <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> अनुप्रयोगबाट आउँदछ। यो इनपुट विधि प्रयोग गर्ने हो?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"टिपोट: पुनःबुट पछि तपाईँले आफ्नो फोनलाई अनलक नगरेसम्म यो एप सुरु हुन सक्दैन"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"नोट: रिबुट गरेपछि तपाईंले आफ्नो फोन अनलक नगरेसम्म यो एप सुरु हुँदैन"</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"IMS दर्ताको स्थिति"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"दर्ता गरिएको"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"दर्ता नगरिएको"</string>
@@ -609,7 +628,7 @@
     <string name="user_add_user_type_title" msgid="551279664052914497">"थप्नुहोस्"</string>
     <string name="user_new_user_name" msgid="60979820612818840">"नयाँ प्रयोगकर्ता"</string>
     <string name="user_new_profile_name" msgid="2405500423304678841">"नयाँ प्रोफाइल"</string>
-    <string name="user_info_settings_title" msgid="6351390762733279907">"प्रयोगकर्ता जानकारी"</string>
+    <string name="user_info_settings_title" msgid="6351390762733279907">"प्रयोगकर्ताको विवरण"</string>
     <string name="profile_info_settings_title" msgid="105699672534365099">"प्रोफाइलको जानकारी"</string>
     <string name="user_need_lock_message" msgid="4311424336209509301">"निषेधयुक्त प्रोफाइल बनाउनु अघि तपाईँको एप र व्यक्तिगत डेटा सुरक्षा गर्नाका लागि तपाईँले स्क्रिन लक सेटअप गर्नु पर्दछ ।"</string>
     <string name="user_set_lock_button" msgid="1427128184982594856">"लक सेट गर्नुहोस्"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"अतिथि मोडबाट बाहिरिँदा सबै क्रियाकलाप मेटाइने छ"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"तपाईं अतिथि मोडबाट बाहिरिँदा आफ्ना क्रियाकलाप सेभ गर्ने वा मेटाउने विकल्प रोज्न सक्नुहुन्छ"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"यो सत्रमा गरिएका क्रियाकलाप अहिले नै मेटाउन रिसेट गर्नुहोस्, अथवा तपाईं अतिथि मोडबाट बाहिरिँदा आफ्ना क्रियाकलाप सेभ गर्ने वा मेटाउने विकल्प रोज्न सक्नुहुन्छ"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"फोटो खिच्नुहोस्"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"कुनै फोटो छनौट गर्नुहोस्"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"फोटो चयन गर्नुहोस्"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"धेरै पटक गलत तरिकाले अनलक गर्ने प्रयास गरियो। यो डिभाइसमा भएको डेटा मेटाइने छ।"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"धेरै पटक गलत तरिकाले अनलक गर्ने प्रयास गरियो। यो प्रयोगकर्ता मेटाइने छ।"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"इथरनेट विच्छेद भयो।"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"इथरनेट।"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"कल गर्ने सुविधा उपलब्ध छैन।"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"प्रोफाइल फोटो छान्नुहोस्"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"प्रयोगकर्ताको डिफल्ट आइकन"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"भौतिक किबोर्ड"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"किबोर्ड लेआउट छान्नुहोस्"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"डिफल्ट"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index b405903..801c73f 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Actief, alleen links"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Actief, alleen rechts"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Actief, links en rechts"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Media-audio"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefoongesprekken"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Bestandsoverdracht"</string>
@@ -115,7 +137,7 @@
     <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"De informatie wordt onder andere gebruikt voor gespreksaankondigingen"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Internetverbinding delen"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Sms-berichten"</string>
-    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Sim-toegang"</string>
+    <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Simtoegang"</string>
     <string name="bluetooth_profile_a2dp_high_quality" msgid="4739440941324792775">"HD-audio: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
     <string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="2477639096903834374">"HD-audio"</string>
     <string name="bluetooth_profile_hearing_aid" msgid="2607867572569689732">"Hoortoestellen"</string>
@@ -133,7 +155,7 @@
     <string name="bluetooth_pan_nap_profile_summary_connected" msgid="3744773111299503493">"Lokale internetverbinding delen met apparaat"</string>
     <string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"Gebruik voor internettoegang"</string>
     <string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"Gebruiken voor kaart"</string>
-    <string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"Gebruiken voor sim-toegang"</string>
+    <string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"Gebruiken voor simtoegang"</string>
     <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Gebruiken voor audio van medium"</string>
     <string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"Gebruiken voor audio van telefoon"</string>
     <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Gebruiken voor bestandsoverdracht"</string>
@@ -305,7 +327,7 @@
     <string name="private_dns_mode_off" msgid="7065962499349997041">"Uit"</string>
     <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Automatisch"</string>
     <string name="private_dns_mode_provider" msgid="3619040641762557028">"Hostnaam van privé-DNS-provider"</string>
-    <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Geef hostnaam van DNS-provider op"</string>
+    <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Voer de hostnaam van de DNS-provider in"</string>
     <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Kan geen verbinding maken"</string>
     <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Toon opties voor certificering van draadloze weergave"</string>
     <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Verhoog het logniveau voor wifi, toon per SSID RSSI in wifi-kiezer"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Aannemen dat apps moderne indelingen ondersteunen"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Transcoderingsmeldingen tonen"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Transcodering van cache uitzetten"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine-instellingen"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3-fallback afdwingen"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Selecteren om L3-fallback af te dwingen"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Actieve services"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Bekijk en beheer services die momenteel actief zijn"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementatie"</string>
@@ -518,7 +537,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Gebruik systeemtalen"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Instellingen openen voor <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g> mislukt"</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"Deze invoermethode verzamelt mogelijk alle tekst die je typt, inclusief persoonsgegevens zoals wachtwoorden en creditcardnummers. De methode is afkomstig uit de app <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Deze invoermethode aanzetten?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Opmerking: Wanneer je telefoon opnieuw is opgestart, kan deze app pas worden gestart nadat je je telefoon hebt ontgrendeld"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Opmerking: Nadat je de telefoon opnieuw opstart, wordt deze app pas gestart nadat je de telefoon ontgrendelt"</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"IMS-registratiestatus"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"Geregistreerd"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Niet geregistreerd"</string>
@@ -596,7 +615,7 @@
     <string name="user_add_user_item_title" msgid="2394272381086965029">"Gebruiker"</string>
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"Beperkt profiel"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"Nieuwe gebruiker toevoegen?"</string>
-    <string name="user_add_user_message_long" msgid="1527434966294733380">"Je kunt dit apparaat met anderen delen door extra gebruikers toe te voegen. Elke gebruiker heeft een eigen profiel met zelf gekozen apps, achtergrond, enzovoort. Gebruikers kunnen ook apparaatinstellingen aanpassen die van invloed zijn op alle gebruikers, zoals wifi.\n\nWanneer je een nieuwe gebruiker toevoegt, moet die persoon een eigen profiel instellen.\n\nElke gebruiker kan apps updaten voor alle andere gebruikers. Toegankelijkheidsinstellingen en -services worden mogelijk niet overgezet naar de nieuwe gebruiker."</string>
+    <string name="user_add_user_message_long" msgid="1527434966294733380">"Je kunt dit apparaat met anderen delen door extra gebruikers toe te voegen. Elke gebruiker heeft een eigen profiel met zelf gekozen apps, achtergrond, enzovoort. Gebruikers kunnen ook apparaatinstellingen aanpassen die van invloed zijn op alle gebruikers, zoals wifi.\n\nWanneer je een nieuwe gebruiker toevoegt, moet die persoon een eigen ruimte instellen.\n\nElke gebruiker kan apps updaten voor alle andere gebruikers. Toegankelijkheidsinstellingen en -services worden mogelijk niet overgezet naar de nieuwe gebruiker."</string>
     <string name="user_add_user_message_short" msgid="3295959985795716166">"Wanneer je een nieuwe gebruiker toevoegt, moet die persoon een eigen profiel instellen.\n\nElke gebruiker kan apps updaten voor alle andere gebruikers."</string>
     <string name="user_grant_admin_title" msgid="5157031020083343984">"Deze gebruiker beheerder maken?"</string>
     <string name="user_grant_admin_message" msgid="1673791931033486709">"Beheerders hebben speciale rechten die andere gebruikers niet hebben. Een beheerder kan alle gebruikers beheren, dit apparaat updaten of resetten, instellingen wijzigen, alle geïnstalleerde apps bekijken en beheerdersrechten toekennen of intrekken voor anderen."</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Alle activiteit wordt na het afsluiten verwijderd"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Je kunt je activiteit bij afsluiten opslaan of verwijderen"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Voer een reset uit om de sessie-activiteit nu te verwijderen of verwijder of sla je activiteit op bij afsluiten"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Foto maken"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Afbeelding kiezen"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Foto selecteren"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Te veel onjuiste pogingen. De gegevens van dit apparaat worden verwijderd."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Te veel onjuiste pogingen. Deze gebruiker wordt verwijderd."</string>
@@ -657,7 +674,7 @@
     <string name="cached_apps_freezer_disabled" msgid="4816382260660472042">"Uit"</string>
     <string name="cached_apps_freezer_enabled" msgid="8866703500183051546">"Aan"</string>
     <string name="cached_apps_freezer_reboot_dialog_text" msgid="695330563489230096">"Je apparaat moet opnieuw worden opgestart om deze wijziging toe te passen. Start nu opnieuw op of annuleer de wijziging."</string>
-    <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Bedrade hoofdtelefoon"</string>
+    <string name="media_transfer_wired_usb_device_name" msgid="7699141088423210903">"Bedrade koptelefoon"</string>
     <string name="wifi_hotspot_switch_on_text" msgid="9212273118217786155">"Aan"</string>
     <string name="wifi_hotspot_switch_off_text" msgid="7245567251496959764">"Uit"</string>
     <string name="carrier_network_change_mode" msgid="4257621815706644026">"Netwerk van provider wordt gewijzigd"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernetverbinding verbroken."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Geen gesprekken."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Kies een profielfoto"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Standaard gebruikersicoon"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fysiek toetsenbord"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Toetsenbordindeling kiezen"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Standaard"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 3b28783..3cbbc05 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"ସକ୍ରିୟ, କେବଳ ବାମ"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"ସକ୍ରିୟ, କେବଳ ଡାହାଣ"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"ସକ୍ରିୟ, ବାମ ଏବଂ ଡାହାଣ"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"ମିଡିଆ ଅଡିଓ"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"ଫୋନ୍‌ କଲ୍‌‌ଗୁଡ଼ିକ"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ଫାଇଲ୍‌ ଟ୍ରାନ୍ସଫର୍‌"</string>
@@ -264,7 +286,7 @@
     <string name="bugreport_in_power" msgid="8664089072534638709">"ବଗ୍ ରିପୋର୍ଟ ସର୍ଟକଟ୍‌"</string>
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"ବଗ୍ ରିପୋର୍ଟ ଦେବା ପାଇଁ ପାୱାର୍‌ ମେନୁରେ ଏକ ବଟନ୍‌ ଦେଖାନ୍ତୁ"</string>
     <string name="keep_screen_on" msgid="1187161672348797558">"ସତର୍କ ରୁହନ୍ତୁ"</string>
-    <string name="keep_screen_on_summary" msgid="1510731514101925829">"ଚାର୍ଜ ହେବାବେଳେ ସ୍କ୍ରୀନ୍‌ ଆଦୌ ବନ୍ଦ ହେବନାହିଁ"</string>
+    <string name="keep_screen_on_summary" msgid="1510731514101925829">"ଚାର୍ଜ ହେବାବେଳେ ସ୍କ୍ରିନ କେବେ ବି ବନ୍ଦ ହେବନାହିଁ"</string>
     <string name="bt_hci_snoop_log" msgid="7291287955649081448">"ବ୍ଲୁଟୂଥ୍‍‌ HCI ସ୍ନୁପ୍‌ ଲଗ୍‌ ସକ୍ଷମ କରନ୍ତୁ"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"ବ୍ଲୁଟୁଥ୍‌ ପ୍ୟାକେଟ୍ କ୍ୟାପଚର୍ କରନ୍ତୁ (ଏହି ସେଟିଂ ବଦଳାଇବା ପରେ ବ୍ଲୁଟୁଥ୍‍‌କୁ ଟୋଗଲ୍ କରନ୍ତୁ)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"OEM ଅନଲକ୍‌ କରିବା"</string>
@@ -300,10 +322,10 @@
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"ବ୍ଲୁଟୂଥ୍‍‌ ଅଡିଓ LDAC କୋଡେକ୍‌: ପ୍ଲେବ୍ୟାକ୍‌ ଗୁଣବତ୍ତା"</string>
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"ବ୍ଲୁ-ଟୁଥ୍‌ ଅଡିଓ LDAC\nକୋଡେକ୍‌ ଚୟନକୁ ଗତିଶୀଳ କରନ୍ତୁ: ପ୍ଲେବ୍ୟାକ୍‌ କ୍ୱାଲିଟୀ"</string>
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"ଷ୍ଟ୍ରିମ୍ କରୁଛି: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
-    <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"ବ୍ୟକ୍ତିଗତ DNS"</string>
+    <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"ପ୍ରାଇଭେଟ DNS"</string>
     <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"ବ୍ୟକ୍ତିଗତ DNS ମୋଡ୍‌ ବାଛନ୍ତୁ"</string>
     <string name="private_dns_mode_off" msgid="7065962499349997041">"ବନ୍ଦ"</string>
-    <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"ଅଟୋମେଟିକ"</string>
+    <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"ସ୍ୱତଃ"</string>
     <string name="private_dns_mode_provider" msgid="3619040641762557028">"ବ୍ୟକ୍ତିଗତ DNS ପ୍ରଦାତା ହୋଷ୍ଟନାମ"</string>
     <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"DNS ପ୍ରଦାନକାରୀଙ୍କ ହୋଷ୍ଟନାମ ଲେଖନ୍ତୁ"</string>
     <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"କନେକ୍ଟ କରିହେଲା ନାହିଁ"</string>
@@ -341,7 +363,7 @@
     <string name="enhanced_connectivity_summary" msgid="1576414159820676330">"ଏନହାନ୍ସଡ୍ କନେକ୍ଟିଭିଟି ଫିଚର୍ ସକ୍ଷମ କରିଥାଏ।"</string>
     <string name="enable_terminal_title" msgid="3834790541986303654">"ସ୍ଥାନୀୟ ଟର୍ମିନାଲ୍‌"</string>
     <string name="enable_terminal_summary" msgid="2481074834856064500">"ସ୍ଥାନୀୟ ଶେଲ୍‌କୁ ଆକ‌ସେସ୍‌ ଦେଉଥିବା ଟର୍ମିନଲ୍‌ ଆପ୍‌କୁ ସକ୍ଷମ କରନ୍ତୁ"</string>
-    <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ଯାଞ୍ଚ କରୁଛି"</string>
+    <string name="hdcp_checking_title" msgid="3155692785074095986">"HDCP ଯାଞ୍ଚ"</string>
     <string name="hdcp_checking_dialog_title" msgid="7691060297616217781">"HDCPର ଯାଞ୍ଚ ଗତିବିଧି ସେଟ୍‍ କରନ୍ତୁ"</string>
     <string name="debug_debugging_category" msgid="535341063709248842">"ଡିବଗ୍‌ କରୁଛି"</string>
     <string name="debug_app" msgid="8903350241392391766">"ଡିବଗ୍‌ ଆପ୍‌ ବାଛନ୍ତୁ"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"ଧରିନିଅନ୍ତୁ ଆପଗୁଡ଼ିକ ଆଧୁନିକ ଫର୍ମାଟଗୁଡ଼ିକୁ ସମର୍ଥନ କରେ"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ଟ୍ରାନ୍ସକୋଡିଂ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଦେଖାନ୍ତୁ"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ଟ୍ରାନ୍ସକୋଡିଂ କ୍ୟାଶକୁ ଅକ୍ଷମ କରନ୍ତୁ"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine ସେଟିଂସ"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"ଫୋର୍ସ L3 ଫଲବେକ"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"ଫୋର୍ସ L3 ଫଲବେକ ଚୟନ କରନ୍ତୁ"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"ଚାଲୁଥିବା ସେବାଗୁଡ଼ିକ"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"ଏବେ ଚାଲୁଥିବା ସେବାଗୁଡ଼ିକୁ ଦେଖନ୍ତୁ ଓ ନିୟନ୍ତ୍ରଣ କରନ୍ତୁ"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"ୱେବ୍‌ଭ୍ୟୁ ପ୍ରୟୋଗ"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ବାହାରିବା ସମୟରେ ସମସ୍ତ କାର୍ଯ୍ୟକଳାପକୁ ଡିଲିଟ କରାଯିବ"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ବାହାରିବା ସମୟରେ ଆପଣଙ୍କର କାର୍ଯ୍ୟକଳାପକୁ ସେଭ ବା ଡିଲିଟ କରିପାରିବେ"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"ବର୍ତ୍ତମାନ ସେସନ କାର୍ଯ୍ୟକଳାପକୁ ଡିଲିଟ କରିବାକୁ ରିସେଟ କରନ୍ତୁ କିମ୍ବା ବାହାରିବା ସମୟରେ ଆପଣ କାର୍ଯ୍ୟକଳାପକୁ ସେଭ କିମ୍ବା ଡିଲିଟ କରିପାରିବେ"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ଗୋଟିଏ ଫଟୋ ଉଠାନ୍ତୁ"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"ଏକ ଛବି ବାଛନ୍ତୁ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ଫଟୋ ବାଛନ୍ତୁ"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"ଅନେକଗୁଡ଼ିଏ ଭୁଲ ପ୍ରଚେଷ୍ଟା। ଏହି ଡିଭାଇସର ଡାଟା ଡିଲିଟ ହୋଇଯିବ।"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"ଅନେକଗୁଡ଼ିଏ ଭୁଲ ପ୍ରଚେଷ୍ଟା। ଏହି ଉପଯୋଗକର୍ତ୍ତାଙ୍କୁ ଡିଲିଟ କରିଦିଆଯିବ।"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ଇଥରନେଟ୍‍ ବିଚ୍ଛିନ୍ନ ହୋଇଛି।"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ଇଥରନେଟ୍।"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"କୌଣସି କଲିଂ ନାହିଁ।"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"ଏକ ପ୍ରୋଫାଇଲ ଛବି ବାଛନ୍ତୁ"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"ଡିଫଲ୍ଟ ୟୁଜର ଆଇକନ"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"ଫିଜିକାଲ କୀବୋର୍ଡ"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"କୀବୋର୍ଡ ଲେଆଉଟ ବାଛନ୍ତୁ"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ଡିଫଲ୍ଟ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index 41de824..2105852 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"ਕਿਰਿਆਸ਼ੀਲ, ਸਿਰਫ਼ ਖੱਬਾ"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"ਕਿਰਿਆਸ਼ੀਲ, ਸਿਰਫ਼ ਸੱਜਾ"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"ਕਿਰਿਆਸ਼ੀਲ, ਖੱਬਾ ਅਤੇ ਸੱਜਾ"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"ਮੀਡੀਆ  ਆਡੀਓ"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"ਫ਼ੋਨ ਕਾਲਾਂ"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"ਮੰਨ ਲਓ ਕਿ ਐਪਾਂ ਆਧੁਨਿਕ ਫਾਰਮੈਟਾਂ ਦਾ ਸਮਰਥਨ ਕਰਦੀਆਂ ਹਨ"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ਟ੍ਰਾਂਸਕੋਡਿੰਗ ਸੂਚਨਾਵਾਂ ਦਿਖਾਓ"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ਟ੍ਰਾਂਸਕੋਡਿੰਗ ਕੈਸ਼ੇ ਬੰਦ ਕਰੋ"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine ਸੈਟਿੰਗਾਂ"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"ਜ਼ਬਰਦਸਤੀ L3 ਫਾਲਬੈਕ ਕਰੋ"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"ਜ਼ਬਰਦਸਤੀ L3 ਫਾਲਬੈਕ ਕਰਨ ਲਈ ਚੁਣੋ"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"ਚੱਲ ਰਹੀਆਂ ਸੇਵਾਵਾਂ"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"ਇਸ ਵੇਲੇ ਚੱਲ ਰਹੀਆਂ ਸੇਵਾਵਾਂ ਦੇਖੋ ਅਤੇ ਉਨ੍ਹਾਂ ਨੂੰ ਕੰਟਰੋਲ ਕਰੋ"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ਅਮਲੀਕਰਨ"</string>
@@ -643,11 +662,9 @@
     <string name="guest_exit_button" msgid="5774985819191803960">"ਮਹਿਮਾਨ ਮੋਡ ਤੋਂ ਬਾਹਰ ਜਾਓ"</string>
     <string name="guest_reset_button" msgid="2515069346223503479">"ਮਹਿਮਾਨ ਸੈਸ਼ਨ ਨੂੰ ਰੀਸੈੱਟ ਕਰੋ"</string>
     <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"ਮਹਿਮਾਨ ਮੋਡ ਤੋਂ ਬਾਹਰ ਜਾਓ"</string>
-    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ਬਾਹਰ ਜਾਣ \'ਤੇ ਸਾਰੀ ਸਰਗਰਮੀ ਮਿਟਾਈ ਜਾਵੇਗੀ"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ਬਾਹਰ ਜਾਣ \'ਤੇ ਸਾਰੀ ਸਰਗਰਮੀ ਮਿਟਾ ਦਿੱਤੀ ਜਾਵੇਗੀ"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ਤੁਸੀਂ ਬਾਹਰ ਜਾਣ \'ਤੇ ਆਪਣੀ ਸਰਗਰਮੀ ਰੱਖਿਅਤ ਕਰ ਜਾਂ ਮਿਟਾ ਸਕਦੇ ਹੋ"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"ਸੈਸ਼ਨ ਦੀ ਸਰਗਰਮੀ ਹੁਣੇ ਮਿਟਾਉਣ ਲਈ ਰੀਸੈੱਟ ਕਰੋ ਜਾਂ ਤੁਸੀਂ ਬਾਹਰ ਜਾਣ \'ਤੇ ਸਰਗਰਮੀ ਨੂੰ ਰੱਖਿਅਤ ਕਰ ਜਾਂ ਮਿਟਾ ਸਕਦੇ ਹੋ"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ਇੱਕ ਫ਼ੋਟੋ ਖਿੱਚੋ"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"ਕੋਈ ਚਿੱਤਰ ਚੁਣੋ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ਫ਼ੋਟੋ ਚੁਣੋ"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"ਬਹੁਤ ਸਾਰੀਆਂ ਗਲਤ ਕੋਸ਼ਿਸ਼ਾਂ। ਇਸ ਡੀਵਾਈਸ ਦਾ ਡਾਟਾ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"ਬਹੁਤ ਸਾਰੀਆਂ ਗਲਤ ਕੋਸ਼ਿਸ਼ਾਂ। ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ਈਥਰਨੈੱਟ ਡਿਸਕਨੈਕਟ ਹੋ ਗਿਆ।"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ਈਥਰਨੈੱਟ।"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"ਕਾਲਿੰਗ ਸੇਵਾ ਉਪਲਬਧ ਨਹੀਂ ਹੈ।"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"ਕੋਈ ਪ੍ਰੋਫਾਈਲ ਤਸਵੀਰ ਚੁਣੋ"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਵਰਤੋਂਕਾਰ ਪ੍ਰਤੀਕ"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡ"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"ਕੀ-ਬੋਰਡ ਖਾਕਾ ਚੁਣੋ"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 0c2d71b..93e65af 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktywne, tylko lewa strona"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktywne, tylko prawa strona"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktywny, lewa i prawa strona"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Dźwięk multimediów"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Połączenia telefoniczne"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Przesyłanie pliku"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Zakładaj, że aplikacje obsługują nowoczesne formaty"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Pokaż powiadomienia transkodowania"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Wyłącz pamięć podręczną transkodowania"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Ustawienia Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Wymuszaj kreację zastępczą L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Wybierz wymuszanie kreacji zastępczej L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Uruchomione usługi"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Wyświetl obecnie uruchomione usługi i nimi zarządzaj"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementacja WebView"</string>
@@ -491,7 +510,7 @@
     <string name="battery_info_status_full_charged" msgid="3536054261505567948">"Bateria w pełni naładowana"</string>
     <string name="battery_info_status_charging_on_hold" msgid="6364355145521694438">"Ładowanie wstrzymane"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"Kontrolowane przez administratora"</string>
-    <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolowane przez ograniczone ustawienia"</string>
+    <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Obowiązują ustawienia z ograniczonym dostępem"</string>
     <string name="disabled" msgid="8017887509554714950">"Wyłączone"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Dozwolone"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Niedozwolone"</string>
@@ -518,7 +537,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Użyj języków systemu"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Nie udało się otworzyć ustawień aplikacji <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"Ta metoda wprowadzania tekstu może gromadzić cały wpisywany tekst, w tym dane osobowe takie jak hasła czy numery kart kredytowych. Pochodzi ona z aplikacji <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Użyć jej?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Uwaga: po restarcie ta aplikacja będzie mogła uruchomić się dopiero po odblokowaniu telefonu"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Uwaga: po restarcie ta aplikacja będzie mogła uruchomić się dopiero, gdy odblokujesz telefon."</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"Stan rejestracji IMS"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"Zarejestrowane"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Niezarejestrowane"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Po zamknięciu cała aktywność zostanie usunięta"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Możesz zapisać lub usunąć swoją aktywność podczas zamykania."</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Zresetuj, aby teraz usunąć aktywność z tej sesji. Możesz też ją zapisać lub usunąć podczas zamykania sesji."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Zrób zdjęcie"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Wybierz obraz"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Wybierz zdjęcie"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Zbyt wiele nieudanych prób. Dane na urządzeniu zostaną usunięte."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Zbyt wiele nieudanych prób. Użytkownik zostanie usunięty."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Rozłączono z siecią Ethernet."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Brak połączenia."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Wybierz zdjęcie profilowe"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Ikona domyślnego użytkownika"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Klawiatura fizyczna"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Wybierz układ klawiatury"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Domyślny"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index aea8666..811c04a 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ativo, apenas o esquerdo"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ativo, apenas o direito"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ativo, esquerdo e direito"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Áudio da mídia"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Chamadas telefônicas"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferência de arquivo"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Considerar que os apps são compatíveis com formatos modernos"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Mostrar notificações de transcodificação"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Desativar cache da transcodificação"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Configurações o Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Forçar substituição do L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Selecione para forçar a substituição do L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Serviços em execução"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ver e controlar os serviços em execução no momento"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementação do WebView"</string>
@@ -522,7 +541,7 @@
     <string name="ims_reg_title" msgid="8197592958123671062">"Estado do registro de IMS"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"Registrado"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Não registrado"</string>
-    <string name="status_unavailable" msgid="5279036186589861608">"Não disponível"</string>
+    <string name="status_unavailable" msgid="5279036186589861608">"Indisponível"</string>
     <string name="wifi_status_mac_randomized" msgid="466382542497832189">"O MAC é randomizado"</string>
     <string name="wifi_tether_connected_summary" msgid="5100712926640492336">"{count,plural, =1{1 dispositivo conectado}one{# dispositivo conectado}other{# dispositivos conectados}}"</string>
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Mais tempo."</string>
@@ -619,7 +638,7 @@
     <string name="add_user_failed" msgid="4809887794313944872">"Falha ao criar um novo usuário"</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"Falha ao criar um novo convidado"</string>
     <string name="user_nickname" msgid="262624187455825083">"Apelido"</string>
-    <string name="edit_user_info_message" msgid="6677556031419002895">"O nome e a foto escolhidos ficarão visíveis para qualquer pessoa que usar este dispositivo."</string>
+    <string name="edit_user_info_message" msgid="6677556031419002895">"O nome e a foto que você escolher ficarão visíveis para qualquer pessoa que usar este dispositivo."</string>
     <string name="user_add_user" msgid="7876449291500212468">"Adicionar usuário"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Adicionar visitante"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Remover visitante"</string>
@@ -641,13 +660,11 @@
     <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Excluir"</string>
     <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Salvar"</string>
     <string name="guest_exit_button" msgid="5774985819191803960">"Sair do modo visitante"</string>
-    <string name="guest_reset_button" msgid="2515069346223503479">"Redefinir Sessão de visitante"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Redefinir sessão de visitante"</string>
     <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Sair do modo visitante"</string>
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Todas as atividades serão excluídas ao sair"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Você pode salvar ou excluir sua atividade ao sair"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Redefina para excluir a atividade da sessão agora. Salve ou exclua a atividade ao sair"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Excesso de tentativas incorretas. Os dados deste dispositivo serão excluídos."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Excesso de tentativas incorretas. O usuário será excluído."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet desconectada."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Sem chamadas."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Escolher a foto do perfil"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Ícone de usuário padrão"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Teclado físico"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Escolha o layout do teclado"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Padrão"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index e0fd5e7..4c88683 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -106,12 +106,34 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ativo, apenas esquerdo"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ativo, apenas direito"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ativo, esquerdo e direito"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Áudio de multimédia"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Chamadas telefónicas"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferência do ficheiro"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispositivo de entrada"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acesso à internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Perm. acesso a contactos e histór. cham."</string>
+    <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Acesso a contactos e histórico de chamadas"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"As informações são usadas para anúncios de chamadas e outros"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Partilha da ligação à internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mensagens de texto"</string>
@@ -140,7 +162,7 @@
     <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Usar para entrada"</string>
     <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="3374057355721486932">"Usar para aparelhos auditivos"</string>
     <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Usar para LE_AUDIO"</string>
-    <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Sincr."</string>
+    <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Sincronizar"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"SINCRONIZAR"</string>
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"A sincronização concede acesso aos seus contactos e ao histórico de chamadas quando tem uma ligação estabelecida."</string>
@@ -265,7 +287,7 @@
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Mostrar um botão no menu ligar/desligar para criar um relatório de erro"</string>
     <string name="keep_screen_on" msgid="1187161672348797558">"Manter ativo"</string>
     <string name="keep_screen_on_summary" msgid="1510731514101925829">"O ecrã nunca entrará em suspensão durante o carregamento"</string>
-    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Ativar registo de monit. Bluetooth HCI"</string>
+    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Ativar registo de monitorização Bluetooth HCI"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Capturar os pacotes Bluetooth (ative/desative o Bluetooth após alterar esta definição)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"Desbloqueio de OEM"</string>
     <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Permitir o desbloqueio do carregador de arranque"</string>
@@ -305,7 +327,7 @@
     <string name="private_dns_mode_off" msgid="7065962499349997041">"Desativado"</string>
     <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"Automático"</string>
     <string name="private_dns_mode_provider" msgid="3619040641762557028">"Nome do anfitrião do fornecedor DNS privado"</string>
-    <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Introduza nome - anfitrião do fornecedor DNS"</string>
+    <string name="private_dns_mode_provider_hostname_hint" msgid="6564868953748514595">"Introduza o nome de anfitrião do fornecedor DNS"</string>
     <string name="private_dns_mode_provider_failure" msgid="8356259467861515108">"Não foi possível estabelecer ligação"</string>
     <string name="wifi_display_certification_summary" msgid="8111151348106907513">"Mostrar opções da certificação de display sem fios"</string>
     <string name="wifi_verbose_logging_summary" msgid="4993823188807767892">"Aumentar o nível de reg. de Wi-Fi, mostrar por RSSI de SSID no Selec. de Wi-Fi"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Assumir que as apps suportam formatos modernos"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Mostrar notificações de transcodificação"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Desativar cache de transcodificação"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Definições do Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Forçar utilização alternativa do L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Selecione para forçar a utilização alternativa do L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Serviços em execução"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ver e controlar os serviços actualmente em execução"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementação WebView"</string>
@@ -518,7 +537,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Usar idiomas do sistema"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Falha ao abrir as definições para <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"Este método de introdução pode permitir a recolha de todo o texto que digitar, incluindo dados pessoais como, por exemplo, palavras-passe e números de cartões de crédito. Decorre da aplicação <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Usar este método de introdução?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Nota: após reiniciar, só é possível iniciar esta aplicação quando o telemóvel for desbloqueado."</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Nota: após um reinício, só é possível iniciar esta app com o telemóvel desbloqueado."</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"Estado do registo IMS"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"Registado"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Não registado"</string>
@@ -555,7 +574,7 @@
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"Este tablet"</string>
     <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
     <skip />
-    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Altifalante estação carregam."</string>
+    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"Altifalante estação carregamento"</string>
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo associado"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este telemóvel"</string>
@@ -625,7 +644,7 @@
     <string name="guest_exit_guest" msgid="5908239569510734136">"Remover convidado"</string>
     <string name="guest_reset_guest" msgid="6110013010356013758">"Repor convidado"</string>
     <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Quer repor o convidado?"</string>
-    <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Remover o convidado?"</string>
+    <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Remover convidado?"</string>
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Repor"</string>
     <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Remover"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"A repor o convidado…"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Toda a atividade é eliminada ao sair"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Pode guardar ou eliminar a sua atividade ao sair"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Reponha para eliminar agora a atividade da sessão. Pode ainda guardar ou eliminar a atividade ao sair"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Demasiadas tentativas incorretas. Os dados deste dispositivo vão ser eliminados."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Demasiadas tentativas incorretas. Este utilizador vai ser eliminado."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet desligada."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Sem chamadas."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Escolha uma imagem do perfil"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Ícone do utilizador predefinido"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Teclado físico"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Escolha um esquema de teclado"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Predefinição"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index aea8666..811c04a 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Ativo, apenas o esquerdo"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Ativo, apenas o direito"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Ativo, esquerdo e direito"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Áudio da mídia"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Chamadas telefônicas"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferência de arquivo"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Considerar que os apps são compatíveis com formatos modernos"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Mostrar notificações de transcodificação"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Desativar cache da transcodificação"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Configurações o Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Forçar substituição do L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Selecione para forçar a substituição do L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Serviços em execução"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ver e controlar os serviços em execução no momento"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementação do WebView"</string>
@@ -522,7 +541,7 @@
     <string name="ims_reg_title" msgid="8197592958123671062">"Estado do registro de IMS"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"Registrado"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Não registrado"</string>
-    <string name="status_unavailable" msgid="5279036186589861608">"Não disponível"</string>
+    <string name="status_unavailable" msgid="5279036186589861608">"Indisponível"</string>
     <string name="wifi_status_mac_randomized" msgid="466382542497832189">"O MAC é randomizado"</string>
     <string name="wifi_tether_connected_summary" msgid="5100712926640492336">"{count,plural, =1{1 dispositivo conectado}one{# dispositivo conectado}other{# dispositivos conectados}}"</string>
     <string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Mais tempo."</string>
@@ -619,7 +638,7 @@
     <string name="add_user_failed" msgid="4809887794313944872">"Falha ao criar um novo usuário"</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"Falha ao criar um novo convidado"</string>
     <string name="user_nickname" msgid="262624187455825083">"Apelido"</string>
-    <string name="edit_user_info_message" msgid="6677556031419002895">"O nome e a foto escolhidos ficarão visíveis para qualquer pessoa que usar este dispositivo."</string>
+    <string name="edit_user_info_message" msgid="6677556031419002895">"O nome e a foto que você escolher ficarão visíveis para qualquer pessoa que usar este dispositivo."</string>
     <string name="user_add_user" msgid="7876449291500212468">"Adicionar usuário"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Adicionar visitante"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Remover visitante"</string>
@@ -641,13 +660,11 @@
     <string name="guest_exit_clear_data_button" msgid="3425812652180679014">"Excluir"</string>
     <string name="guest_exit_save_data_button" msgid="3690974510644963547">"Salvar"</string>
     <string name="guest_exit_button" msgid="5774985819191803960">"Sair do modo visitante"</string>
-    <string name="guest_reset_button" msgid="2515069346223503479">"Redefinir Sessão de visitante"</string>
+    <string name="guest_reset_button" msgid="2515069346223503479">"Redefinir sessão de visitante"</string>
     <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"Sair do modo visitante"</string>
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Todas as atividades serão excluídas ao sair"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Você pode salvar ou excluir sua atividade ao sair"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Redefina para excluir a atividade da sessão agora. Salve ou exclua a atividade ao sair"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Tirar uma foto"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Escolher uma imagem"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selecionar foto"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Excesso de tentativas incorretas. Os dados deste dispositivo serão excluídos."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Excesso de tentativas incorretas. O usuário será excluído."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet desconectada."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Sem chamadas."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Escolher a foto do perfil"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Ícone de usuário padrão"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Teclado físico"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Escolha o layout do teclado"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Padrão"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 92eeb2f..1233afd 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -106,12 +106,34 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Activ, numai stânga"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Activ, numai dreapta"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Activ, stânga și dreapta"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Conținut media audio"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Apeluri telefonice"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transfer de fișiere"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Dispozitiv de intrare"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Acces la internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Permite accesul la agendă și la istoric"</string>
+    <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Oferă acces la agendă și istoric apeluri"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Informațiile se vor folosi pentru notificări de apeluri etc."</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Distribuirea conexiunii la internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Mesaje text"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Presupune că aplicațiile acceptă formatele moderne"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Vezi notificările privind transcodarea"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Dezactivează memoria cache pentru transcodare"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Setări Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Forțează alternativa L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Selectează pentru a forța alternativa L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Servicii în curs de funcționare"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Vezi și controlează serviciile care funcționează în prezent"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementare WebView"</string>
@@ -627,7 +646,7 @@
     <string name="guest_reset_guest_dialog_title" msgid="8047270010895437534">"Resetezi invitatul?"</string>
     <string name="guest_remove_guest_dialog_title" msgid="4548511006624088072">"Excluzi invitatul?"</string>
     <string name="guest_reset_guest_confirm_button" msgid="2989915693215617237">"Resetează"</string>
-    <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Elimină"</string>
+    <string name="guest_remove_guest_confirm_button" msgid="7858123434954143879">"Exclude"</string>
     <string name="guest_resetting" msgid="7822120170191509566">"Se resetează invitatul…"</string>
     <string name="guest_reset_and_restart_dialog_title" msgid="3396657008451616041">"Resetezi sesiunea pentru invitați?"</string>
     <string name="guest_reset_and_restart_dialog_message" msgid="2764425635305200790">"Astfel, va începe o nouă sesiune pentru invitați și se vor șterge toate aplicațiile și datele din sesiunea actuală"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Toate activitățile vor fi șterse la ieșire"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Poți să salvezi sau să ștergi activitatea la ieșire"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Resetează pentru a șterge acum activitatea din sesiune sau salvează ori șterge activitatea la ieșire"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Fă o fotografie"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Alege o imagine"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Selectează fotografia"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Prea multe încercări incorecte. Datele de pe acest dispozitiv vor fi șterse."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Prea multe încercări incorecte. Acest utilizator va fi șters."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet deconectat."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Apelarea nu este disponibilă."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Alege o fotografie de profil"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Pictograma prestabilită a utilizatorului"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Tastatură fizică"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Alege aspectul tastaturii"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Prestabilit"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index c78bdec..43645f4 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Активен, только левое ухо"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Активен, только правое ухо"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Активен, оба уха"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Профиль A2DP"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Звонки"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Профиль OPP"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Считать, что приложения поддерживают современные форматы кодирования"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Показывать уведомления о перекодировании"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Отключить кеш перекодирования"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Настройки Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Принудительный переход к L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Выберите, чтобы использовать принудительный переход к L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Работающие службы"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Просмотр работающих служб и управление ими"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Сервис WebView"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"История будет удалена сразу после выхода"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"При выходе вы можете сохранить или удалить историю"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Можно сбросить историю сеанса прямо сейчас, либо удалить или сохранить ее при выходе."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Сделать снимок"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Выбрать фото"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Выбрать фотографию"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Слишком много неудачных попыток. С устройства будут удалены все данные."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Слишком много неудачных попыток. Этот пользователь будет удален."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Устройство отключено от Ethernet."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Совершение вызовов невозможно."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Выберите фото профиля"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Значок пользователя по умолчанию"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Физическая клавиатура"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Выберите раскладку клавиатуры"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"По умолчанию"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 9239237..d965b73 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"සක්‍රිය, වම පමණි"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"සක්‍රිය, දකුණ පමණි"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"සක්‍රිය, වම සහ දකුණ"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"මාධ්‍ය ශ්‍රව්‍ය"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"දුරකථන ඇමතුම්"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ගොනු හුවමාරුව"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"යෙදුම් නවීන ආකෘති සඳහා සහාය දක්වයි යැයි උපකල්පනය කරමු"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ට්‍රාන්ස්කෝඩින් දැනුම්දීම් පෙන්වන්න"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ට්‍රාන්ස්කොඩින් හැඹිලිය අබල කරන්න"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine සැකසීම්"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 පසුබැසීමට බල කරන්න"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 පසුබැසීමට බල කිරීමට තෝරන්න"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"ධාවනය වන සේවා"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"දැනට ධාවනය වන සේවා බලන්න සහ පාලනය කරන්න"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ක්‍රියාත්මක කිරීම"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"පිටවීමේදී සියලු ක්‍රියාකාරකම් මකනු ඇත"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"ඔබට පිටවීමේදී ඔබගේ ක්‍රියාකාරකම් සුරැකීමට හෝ මැකීමට හැකිය"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"දැන් සැසි ක්‍රියාකාරකම් මැකීමට යළි සකසන්න, නැතහොත් ඔබට පිටවීමේදී ක්‍රියාකාරකම් සුරැකීමට හෝ මැකීමට හැකිය"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ඡායාරූපයක් ගන්න"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"රූපයක් තෝරන්න"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ඡායාරූපය තෝරන්න"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"වැරදි උත්සාහයන් ඉතා වැඩි ගණනකි. මෙම උපාංගයෙහි දත්ත මකනු ඇත."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"වැරදි උත්සාහයන් ඉතා වැඩි ගණනකි. මෙම පරිශීලකයා මකනු ඇත."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ඊතර්නෙට් විසන්ධි කරන ලදී."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ඊතර්නෙට්."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"ඇමතුම් නැත."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"පැතිකඩ පින්තූරයක් තේරීම"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"පෙරනිමි පරිශීලක නිරූපකය"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"භෞතික යතුරු පුවරුව"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"යතුරු පුවරු පිරිසැලසුම තෝරන්න"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"පෙරනිමි"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 2778f8d..77c265e 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -106,12 +106,34 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktívne, iba ľavá strana"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktívne, iba pravá strana"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktívne, ľavá aj pravá strana"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Zvuk médií"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonické hovory"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos súborov"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Vstupné zariadenie"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Prístup na internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Povoľte aj prístup ku kontaktom a histórii hovorov"</string>
+    <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Povoliť prístup ku kontaktom a histórii hovorov"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Pomocou informácií sa budú oznamovať hovory a viac"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Zdieľanie pripojenia na Internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Textové správy"</string>
@@ -140,7 +162,7 @@
     <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Použiť pre vstup"</string>
     <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="3374057355721486932">"Používať pre načúvadlá"</string>
     <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Používať s profilom LE_AUDIO"</string>
-    <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Párovať"</string>
+    <string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Spárovať"</string>
     <string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"PÁROVAŤ"</string>
     <string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Zrušiť"</string>
     <string name="bluetooth_pairing_will_share_phonebook" msgid="3064334458659165176">"Párovaním udelíte zariadeniam po pripojení prístup k svojim kontaktom a histórii hovorov."</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Prepdokladať, že aplikácie podporujú moderné formáty"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Zobraziť upozornenia prekódovania"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Deaktivácia vyrovnávacej pamäte prekódovania"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Nastavenia softvéru Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Vynútiť zálohu L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Vyberte, keď chcete vynútiť zálohu L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Spustené služby"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Zobrazovať a riadiť aktuálne spustené služby"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Implementácia WebView"</string>
@@ -483,7 +502,7 @@
     <string name="battery_info_status_charging" msgid="4279958015430387405">"Nabíja sa"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Rýchle nabíjanie"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Pomalé nabíjanie"</string>
-    <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Nabíja sa bezdrôtovo"</string>
+    <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Bezdrôtové nabíjanie"</string>
     <string name="battery_info_status_charging_dock" msgid="8573274094093364791">"Nabíja sa"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Nenabíja sa"</string>
     <string name="battery_info_status_not_charging" msgid="1103084691314264664">"Pripojené, ale nenabíja sa"</string>
@@ -619,7 +638,7 @@
     <string name="add_user_failed" msgid="4809887794313944872">"Nového použív. sa nepodarilo vytvoriť"</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"Nového hosťa sa nepodarilo vytvoriť"</string>
     <string name="user_nickname" msgid="262624187455825083">"Prezývka"</string>
-    <string name="edit_user_info_message" msgid="6677556031419002895">"Názov a obrázok, ktorý vyberiete, budú vidieť všetci používatelia tohto zariadenia."</string>
+    <string name="edit_user_info_message" msgid="6677556031419002895">"Meno a obrázok, ktorý vyberiete, uvidia všetci používatelia tohto zariadenia."</string>
     <string name="user_add_user" msgid="7876449291500212468">"Pridať používateľa"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Pridať hosťa"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Odobrať hosťa"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Pri ukončení sa všetka aktivita odstráni"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Aktivitu môžete pri ukončení uložiť alebo odstrániť"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Resetovaním ihneď odstránite aktivitu relácie alebo ju uložte či odstráňte pri ukončení relácie"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Odfotiť"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Vybrať obrázok"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Vybrať fotku"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Príliš veľa chybných pokusov. Údaje tohto zariadenia budú odstránené."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Príliš veľa chybných pokusov. Tento používateľ bude odobraný."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Sieť ethernet je odpojená"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Žiadne volanie."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Výber profilovej fotky"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Predvolená ikona používateľa"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fyzická klávesnica"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Vyberte rozloženie klávesnice"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Predvolené"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index b1ca328..abca26f 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktivno, samo levo"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktivno, samo desno"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktivno, levo in desno"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Zvok predstavnosti"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonski klici"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Prenos datoteke"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Aplikacije naj bi podpirale sodobne oblike zapisov"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Prikaz obvestil o prekodiranju"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Onemogoči predpomnilnik za prekodiranje"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Nastavitve za Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Vsili nadomestno varnostno raven L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Izbira vsiljenja nadomestne varnostne ravni L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Zagnane storitve"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Preglejte in nadzorujte storitve, ki so trenutno zagnane."</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Izvedba spletnega pogleda"</string>
@@ -619,7 +638,7 @@
     <string name="add_user_failed" msgid="4809887794313944872">"Ustvarjanje novega uporabnika ni uspelo."</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"Ustvarjanje novega gosta ni uspelo."</string>
     <string name="user_nickname" msgid="262624187455825083">"Vzdevek"</string>
-    <string name="edit_user_info_message" msgid="6677556031419002895">"Ime in slika, ki ju izberete, bosta vidna za vse, ki uporabljajo to napravo."</string>
+    <string name="edit_user_info_message" msgid="6677556031419002895">"Ime in slika, ki ju izberete, bosta vidna vsem, ki uporabljajo to napravo."</string>
     <string name="user_add_user" msgid="7876449291500212468">"Dodaj uporabnika"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"Dodaj gosta"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"Odstrani gosta"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Ko zaprete način za goste, bo vsa dejavnost izbrisana."</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Ob zaprtju načina lahko shranite ali izbrišete dejavnost."</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Ponastavite za izbris dejavnosti v seji zdaj, lahko pa jo shranite ali izbrišete, ko zaprete način za goste."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Fotografiranje"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Izberi sliko"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Izbira fotografije"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Preveč napačnih poskusov. Podatki v napravi bodo izbrisani."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Preveč napačnih poskusov. Uporabnik bo izbrisan."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernetna povezava je prekinjena."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Klicanje ni mogoče."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Izbira profilne slike"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Privzeta ikona uporabnika"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fizična tipkovnica"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Izbira razporeditve tipkovnice"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Privzeto"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index e46a4d8..0f48e42c9 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -106,7 +106,29 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktive, vetëm majtas"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktive, vetëm djathtas"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktive, majtas dhe djathtas"</string>
-    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Audioja e klipit \"media\""</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
+    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Audioja e medias"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonatat"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Transferimi i skedarëve"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Pajisja e hyrjes"</string>
@@ -410,8 +432,8 @@
     <string name="force_resizable_activities_summary" msgid="2490382056981583062">"Bëj që të gjitha aktivitetet të kenë madhësi të ndryshueshme për përdorimin me shumë dritare, pavarësisht vlerave të manifestit."</string>
     <string name="enable_freeform_support" msgid="7599125687603914253">"Aktivizo dritaret me formë të lirë"</string>
     <string name="enable_freeform_support_summary" msgid="1822862728719276331">"Aktivizo mbështetjen për dritaret eksperimentale me formë të lirë."</string>
-    <string name="local_backup_password_title" msgid="4631017948933578709">"Fjalëkalimi rezervë i kompjuterit"</string>
-    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Rezervimet e plota në kompjuter nuk janë të mbrojtura aktualisht"</string>
+    <string name="local_backup_password_title" msgid="4631017948933578709">"Fjalëkalimi i rezervimit të desktopit"</string>
+    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"Rezervimet e plota të desktopit nuk janë të mbrojtura aktualisht"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"Trokit për të ndryshuar ose hequr fjalëkalimin për rezervime të plota të desktopit"</string>
     <string name="local_backup_password_toast_success" msgid="4891666204428091604">"Fjalëkalimi i ri u vendos"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"Fjalëkalimi i ri dhe konfirmimi nuk përputhen"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Supozo se aplikacionet i mbështetin formatet moderne"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Shfaq njoftimet e transkodimit"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Çaktivizo memorien specifike të transkodimit"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Cilësimet e Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Detyro kalimin përsëri te L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Zgjidh që të detyrosh kalimin përsëri te L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Shërbimet në ekzekutim"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Shiko dhe kontrollo shërbimet që po ekzekutohen aktualisht"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Zbatimi i WebView"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Të gjitha aktivitetet do të fshihen kur të dalësh"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Mund ta ruash ose ta fshish aktivitetin tënd kur të dalësh"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Rivendose për të fshirë aktivitetin e sesionit tani ose mund ta ruash ose ta fshish aktivitetin kur të dalësh"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Bëj një fotografi"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Zgjidh një imazh"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Zgjidh një fotografi"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Shumë tentativa të pasakta. Të dhënat e kësaj pajisjeje do të fshihen."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Shumë tentativa të pasakta. Ky përdorues do të fshihet."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Lidhja e eternetit u shkëput."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Eternet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Telefonatat nuk ofrohen"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Zgjidh një fotografi profili"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Ikona e parazgjedhur e përdoruesit"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Tastiera fizike"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Zgjidh strukturën e tastierës"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Parazgjedhja"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index cc4cd5f..d309036c 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -106,11 +106,33 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Активно, само с леве стране"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Активно, с десне стране"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Активно, с леве и десне стране"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Звук медија"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Телефонски позиви"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Пренос датотеке"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Улазни уређај"</string>
-    <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Приступ Интернету"</string>
+    <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Приступ интернету"</string>
     <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Дозволи контакте и историју позива"</string>
     <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Информације ће се користити за обавештења о позивима и друго"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Дељење интернет везе"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Подразумевај да апликације подржавају модерне формате"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Приказуј обавештења о транскодирању"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Онемогући кеш транскодирања"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine подешавања"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Принудно примени L3 резерву"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Изаберите да бисте принудно применили L3 резерву"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Покренуте услуге"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Приказ и контрола тренутно покренутих услуга"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Примена WebView-а"</string>
@@ -611,8 +630,8 @@
     <string name="user_new_profile_name" msgid="2405500423304678841">"Нови профил"</string>
     <string name="user_info_settings_title" msgid="6351390762733279907">"Подаци о кориснику"</string>
     <string name="profile_info_settings_title" msgid="105699672534365099">"Подаци о профилу"</string>
-    <string name="user_need_lock_message" msgid="4311424336209509301">"Да бисте могли да направите ограничени профил, треба да подесите закључавање екрана да бисте заштитили апликације и личне податке."</string>
-    <string name="user_set_lock_button" msgid="1427128184982594856">"Подеси закључавање"</string>
+    <string name="user_need_lock_message" msgid="4311424336209509301">"Да бисте могли да направите ограничени профил, треба да подесите откључавање екрана да бисте заштитили апликације и личне податке."</string>
+    <string name="user_set_lock_button" msgid="1427128184982594856">"Подеси откључавање"</string>
     <string name="user_switch_to_user" msgid="6975428297154968543">"Пређи на корисника <xliff:g id="USER_NAME">%s</xliff:g>"</string>
     <string name="creating_new_user_dialog_message" msgid="7232880257538970375">"Прави се нови корисник…"</string>
     <string name="creating_new_guest_dialog_message" msgid="1114905602181350690">"Прави се нови гост…"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Све активности ће бити избрисане при излазу"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Можете да сачувате или избришете активности при излазу"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Ресетујете за брисање активности сесије, или сачувајте или избришите активности при излазу"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Сликај"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Одабери слику"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Изаберите слику"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Превише нетачних покушаја. Избрисаћемо податке са овог уређаја."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Превише нетачних покушаја. Избрисаћемо овог корисника."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Веза са етернетом је прекинута."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Етернет."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Без позивања."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Одаберите слику профила"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Подразумевана икона корисника"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Физичка тастатура"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Одаберите распоред тастатуре"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Подразумевано"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index f2a73c5..363396a 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktiv, bara vänster"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktiv, bara höger"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktiv, vänster och höger"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Medialjud"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefonsamtal"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Filöverföring"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Anta att appar har stöd för moderna format"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Visa aviseringar för omkodning"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Inaktivera cacheminne för omkodning"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine-inställningar"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Tvinga L3-alternativ"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Välj för att tvinga L3-alternativ"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Aktiva tjänster"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Visa och styr aktiva tjänster"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView-implementering"</string>
@@ -518,7 +537,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Använd systemspråk"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Det gick inte att öppna inställningarna för <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"Den här inmatningsmetoden kan samla all text som du skriver, inklusive personliga uppgifter som lösenord och kreditkortsnummer. Den kommer från appen <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Vill du använda inmatningsmetoden?"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Obs! När du har startat om enheten måste du låsa upp mobilen innan du kan starta den här appen"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Obs! När du har startat om enheten måste du låsa upp telefonen innan du kan starta den här appen"</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"IMS-registrering"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"Registrerad"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"Ej registrerad"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"All aktivitet raderas när du avslutar"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Du kan spara eller radera aktivitet när du avslutar"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Återställ om du vill radera sessionsaktiviteten nu, eller spara eller radera aktivitet när du avslutar"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Ta ett foto"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Välj en bild"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Välj foto"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"För många felaktiga försök. Enhetens data raderas."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"För många felaktiga försök. Den här användaren raderas."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet har kopplats från."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Inga anrop."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Välj en profilbild"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Ikon för standardanvändare"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fysiskt tangentbord"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Välj en tangentbordslayout"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Standard"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index ce28386..ebff38b 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Inatumika, kushoto pekee"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Inatumika, kulia pekee"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Inatumika, kushoto na kulia"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Sauti ya maudhui"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Simu"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Uhamishaji wa faili"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Chukulia kuwa programu zinatumia miundo ya kisasa"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Onyesha arifa za kubadilisha muundo wa faili"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Zima kipengele cha akiba ya kubadilisha muundo wa faili"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Mipangilio ya Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Lazimisha chaguo mbadala ya L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Teua ili ulazimishe chaguo mbadala ya L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Huduma zinazoendeshwa"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Onyesha na udhibiti huduma zinazoendeshwa kwa sasa"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Utekelezaji wa WebView"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Shughuli zote zitafutwa wakati wa kufunga"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Unaweza kuhifadhi au kufuta shughuli zako wakati wa kufunga"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Weka upya ili ufute shughuli za kipindi sasa au unaweza kuhifadhi au kufuta shughuli wakati wa kufunga"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Piga picha"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Chagua picha"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Chagua picha"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Umejaribu kufungua mara nyingi mno kwa njia isiyo sahihi. Data iliyo kwenye kifaa hiki itafutwa."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Umejaribu kufungua mara nyingi mno kwa njia isiyo sahihi. Maelezo ya mtumiaji huyu yatafutwa."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethaneti imeondolewa."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethaneti."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Huwezi kupiga wala kupokea simu."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Chagua picha ya wasifu"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Aikoni chaguomsingi ya mtumiaji"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Kibodi halisi"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Chagua mpangilio wa kibodi"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Chaguomsingi"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 2936378..1648de0 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"இடது பக்கம் மட்டும் செயலில் உள்ளது"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"வலது பக்கம் மட்டும் செயலில் உள்ளது"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"வலது மற்றும் இடது பக்கம் செயலில் உள்ளது"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"மீடியா ஆடியோ"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"ஃபோன் அழைப்புகள்"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ஃபைல் இடமாற்றம்"</string>
@@ -265,7 +287,7 @@
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"பிழை அறிக்கையைப் பெற பவர் மெனுவில் விருப்பத்தைக் காட்டு"</string>
     <string name="keep_screen_on" msgid="1187161672348797558">"செயலில் வைத்திரு"</string>
     <string name="keep_screen_on_summary" msgid="1510731514101925829">"சார்ஜ் ஏறும்போது திரை எப்போதும் உறக்கநிலைக்குச் செல்லாது"</string>
-    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"புளூடூத் HCI ஸ்னுப் பதிவை இயக்கு"</string>
+    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"புளூடூத் HCI ஸ்னுப் பதிவை இயக்குதல்"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"புளூடூத் பேக்கெட்டுகளைக் கண்டறி. (இந்த அமைப்பை மாற்றிய பின்பு, புளூடூத்தை மாற்று)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"OEM திறத்தல்"</string>
     <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"பூட்லோடரைத் திறக்க அனுமதி"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"ஆப்ஸ் மாடர்ன் வடிவங்களை ஆதரிக்கும்படி அமை"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"குறிமாற்ற அறிவிப்புகளைக் காட்டு"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"குறிமாற்றத்திற்கான தற்காலிக சேமிப்பை முடக்குதல்"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine அமைப்புகள்"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 ஃபால்பேக்கை இயக்குதல்"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 ஃபால்பேக்கை இயக்குவதற்குத் தேர்ந்தெடுக்கலாம்"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"இயங்கும் சேவைகள்"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"தற்போது இயக்கத்தில் இருக்கும் சேவைகளைப் பார்த்து கட்டுப்படுத்து"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView செயல்படுத்தல்"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"வெளியேறியவுடன் அனைத்துச் செயல்பாடுகளும் நீக்கப்படும்"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"வெளியேறும்போது செயல்பாடுகளைச் சேமிக்கலாம் அல்லது நீக்கலாம்"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"அமர்வின் செயல்பாடுகளை இப்போதே நீக்க ரீசெட் செய்யவும் அல்லது வெளியேறும்போது செயல்பாடுகளைச் சேமிக்கலாம் அல்லது நீக்கலாம்"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"படமெடுங்கள்"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"படத்தைத் தேர்வுசெய்யுங்கள்"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"படத்தைத் தேர்ந்தெடுங்கள்"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"பலமுறை தவறாக முயன்ற காரணத்தால் இந்தச் சாதனத்தின் தரவு நீக்கப்படும்."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"பலமுறை தவறாக முயன்ற காரணத்தால் இந்தப் பயனர் நீக்கப்படுவார்."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ஈத்தர்நெட் துண்டிக்கப்பட்டது."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ஈதர்நெட்."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"அழைப்பை மேற்கொள்ள முடியவில்லை."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"சுயவிவரப் படத்தைத் தேர்வுசெய்யுங்கள்"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"இயல்புநிலைப் பயனர் ஐகான்"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"கீபோர்டு"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"கீபோர்டு தளவமைப்பைத் தேர்வுசெய்தல்"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"இயல்பு"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index a80976d..7ee57cf 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"యాక్టివ్‌గా ఉంది, ఎడమవైపు మాత్రమే యాక్టివ్‌గా ఉంది"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"యాక్టివ్‌గా ఉంది, కుడివైపు యాక్టివ్‌గా ఉంది"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"యాక్టివ్‌గా ఉంది, ఎడమవైపు, కుడివైపు యాక్టివ్‌గా ఉంది"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"మీడియా ఆడియో"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"ఫోన్ కాల్స్‌"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"ఫైల్ బదిలీ"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"యాప్‌లు ఆధునిక ఫార్మాట్‌లకు సపోర్ట్ చేస్తాయని అనుకోండి"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ట్రాన్స్‌కోడింగ్ నోటిఫికేషన్‌లను చూపండి"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ట్రాన్స్‌కోడింగ్ కాష్‌ను డిజేబుల్ చేయండి"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine సెట్టింగ్‌లు"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"ఫోర్స్ L3 ఫాల్‌బ్యాక్"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"ఫోర్స్ L3 ఫాల్‌బ్యాక్‌ను ఎంచుకోండి"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"అమలులో ఉన్న సర్వీస్‌లు"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"ప్రస్తుతం అమలులో ఉన్న సర్వీస్‌లను చూడండి, కంట్రోల్‌ చేయండి"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"వెబ్ వీక్షణ అమలు"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"వైదొలగినప్పుడు యాక్టివిటీ అంతా తొలగించబడుతుంది"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"మీరు వైదొలగేటప్పుడు, యాక్టివిటీని సేవ్ చేయవచ్చు లేదా తొలగించవచ్చు"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"సెషన్ యాక్టివిటీని తొలగించడానికి ఇప్పుడే రీసెట్ చేయండి లేదా మీరు నిష్క్రమించేటప్పుడు యాక్టివిటీని సేవ్ చేయవచ్చు లేదా తొలగించవచ్చు"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ఒక ఫోటో తీయండి"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"ఇమేజ్‌ను ఎంచుకోండి"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"ఫోటోను ఎంచుకోండి"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"చాలా ఎక్కువ తప్పు ప్రయత్నాలు చేశారు. ఈ పరికరం డేటా తొలగించబడుతుంది."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"చాలా ఎక్కువ తప్పు ప్రయత్నాలు చేశారు. ఈ యూజర్ తొలగించబడతారు."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ఈథర్‌నెట్ డిస్‌కనెక్ట్ చేయబడింది."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ఈథర్‌నెట్."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"కాలింగ్ మోడ్ ఆఫ్‌లో ఉంది."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"ప్రొఫైల్ ఫోటోను ఎంచుకోండి"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"ఆటోమేటిక్ సెట్టింగ్ యూజర్ చిహ్నం"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"భౌతిక కీబోర్డ్"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"కీబోర్డ్ లేఅవుట్‌ను ఎంచుకోండి"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ఆటోమేటిక్ సెట్టింగ్"</string>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index 480aee4..bf73a22 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -59,7 +59,7 @@
     <item msgid="6421717003037072581">"ใช้การตรวจสอบ HDCP เสมอ"</item>
   </string-array>
   <string-array name="bt_hci_snoop_log_entries">
-    <item msgid="695678520785580527">"ปิดใช้"</item>
+    <item msgid="695678520785580527">"ปิดใช้อยู่"</item>
     <item msgid="6336372935919715515">"เปิดใช้รายการที่กรอง"</item>
     <item msgid="2779123106632690576">"เปิดใช้"</item>
   </string-array>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index cdba33d..55b57db 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -106,13 +106,35 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"ใช้งานอยู่ เฉพาะข้างซ้าย"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"ใช้งานอยู่ เฉพาะข้างขวา"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"ใช้งานอยู่ ข้างซ้ายและขวา"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"เสียงของสื่อ"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"โทรศัพท์"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"การถ่ายโอนไฟล์"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"อุปกรณ์อินพุต"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"การเข้าถึงอินเทอร์เน็ต"</string>
     <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"ให้เข้าถึงรายชื่อติดต่อและประวัติการโทร"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"จะมีการใช้ข้อมูลเพื่อประกาศการติดต่อและอื่นๆ"</string>
+    <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"จะมีการใช้ข้อมูลเพื่อประกาศการโทรและอื่นๆ"</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"การแชร์การเชื่อมต่ออินเทอร์เน็ต"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"ข้อความ"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"การเข้าถึงซิม"</string>
@@ -239,7 +261,7 @@
     <string name="adb_wireless_settings" msgid="2295017847215680229">"การแก้ไขข้อบกพร่องผ่าน Wi-Fi"</string>
     <string name="adb_wireless_list_empty_off" msgid="1713707973837255490">"หากต้องการดูและใช้อุปกรณ์ที่มีอยู่ ให้เปิดการแก้ไขข้อบกพร่องผ่าน Wi-Fi"</string>
     <string name="adb_pair_method_qrcode_title" msgid="6982904096137468634">"จับคู่อุปกรณ์ด้วยคิวอาร์โค้ด"</string>
-    <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"จับคู่อุปกรณ์เครื่องใหม่โดยใช้เครื่องมือสแกนคิวอาร์โค้ด"</string>
+    <string name="adb_pair_method_qrcode_summary" msgid="7130694277228970888">"จับคู่อุปกรณ์เครื่องใหม่โดยใช้แอปสแกนคิวอาร์โค้ด"</string>
     <string name="adb_pair_method_code_title" msgid="1122590300445142904">"จับคู่อุปกรณ์ด้วยรหัสการจับคู่"</string>
     <string name="adb_pair_method_code_summary" msgid="6370414511333685185">"จับคู่อุปกรณ์เครื่องใหม่โดยใช้รหัสตัวเลข 6 หลัก"</string>
     <string name="adb_paired_devices_title" msgid="5268997341526217362">"อุปกรณ์ที่จับคู่"</string>
@@ -263,9 +285,9 @@
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"adb, แก้ไขข้อบกพร่อง, พัฒนา"</string>
     <string name="bugreport_in_power" msgid="8664089072534638709">"ทางลัดรายงานข้อบกพร่อง"</string>
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"แสดงปุ่มในเมนูเปิด/ปิดสำหรับการใช้รายงานข้อบกพร่อง"</string>
-    <string name="keep_screen_on" msgid="1187161672348797558">"เปิดหน้าจอค้าง"</string>
+    <string name="keep_screen_on" msgid="1187161672348797558">"เปิดหน้าจอค้างไว้"</string>
     <string name="keep_screen_on_summary" msgid="1510731514101925829">"หน้าจอจะไม่เข้าสู่โหมดสลีปขณะชาร์จ"</string>
-    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"เปิดใช้งานบันทึก HCI Snoop ของบลูทูธ"</string>
+    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"เปิดใช้บันทึก HCI Snoop ของบลูทูธ"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"บันทึกแพ็กเก็ตบลูทูธ (ปิด-เปิดบลูทูธหลังจากเปลี่ยนการตั้งค่านี้)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"การปลดล็อก OEM"</string>
     <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"อนุญาตให้ปลดล็อกตัวโหลดการเปิดเครื่อง"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"ถือว่าแอปรองรับรูปแบบสมัยใหม่"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"แสดงการแจ้งเตือนการแปลง"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ปิดใช้แคชสำหรับการแปลง"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"การตั้งค่า Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Force L3 สำรอง"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"เลือกเพื่อเปิดใช้ Force L3 สำรอง"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"บริการที่ทำงานอยู่"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"ดูและควบคุมบริการที่ทำงานอยู่"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"การใช้งาน WebView"</string>
@@ -518,7 +537,7 @@
     <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"ใช้ภาษาของระบบ"</string>
     <string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"ไม่สามารถเปิดการตั้งค่าสำหรับ <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
     <string name="ime_security_warning" msgid="6547562217880551450">"วิธีการป้อนข้อมูลนี้อาจเก็บข้อความทั้งหมดที่คุณพิมพ์ รวมถึงข้อมูลส่วนบุคคล เช่น รหัสผ่านและหมายเลขบัตรเครดิต โดยมาจากแอปพลิเคชัน <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g> ใช้วิธีการป้อนข้อมูลนี้หรือไม่"</string>
-    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"หมายเหตุ: หลังจากเริ่มต้นใหม่ แอปนี้จะไม่สามารถเริ่มการทำงานได้จนกว่าคุณจะปลดล็อกโทรศัพท์"</string>
+    <string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"หมายเหตุ: หลังจากรีบูต แอปนี้จะไม่สามารถเริ่มการทำงานได้จนกว่าคุณจะปลดล็อกโทรศัพท์"</string>
     <string name="ims_reg_title" msgid="8197592958123671062">"สถานะการลงทะเบียน IMS"</string>
     <string name="ims_reg_status_registered" msgid="884916398194885457">"ลงทะเบียนแล้ว"</string>
     <string name="ims_reg_status_not_registered" msgid="2989287366045704694">"ไม่ได้ลงทะเบียน"</string>
@@ -555,7 +574,7 @@
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"แท็บเล็ตเครื่องนี้"</string>
     <!-- no translation found for media_transfer_this_device_name_tv (5285685336836896535) -->
     <skip />
-    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"แท่นวางลำโพง"</string>
+    <string name="media_transfer_dock_speaker_device_name" msgid="2856219597113881950">"แท่นชาร์จที่มีลำโพง"</string>
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"อุปกรณ์ภายนอก"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"อุปกรณ์ที่เชื่อมต่อ"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"โทรศัพท์เครื่องนี้"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"ระบบจะลบกิจกรรมทั้งหมดเมื่อออก"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"คุณสามารถบันทึกหรือลบกิจกรรมเมื่อออก"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"รีเซ็ตเพื่อลบกิจกรรมของเซสชันตอนนี้เลย หรือจะ​บันทึกหรือลบกิจกรรมเมื่อออกก็ได้"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ถ่ายรูป"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"เลือกรูปภาพ"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"เลือกรูปภาพ"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"ใช้ความพยายามหลายครั้งเกินไป ระบบจะลบข้อมูลในอุปกรณ์เครื่องนี้"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"ใช้ความพยายามหลายครั้งเกินไป ระบบจะลบผู้ใช้รายนี้"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ยกเลิกการเชื่อมต่ออีเทอร์เน็ตแล้ว"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"อีเทอร์เน็ต"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"ไม่มีการโทร"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"เลือกรูปโปรไฟล์"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"ไอคอนผู้ใช้เริ่มต้น"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"แป้นพิมพ์จริง"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"เลือกรูปแบบแป้นพิมพ์"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ค่าเริ่มต้น"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index e609b7d..c34588d 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Aktibo, kaliwa lang"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Aktibo, kanan lang"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Aktibo, kaliwa at kanan"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Audio ng media"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Mga tawag sa telepono"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Paglilipat ng file"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Ipagpalagay na sinusuportahan ng mga app ang mga modernong format"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Ipakita ang mga notification sa pag-transcode"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"I-disable ang cache ng pag-transcode"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Mga setting ng Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Puwersahin ang L3 fallback"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Piliin para puwersahin ang L3 fallback"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Mga tumatakbong serbisyo"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Tingnan at kontrolin ang mga kasalukuyang tumatakbong serbisyo"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Pagpapatupad sa WebView"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Made-delete ang lahat ng aktibidad kapag umalis"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Puwede mong i-save o i-delete ang aktibidad pagkaalis"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Mag-reset para mag-delete ng aktibidad ng session ngayon, o puwede kang mag-save o mag-delete ng aktibidad pagkaalis"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Kumuha ng larawan"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Pumili ng larawan"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Pumili ng larawan"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Masyadong maraming maling pagsubok. Made-delete ang data ng device na ito."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Masyadong maraming maling pagsubok. Made-delete ang user na ito."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Nadiskonekta ang Ethernet."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Hindi makakatawag."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Pumili ng larawan sa profile"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Icon ng default na user"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Pisikal na keyboard"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Pumili ng layout ng keyboard"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Default"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index c41ff1c..4315241 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Yalnızca sol tarafta etkin"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Yalnızca sağ tarafta etkin"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Sol ve sağ tarafta etkin"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Medya sesi"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefon aramaları"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Dosya aktarımı"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Uygulamaların modern biçimleri desteklediğini varsay"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Kod dönüştürme bildirimlerini göster"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Kod dönüştürme önbelleğini devre dışı bırak"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine ayarları"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"L3 yedeğiniz zorunlu tut"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"L3 yedeğini zorunlu tutmak için seçin"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Çalışan hizmetler"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Şu anda çalışan hizmetleri görüntüle ve denetle"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Web Görünümü kullanımı"</string>
@@ -484,7 +503,7 @@
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Hızlı şarj oluyor"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"Yavaş şarj oluyor"</string>
     <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"Kablosuz şarj oluyor"</string>
-    <string name="battery_info_status_charging_dock" msgid="8573274094093364791">"Şarj Etme"</string>
+    <string name="battery_info_status_charging_dock" msgid="8573274094093364791">"Şarj oluyor"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"Şarj olmuyor"</string>
     <string name="battery_info_status_not_charging" msgid="1103084691314264664">"Bağlı ancak şarj olmuyor"</string>
     <string name="battery_info_status_full" msgid="1339002294876531312">"Şarj oldu"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Çıkış yapıldığında tüm etkinlikler silinir"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Etkinliklerinizi çıkarken kaydedebilir veya silebilirsiniz"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Oturum etkinliklerini silmek için sıfırlayabilir ya da çıkarken kaydedebilir veya silebilirsiniz"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Fotoğraf çek"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Resim seç"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Fotoğraf seç"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Çok fazla sayıda hatalı deneme yapıldı. Bu cihazın verileri silinecek."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Çok fazla sayıda hatalı deneme yapıldı. Bu kullanıcı silinecek."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet bağlantısı kesildi."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Çağrı yok."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Profil fotoğrafı seçin"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Varsayılan kullanıcı simgesi"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Fiziksel klavye"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Klavye düzenini seçin"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Varsayılan"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index d8cb368..ac9edc5 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -106,7 +106,29 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Активовано, лише лівий"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Активовано, лише правий"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Активовано, лівий і правий"</string>
-    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Звук медіа-файлів"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
+    <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Звук медіафайлів"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Телефонні дзвінки"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Передавання файлів"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Пристрій введення"</string>
@@ -265,7 +287,7 @@
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"Показувати в меню живлення кнопку створення звіту про помилки"</string>
     <string name="keep_screen_on" msgid="1187161672348797558">"Залишати активним"</string>
     <string name="keep_screen_on_summary" msgid="1510731514101925829">"Екран не засинатиме під час заряджання"</string>
-    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Журнал інтерфейсу Bluetooth"</string>
+    <string name="bt_hci_snoop_log" msgid="7291287955649081448">"Увімкнути журнал перехоплення даних інтерфейсу Bluetooth"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"Отримання пакетів Bluetooth. (Змінивши це налаштування, увімкніть Bluetooth.)"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"Розблокування виробником"</string>
     <string name="oem_unlock_enable_summary" msgid="5857388174390953829">"Дозволити розблокування завантажувача"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Вважати, що додатки підтримують сучасні формати"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Показувати сповіщення про перекодування"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Вимкнути кеш перекодування"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Налаштування Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Примусово повернутися на рівень безпеки 3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Виберіть, щоб примусово повернутися на рівень безпеки 3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Запущені сервіси"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Переглянути й налаштувати запущені сервіси"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Застосування WebView"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Під час виходу буде видалено історію всіх дій"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Під час виходу можна зберегти або видалити ваші дії"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Можна скинути історію сеансу просто зараз або видалити чи зберегти її під час виходу."</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Зробити фотографію"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Вибрати зображення"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Вибрати фотографію"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Забагато невдалих спроб. Дані на цьому пристрої буде видалено."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Забагато невдалих спроб. Цього користувача буде видалено."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Ethernet відключено."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Виклики недоступні."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Виберіть зображення профілю"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Значок користувача за умовчанням"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Фізична клавіатура"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Вибрати розкладку клавіатури"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"За умовчанням"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 7ba7b8b..d2fc32a 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"فعال، صرف بائیں طرف"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"فعال، صرف دائیں طرف"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"فعال، صرف بائیں اور دائیں طرف"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"میڈيا آڈیو"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"فون کالز"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"فائل کی منتقلی"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"فرض کریں کہ ایپس جدید فارمیٹس کو سپورٹ کرتی ہیں"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"ٹرانسکوڈنگ اطلاعات دکھائیں"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"ٹرانسکوڈنگ کیش غیر فعال کریں"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"‏Widevine کی ترتیبات"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Force L3 fallback"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"‏Force L3 fallback منتخب کریں"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"چل رہی سروسز"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"فی الحال چل رہی سروسز دیکھیں اور انہیں کنٹرول کریں"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"‏WebView کا نفاذ"</string>
@@ -619,7 +638,7 @@
     <string name="add_user_failed" msgid="4809887794313944872">"نیا صارف بنانے میں ناکام"</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"نیا مہمان بنانے میں ناکام"</string>
     <string name="user_nickname" msgid="262624187455825083">"عرفی نام"</string>
-    <string name="edit_user_info_message" msgid="6677556031419002895">"آپ کی جانب سے منتخب کردہ نام اور تصویر، اس آلے کے استعمال کرنے والے ہر شخص کو نظر آئے گا۔"</string>
+    <string name="edit_user_info_message" msgid="6677556031419002895">"آپ کی جانب سے منتخب کردہ نام اور تصویر، اس آلے کے استعمال کرنے والے ہر شخص کو نظر آئے گی۔"</string>
     <string name="user_add_user" msgid="7876449291500212468">"صارف کو شامل کریں"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"مہمان کو شامل کریں"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"مہمان کو ہٹائیں"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"باہر نکلنے پر تمام سرگرمیاں حذف کر دی جائیں گی"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"باہر نکلنے پر آپ اپنی سرگرمی کو محفوظ یا حذف کر سکتے ہیں"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"سیشن کی سرگرمی کو ابھی حذف کرنے کے لیے ری سیٹ کریں، یا باہر نکلنے پر آپ اپنی سرگرمی کو محفوظ یا حذف کر سکتے ہیں"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"ایک تصویر لیں"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"ایک تصویر منتخب کریں"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"تصویر منتخب کریں"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"بہت زیادہ غلط کوششیں۔ اس آلے کا ڈیٹا حذف کر دیا جائے گا۔"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"بہت زیادہ غلط کوششیں۔ اس صارف کو حذف کر دیا جائے گا۔"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"ایتھرنیٹ منقطع ہے۔"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"ایتھرنیٹ۔"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"کوئی کالنگ نہیں ہے۔"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"پروفائل کی تصویر منتخب کریں"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"ڈیفالٹ صارف کا آئیکن"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"فزیکل کی بورڈ"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"کی بورڈ لے آؤٹ منتخب کریں"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"ڈیفالٹ"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 9c37f41..3c8e249 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Faol, faqat chap"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Faol, faqat oʻng"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Faol, chap va oʻng"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"A2DP profili"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Telefon chaqiruvlari"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Fayl uzatish"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Ilovalarda zamonaviy kodlash formatlari ishlaydi deb hisoblash"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Transkripsiya bildirishnomalarini chiqarish"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Transkripsiya keshini faolsizlantirish"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine sozlamalari"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Majburiy L3 zaxirasi"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Majburiy L3 zaxirasini tanlash"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Ishlab turgan ilovalar"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Ishlab turgan ilovalarni ko‘rish va boshqarish"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView ta’minotchisi"</string>
@@ -609,7 +628,7 @@
     <string name="user_add_user_type_title" msgid="551279664052914497">"Qo‘shish"</string>
     <string name="user_new_user_name" msgid="60979820612818840">"Yangi foydalanuvchi"</string>
     <string name="user_new_profile_name" msgid="2405500423304678841">"Yangi profil"</string>
-    <string name="user_info_settings_title" msgid="6351390762733279907">"Foydalanuvchi ma‘lumoti"</string>
+    <string name="user_info_settings_title" msgid="6351390762733279907">"Foydalanuvchi haqida"</string>
     <string name="profile_info_settings_title" msgid="105699672534365099">"Profil haqida axborot"</string>
     <string name="user_need_lock_message" msgid="4311424336209509301">"Cheklangan profil yaratish uchun, shaxsiy ilovlar va ma‘lumotlarni himoyalash maqsadida avval ekran qulfini yaratish lozim."</string>
     <string name="user_set_lock_button" msgid="1427128184982594856">"Qulf o‘rnatish"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Chiqishda faolliklar tarixi tozalab tashlanadi"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Chiqish vaqtida faoliyatni saqlash yoki tozalash mumkin"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Faoliyat hozir tozalanib tiklanishi yoki chiqish vaqtida saqlanishi yoki tozalanishi mumkin"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Suratga olish"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Rasm tanlash"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Surat tanlash"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Juda koʻp marta muvaffaqiyatsiz urinishlar amalga oshirildi. Bu qurilmadagi maʼlumotlar o‘chirib tashlanadi."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Juda koʻp marta muvaffaqiyatsiz urindingiz. Bu foydalanuvchi oʻchirib tashlanadi."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Qurilma Ethernet tarmog‘idan uzildi."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Chaqiruv imkonsiz."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Profil rasmini tanlash"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Foydalanuvchining standart belgisi"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Tashqi klaviatura"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Klaviatura sxemasini tanlang"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Asosiy"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 9a3663a..b3d70cc 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -106,13 +106,35 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Đang hoạt động, chỉ tai bên trái"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Đang hoạt động, chỉ tai phải"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Đang hoạt động, cả tai phải và tai trái"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Âm thanh nội dung nghe nhìn"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Cuộc gọi điện thoại"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Chuyển tệp"</string>
     <string name="bluetooth_profile_hid" msgid="2969922922664315866">"Thiết bị đầu vào"</string>
     <string name="bluetooth_profile_pan" msgid="1006235139308318188">"Truy cập Internet"</string>
-    <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Cho truy cập danh bạ và nhật ký cuộc gọi"</string>
-    <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Thông tin được dùng cho tính năng thông báo cuộc gọi, v.v."</string>
+    <string name="bluetooth_profile_pbap" msgid="2103406516858653017">"Cho phép truy cập danh bạ và nhật ký cuộc gọi"</string>
+    <string name="bluetooth_profile_pbap_summary" msgid="402819589201138227">"Thông tin sẽ được dùng cho tính năng thông báo cuộc gọi, v.v."</string>
     <string name="bluetooth_profile_pan_nap" msgid="7871974753822470050">"Chia sẻ kết nối internet"</string>
     <string name="bluetooth_profile_map" msgid="8907204701162107271">"Tin nhắn văn bản"</string>
     <string name="bluetooth_profile_sap" msgid="8304170950447934386">"Truy cập SIM"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Giả định rằng các ứng dụng hỗ trợ định dạng hiện đại"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Hiện thông báo chuyển mã"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Vô hiệu hóa bộ nhớ đệm dùng để chuyển mã"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Cài đặt Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Buộc sử dụng mức bảo mật L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Chọn để buộc sử dụng mức bảo mật L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Các dịch vụ đang chạy"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Xem và kiểm soát các dịch vụ đang chạy"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Triển khai WebView"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Mọi hoạt động sẽ bị xoá khi thoát"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Bạn có thể lưu hoặc xoá hoạt động của mình khi thoát"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Đặt lại để xoá hoạt động trong phiên ngay bây giờ, hoặc bạn có thể lưu hoặc xoá hoạt động khi thoát"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Chụp ảnh"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Chọn một hình ảnh"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Chọn ảnh"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Quá nhiều lần thử không chính xác. Dữ liệu trên thiết bị này sẽ bị xoá."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Quá nhiều lần thử không chính xác. Người dùng này sẽ bị xoá."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"Đã ngắt kết nối Ethernet."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Không thể gọi điện."</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Chọn một ảnh hồ sơ"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Biểu tượng người dùng mặc định"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Bàn phím thực"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Chọn bố cục bàn phím"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Mặc định"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index b919972..6a9a18c 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"使用中,仅左耳助听器"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"使用中,仅右耳助听器"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"使用中,左右耳助听器"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"媒体音频"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"通话"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"文件传输"</string>
@@ -301,7 +323,7 @@
     <string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"触发蓝牙音频 LDAC\n编解码器选择:播放质量"</string>
     <string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"正在流式传输:<xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
     <string name="select_private_dns_configuration_title" msgid="7887550926056143018">"专用 DNS"</string>
-    <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"选择私人 DNS 模式"</string>
+    <string name="select_private_dns_configuration_dialog_title" msgid="3731422918335951912">"选择专用 DNS 模式"</string>
     <string name="private_dns_mode_off" msgid="7065962499349997041">"已关闭"</string>
     <string name="private_dns_mode_opportunistic" msgid="1947864819060442354">"自动"</string>
     <string name="private_dns_mode_provider" msgid="3619040641762557028">"专用 DNS 提供商主机名"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"假设应用支持现代格式"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"显示转码通知"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"停用转码缓存"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine 设置"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"强制执行 L3 回退"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"选择即可强制执行 L3 回退"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"正在运行的服务"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"查看和控制当前正在运行的服务"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView 实现"</string>
@@ -596,8 +615,8 @@
     <string name="user_add_user_item_title" msgid="2394272381086965029">"用户"</string>
     <string name="user_add_profile_item_title" msgid="3111051717414643029">"受限个人资料"</string>
     <string name="user_add_user_title" msgid="5457079143694924885">"要添加新用户吗?"</string>
-    <string name="user_add_user_message_long" msgid="1527434966294733380">"创建新用户后,您就能够与其他人共用此设备。每位用户都有自己的专属空间,而且在自己的个人空间内还可以自行安装自己想要的应用、设置壁纸等。此外,用户还可以调整会影响所有用户的设备设置(例如 WLAN 设置)。\n\n当您添加新用户后,该用户需要自行设置个人空间。\n\n任何用户都可以为所有其他用户更新应用。无障碍功能设置和服务可能无法转移给新用户。"</string>
-    <string name="user_add_user_message_short" msgid="3295959985795716166">"当您添加新用户后,该用户需要自行设置个人空间。\n\n任何用户都可以为所有其他用户更新应用。"</string>
+    <string name="user_add_user_message_long" msgid="1527434966294733380">"创建新用户后,您就能够与其他人共用此设备。每位用户都有自己的专属空间,而且在自己的个人空间内还可以自行安装自己想要的应用、设置壁纸等。此外,用户还可以调整会影响所有用户的设备设置(例如 WLAN 设置)。\n\n新添加的用户需要自行设置个人空间。\n\n任何用户都可为所有其他用户更新应用。无障碍功能设置和服务可能无法转移给新用户。"</string>
+    <string name="user_add_user_message_short" msgid="3295959985795716166">"新添加的用户需要自行设置个人空间。\n\n任何用户都可为所有其他用户更新应用。"</string>
     <string name="user_grant_admin_title" msgid="5157031020083343984">"将此用户设为管理员?"</string>
     <string name="user_grant_admin_message" msgid="1673791931033486709">"管理员拥有其他用户没有的特殊权限。管理员可以管理所有用户、更新或重置此设备、修改设置、查看所有已安装的应用,以及授予或撤消其他用户的管理员权限。"</string>
     <string name="user_grant_admin_button" msgid="5441486731331725756">"设为管理员"</string>
@@ -643,11 +662,9 @@
     <string name="guest_exit_button" msgid="5774985819191803960">"退出访客模式"</string>
     <string name="guest_reset_button" msgid="2515069346223503479">"重置访客会话"</string>
     <string name="guest_exit_quick_settings_button" msgid="1912362095913765471">"退出访客模式"</string>
-    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"退出时所有活动都将被删除"</string>
+    <string name="guest_notification_ephemeral" msgid="7263252466950923871">"退出时所有活动记录都将被删除"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"您可以在退出时保存或删除您的活动"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"请立即重置以删除会话活动记录;或者,您也可以在退出时保存或删除活动记录"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"拍摄照片"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"选择图片"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"选择照片"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"错误次数过多。系统将删除此设备上的数据。"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"错误次数过多。系统将删除此用户。"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"以太网已断开连接。"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"以太网。"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"不启用通话。"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"选择个人资料照片"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"默认用户图标"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"实体键盘"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"选择键盘布局"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"默认"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 340c7a4..ecdfa62 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"使用中,僅左耳"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"使用中,僅右耳"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"使用中,左右耳"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"媒體音效"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"通話"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"檔案傳輸"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"假設應用程式支援新型格式"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"顯示轉碼通知"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"停用轉碼快取"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine 設定"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"強制退回 L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"選取即可強制退回 L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"執行中的服務"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"查看並控制目前正在執行中的服務"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView 設置"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"結束時將會刪除所有活動"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"你可以在結束時儲存或刪除活動"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"重設可立即刪除工作階段活動,或者你可以在結束時儲存或刪除活動"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"拍照"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"選擇圖片"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"揀相"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"錯誤次數太多,系統將會刪除此裝置上的資料。"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"錯誤次數太多,系統將會刪除此使用者。"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"以太網連接中斷。"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"以太網絡。"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"不啟用通話。"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"選擇個人檔案相片"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"預設使用者圖示"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"實體鍵盤"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"選擇鍵盤配置"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"預設"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index f7414ef..99fe41e 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"使用中,僅左耳"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"使用中,僅右耳"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"使用中,左右耳"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"媒體音訊"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"通話"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"檔案傳輸"</string>
@@ -263,8 +285,8 @@
     <string name="keywords_adb_wireless" msgid="6507505581882171240">"ADB, 偵錯, 開發"</string>
     <string name="bugreport_in_power" msgid="8664089072534638709">"錯誤回報捷徑"</string>
     <string name="bugreport_in_power_summary" msgid="1885529649381831775">"在電源選單中顯示取得錯誤報告的按鈕"</string>
-    <string name="keep_screen_on" msgid="1187161672348797558">"螢幕不休眠"</string>
-    <string name="keep_screen_on_summary" msgid="1510731514101925829">"充電時螢幕不會進入休眠"</string>
+    <string name="keep_screen_on" msgid="1187161672348797558">"不鎖定螢幕"</string>
+    <string name="keep_screen_on_summary" msgid="1510731514101925829">"充電時螢幕不會鎖定"</string>
     <string name="bt_hci_snoop_log" msgid="7291287955649081448">"啟用藍牙 HCI 窺探記錄"</string>
     <string name="bt_hci_snoop_log_summary" msgid="6808538971394092284">"擷取藍牙數據包 (變更這項設定後請切換藍牙)。"</string>
     <string name="oem_unlock_enable" msgid="5334869171871566731">"OEM 解鎖"</string>
@@ -411,7 +433,7 @@
     <string name="enable_freeform_support" msgid="7599125687603914253">"啟用自由形式視窗"</string>
     <string name="enable_freeform_support_summary" msgid="1822862728719276331">"啟用實驗版自由形式視窗的支援功能。"</string>
     <string name="local_backup_password_title" msgid="4631017948933578709">"電腦備份密碼"</string>
-    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"目前尚未設定密碼來保護完整的備份檔案 (透過電腦備份的檔案)"</string>
+    <string name="local_backup_password_summary_none" msgid="7646898032616361714">"尚未設定密碼保護電腦的完整備份"</string>
     <string name="local_backup_password_summary_change" msgid="1707357670383995567">"輕觸即可變更或移除電腦完整備份的密碼"</string>
     <string name="local_backup_password_toast_success" msgid="4891666204428091604">"已設定新備份密碼"</string>
     <string name="local_backup_password_toast_confirmation_mismatch" msgid="2994718182129097733">"新密碼與確認密碼不符。"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"假設應用程式支援新格式"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"顯示轉碼通知"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"停用轉碼快取"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Widevine 設定"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"強制退回 L3"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"選取即可強制退回 L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"正在運作的服務"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"查看並管理目前正在執行的服務"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"WebView 實作"</string>
@@ -483,7 +502,7 @@
     <string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string>
     <string name="battery_info_status_charging_fast" msgid="8027559755902954885">"快速充電中"</string>
     <string name="battery_info_status_charging_slow" msgid="3190803837168962319">"慢速充電中"</string>
-    <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"正在進行無線充電"</string>
+    <string name="battery_info_status_charging_wireless" msgid="8924722966861282197">"正在無線充電"</string>
     <string name="battery_info_status_charging_dock" msgid="8573274094093364791">"充電中"</string>
     <string name="battery_info_status_discharging" msgid="6962689305413556485">"非充電中"</string>
     <string name="battery_info_status_not_charging" msgid="1103084691314264664">"已連接,但未充電"</string>
@@ -491,7 +510,7 @@
     <string name="battery_info_status_full_charged" msgid="3536054261505567948">"充電完成"</string>
     <string name="battery_info_status_charging_on_hold" msgid="6364355145521694438">"目前暫停充電"</string>
     <string name="disabled_by_admin_summary_text" msgid="5343911767402923057">"已由管理員停用"</string>
-    <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"由限制設定控管"</string>
+    <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"由受限制的設定控管"</string>
     <string name="disabled" msgid="8017887509554714950">"已停用"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"允許"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"不允許"</string>
@@ -619,7 +638,7 @@
     <string name="add_user_failed" msgid="4809887794313944872">"無法建立新的使用者"</string>
     <string name="add_guest_failed" msgid="8074548434469843443">"無法建立新訪客"</string>
     <string name="user_nickname" msgid="262624187455825083">"暱稱"</string>
-    <string name="edit_user_info_message" msgid="6677556031419002895">"使用這部裝置的所有人都能看到你選擇的名稱和相片。"</string>
+    <string name="edit_user_info_message" msgid="6677556031419002895">"這部裝置的所有使用者都能看到你選擇的名稱和相片。"</string>
     <string name="user_add_user" msgid="7876449291500212468">"新增使用者"</string>
     <string name="guest_new_guest" msgid="3482026122932643557">"新增訪客"</string>
     <string name="guest_exit_guest" msgid="5908239569510734136">"移除訪客"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"結束時將刪除所有活動"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"你可以在結束時儲存或刪除活動"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"重設即可立即刪除工作階段活動,你也可以在結束時儲存或刪除活動"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"拍照"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"選擇圖片"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"選取相片"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"錯誤次數過多,系統將刪除這部裝置中的資料。"</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"錯誤次數過多,系統將刪除這位使用者。"</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"未連上乙太網路。"</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"乙太網路。"</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"不顯示在螢幕上。"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"選擇個人資料相片"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"預設使用者圖示"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"實體鍵盤"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"選擇鍵盤配置"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"預設"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 8364eef..6f06e1f 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -106,6 +106,28 @@
     <string name="bluetooth_hearing_aid_left_active" msgid="7084887715570971441">"Iyasebenza, ngakwesokunxele kuphela"</string>
     <string name="bluetooth_hearing_aid_right_active" msgid="8574683234077567230">"Iyasebenza, ngakwesokudla kuphela"</string>
     <string name="bluetooth_hearing_aid_left_and_right_active" msgid="407704460573163973">"Iyasebenza, ngakwesokunxele nakwesokudla"</string>
+    <!-- no translation found for bluetooth_active_media_only_battery_level (1164678961213251365) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_battery_level_untethered (1345174295097854560) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_lea_support (8580950145907305436) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_lea_support (8534816721698743015) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_left_lea_support (6605320955858788855) -->
+    <skip />
+    <!-- no translation found for bluetooth_battery_level_untethered_right_lea_support (5717356160322149355) -->
+    <skip />
+    <!-- no translation found for bluetooth_active_media_only_no_battery_level (71106861912593126) -->
+    <skip />
+    <!-- no translation found for bluetooth_saved_device_lea_support (7231323139968285768) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_active (1632152540901488645) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_right_active (3854140683042617230) -->
+    <skip />
+    <!-- no translation found for bluetooth_hearing_aid_media_only_left_and_right_active (1299913413062528417) -->
+    <skip />
     <string name="bluetooth_profile_a2dp" msgid="4632426382762851724">"Umsindo wemidiya"</string>
     <string name="bluetooth_profile_headset" msgid="5395952236133499331">"Amakholi efoni"</string>
     <string name="bluetooth_profile_opp" msgid="6692618568149493430">"Dlulisa ifayela"</string>
@@ -437,9 +459,6 @@
     <string name="transcode_default" msgid="3784803084573509491">"Kuthathe njengokungathi izinhlelo zokusebenza zisekela amafomethi esimanje"</string>
     <string name="transcode_notification" msgid="5560515979793436168">"Bonisa izaziso zokudlulisela ikhodi"</string>
     <string name="transcode_disable_cache" msgid="3160069309377467045">"Khubaza inqolobane yokudlulisela ikhodi"</string>
-    <string name="widevine_settings_title" msgid="4023329801172572917">"Amasethingi e-Widevine"</string>
-    <string name="force_l3_fallback_title" msgid="4987972688770202547">"Force L3 fallback"</string>
-    <string name="force_l3_fallback_summary" msgid="3080790841069996016">"Khetha ukuphoqa isihibe sika-L3"</string>
     <string name="runningservices_settings_title" msgid="6460099290493086515">"Amasevisi asebenzayo"</string>
     <string name="runningservices_settings_summary" msgid="1046080643262665743">"Buka futhi ulawule amasevisi  asebenzayo okwamanje"</string>
     <string name="select_webview_provider_title" msgid="3917815648099445503">"Ukufakwa ke-WebView"</string>
@@ -646,8 +665,6 @@
     <string name="guest_notification_ephemeral" msgid="7263252466950923871">"Wonke umsebenzi uzosulwa lapho uphuma"</string>
     <string name="guest_notification_non_ephemeral" msgid="6843799963012259330">"Ungalondoloza noma usule umsebenzi wakho lapho uphuma"</string>
     <string name="guest_notification_non_ephemeral_non_first_login" msgid="8009307983766934876">"Setha kabusha ukuze usule umsebenzi wesikhathi manje, noma ungalondoloza noma usule umsebenzi lapho uphuma"</string>
-    <string name="user_image_take_photo" msgid="467512954561638530">"Thatha isithombe"</string>
-    <string name="user_image_choose_photo" msgid="1363820919146782908">"Khetha isithombe"</string>
     <string name="user_image_photo_selector" msgid="433658323306627093">"Khetha isithombe"</string>
     <string name="failed_attempts_now_wiping_device" msgid="4016329172216428897">"Imizamo eminingi kakhulu engalungile. Le datha yedivayisi izosulwa."</string>
     <string name="failed_attempts_now_wiping_user" msgid="469060411789668050">"Imizamo eminingi kakhulu engalungile. Lo msebenzisi uzosulwa."</string>
@@ -687,8 +704,6 @@
     <string name="accessibility_ethernet_disconnected" msgid="2832501530856497489">"I-Ethernet inqanyuliwe."</string>
     <string name="accessibility_ethernet_connected" msgid="6175942685957461563">"I-Ethernet."</string>
     <string name="accessibility_no_calling" msgid="3540827068323895748">"Akukho ukwenza ikholi"</string>
-    <string name="avatar_picker_title" msgid="8492884172713170652">"Khetha isithombe sephrofayela"</string>
-    <string name="default_user_icon_description" msgid="6554047177298972638">"Isithonjana somsebenzisi sokuzenzakalelayo"</string>
     <string name="physical_keyboard_title" msgid="4811935435315835220">"Ikhibhodi ephathekayo"</string>
     <string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Khetha isendlalelo sekhibhodi"</string>
     <string name="keyboard_layout_default_label" msgid="1997292217218546957">"Zenzekela"</string>
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index 1b29e83..5a4d3ce 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -639,15 +639,6 @@
         <item>disabled</item>
     </array>
 
-    <!-- Images offered as options in the avatar picker. If populated, the avatar_image_descriptions
-         array must also be populated with a content description for each image. -->
-    <array name="avatar_images"/>
-
-    <!-- Content descriptions for each of the images in the avatar_images array. When overlaid
-         these values should be translated, but this empty array must not be translated or it may
-         replace the real descriptions with an empty array. -->
-    <string-array name="avatar_image_descriptions" translatable="false"/>
-
     <!-- NOTE: if you change this, you must also add the corresponding scale key and lookup table to
      frameworks/base/core/java/android/content/res/FontScaleConverterFactory.java -->
     <string-array name="entryvalues_font_size" translatable="false">
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index 07854bd..2bd4d02 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -84,13 +84,6 @@
     <dimen name="add_a_photo_icon_size_in_user_info_dialog">32dp</dimen>
     <dimen name="user_name_height_in_user_info_dialog">48sp</dimen>
 
-    <integer name="avatar_picker_columns">3</integer>
-    <dimen name="avatar_size_in_picker">96dp</dimen>
-    <dimen name="avatar_picker_padding">6dp</dimen>
-    <dimen name="avatar_picker_margin">2dp</dimen>
-
-    <dimen name="avatar_picker_icon_inset">25dp</dimen>
-
     <!-- Minimum increment between density scales. -->
     <fraction name="display_density_min_scale_interval">9%</fraction>
     <!-- Maximum density scale. The actual scale used depends on the device. -->
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 69e4bd7..7e6b004 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -222,6 +222,30 @@
     <!-- Connected device settings. Message when the left-side and right-side hearing aids device are active. [CHAR LIMIT=NONE] -->
     <string name="bluetooth_hearing_aid_left_and_right_active">Active, left and right</string>
 
+    <!-- Connected devices settings. Message when Bluetooth is connected and active for media only, showing remote device status and battery level. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_active_media_only_battery_level">Active (media only), <xliff:g id="battery_level_as_percentage">%1$s</xliff:g> battery</string>
+    <!-- Connected devices settings. Message when Bluetooth is connected and active for media only, showing remote device status and battery level for untethered headset. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_active_media_only_battery_level_untethered">Active (media only), L: <xliff:g id="battery_level_as_percentage" example="25%">%1$s</xliff:g> battery, R: <xliff:g id="battery_level_as_percentage" example="25%">%2$s</xliff:g> battery</string>
+    <!-- Connected devices settings. Message when Bluetooth is connected but not in use, showing remote device battery level, supports audio sharing. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_battery_level_lea_support">Connected (supports audio sharing), <xliff:g id="battery_level_as_percentage">%1$s</xliff:g> battery</string>
+    <!-- Connected devices settings. Message when Bluetooth is connected but not in use, showing remote device battery level for untethered headset, supports audio sharing. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_battery_level_untethered_lea_support">Connected (supports audio sharing), L: <xliff:g id="battery_level_as_percentage" example="25%">%1$s</xliff:g> battery, R: <xliff:g id="battery_level_as_percentage" example="25%">%2$s</xliff:g> battery</string>
+    <!-- Connected devices settings. Message when Bluetooth is connected but not in use, showing remote device battery level for the left part of the untethered headset, supports audio sharing. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_battery_level_untethered_left_lea_support">Connected (supports audio sharing), left <xliff:g id="battery_level_as_percentage" example="25%">%1$s</xliff:g></string>
+    <!-- Connected devices settings. Message when Bluetooth is connected but not in use, showing remote device battery level for the right part of the untethered headset, supports audio sharing. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_battery_level_untethered_right_lea_support">Connected (supports audio sharing), right <xliff:g id="battery_level_as_percentage" example="25%">%1$s</xliff:g></string>
+    <!-- Connected devices settings. Message when Bluetooth is connected and active for media only but no battery information, showing remote device status. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_active_media_only_no_battery_level">Active (media only)</string>
+    <!-- Connected devices settings. Message shown when bluetooth device is disconnected but is a known, previously connected device, supports audio sharing [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_saved_device_lea_support">Supports audio sharing</string>
+
+    <!-- Connected device settings. Message when the left-side hearing aid device is active for media only. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_hearing_aid_media_only_left_active">Active (media only), left only</string>
+    <!-- Connected device settings. Message when the right-side hearing aid device is active for media only. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_hearing_aid_media_only_right_active">Active (media only), right only</string>
+    <!-- Connected device settings. Message when the left-side and right-side hearing aids device are active for media only. [CHAR LIMIT=NONE] -->
+    <string name="bluetooth_hearing_aid_media_only_left_and_right_active">Active (media only), left and right</string>
+
     <!-- Bluetooth settings.  The user-visible string that is used whenever referring to the A2DP profile. -->
     <string name="bluetooth_profile_a2dp">Media audio</string>
     <!-- Bluetooth settings.  The user-visible string that is used whenever referring to the headset or handsfree profile. -->
@@ -1540,10 +1564,6 @@
     <string name="guest_notification_non_ephemeral_non_first_login">Reset to delete session
         activity now, or you can save or delete activity on exit</string>
 
-    <!-- An option in a photo selection dialog to take a new photo [CHAR LIMIT=50] -->
-    <string name="user_image_take_photo">Take a photo</string>
-    <!-- An option in a photo selection dialog to choose a pre-existing image [CHAR LIMIT=50] -->
-    <string name="user_image_choose_photo">Choose an image</string>
     <!-- Accessibility message for the photo selector which is a button/popup with the current photo [CHAR LIMIT=50] -->
     <string name="user_image_photo_selector">Select photo</string>
 
@@ -1661,12 +1681,6 @@
     <string name="accessibility_no_calling">No calling.</string>
 
 
-    <!-- Title for a screen allowing the user to choose a profile picture. [CHAR LIMIT=NONE] -->
-    <string name="avatar_picker_title">Choose a profile picture</string>
-
-    <!-- Content description for a default user icon. [CHAR LIMIT=NONE] -->
-    <string name="default_user_icon_description">Default user icon</string>
-
     <!-- Title for the 'physical keyboard' settings screen. [CHAR LIMIT=35] -->
     <string name="physical_keyboard_title">Physical keyboard</string>
     <!-- Title for the keyboard layout preference dialog. [CHAR LIMIT=35] -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
index 20f1b17..1597a4b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
@@ -28,6 +28,7 @@
 import android.app.AppOpsManager;
 import android.app.admin.DevicePolicyManager;
 import android.app.ecm.EnhancedConfirmationManager;
+import android.app.admin.PackagePolicy;
 import android.app.role.RoleManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -57,6 +58,7 @@
 
 import com.android.internal.widget.LockPatternUtils;
 
+import java.util.HashSet;
 import java.util.List;
 
 /**
@@ -828,6 +830,29 @@
     }
 
     /**
+     * Check if there are restrictions on an application from being a Credential Manager provider.
+     *
+     * @return EnforcedAdmin Object containing the enforced admin component and admin user details,
+     * or {@code null} if the setting is not managed.
+     */
+    public static @Nullable EnforcedAdmin checkIfApplicationCanBeCredentialManagerProvider(
+            @NonNull Context context, @NonNull String packageName) {
+        final DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
+        final PackagePolicy pp = dpm.getCredentialManagerPolicy();
+
+        if (pp == null || pp.isPackageAllowed(packageName, new HashSet<>())) {
+            return null;
+        }
+
+        EnforcedAdmin admin = RestrictedLockUtilsInternal.getDeviceOwner(context);
+        if (admin != null) {
+            return admin;
+        }
+        int profileId = getManagedProfileId(context, UserHandle.USER_SYSTEM);
+        return RestrictedLockUtils.getProfileOrDeviceOwner(context, UserHandle.of(profileId));
+    }
+
+    /**
      * Static {@link LockPatternUtils} and {@link DevicePolicyManager} wrapper for testing purposes.
      * {@link LockPatternUtils} is an internal API not supported by robolectric.
      * {@link DevicePolicyManager} has a {@code getProfileParent} not yet suppored by robolectric.
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSelectorWithWidgetPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSelectorWithWidgetPreference.java
new file mode 100644
index 0000000..c52c7ea
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSelectorWithWidgetPreference.java
@@ -0,0 +1,168 @@
+/*
+ * 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.settingslib;
+
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.util.AttributeSet;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceViewHolder;
+
+import com.android.settingslib.widget.SelectorWithWidgetPreference;
+
+/**
+ * Selector with widget preference that can be disabled by a device admin using a user restriction.
+ */
+public class RestrictedSelectorWithWidgetPreference extends SelectorWithWidgetPreference {
+    private RestrictedPreferenceHelper mHelper;
+
+    /**
+     * Perform inflation from XML and apply a class-specific base style.
+     *
+     * @param context The {@link Context} this is associated with, through which it can access the
+     *     current theme, resources, {@link SharedPreferences}, etc.
+     * @param attrs The attributes of the XML tag that is inflating the preference
+     * @param defStyle An attribute in the current theme that contains a reference to a style
+     *     resource that supplies default values for the view. Can be 0 to not look for defaults.
+     */
+    public RestrictedSelectorWithWidgetPreference(
+            @NonNull Context context, @NonNull AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        mHelper = new RestrictedPreferenceHelper(context, /* preference= */ this, attrs);
+    }
+
+    /**
+     * Perform inflation from XML and apply a class-specific base style.
+     *
+     * @param context The {@link Context} this is associated with, through which it can access the
+     *     current theme, resources, {@link SharedPreferences}, etc.
+     * @param attrs The attributes of the XML tag that is inflating the preference
+     */
+    public RestrictedSelectorWithWidgetPreference(
+            @NonNull Context context, @NonNull AttributeSet attrs) {
+        super(context, attrs);
+        mHelper = new RestrictedPreferenceHelper(context, /* preference= */ this, attrs);
+    }
+
+    /**
+     * Constructor to create a preference, which will display with a checkbox style.
+     *
+     * @param context The {@link Context} this is associated with.
+     * @param isCheckbox Whether this preference should display as a checkbox.
+     */
+    public RestrictedSelectorWithWidgetPreference(@NonNull Context context, boolean isCheckbox) {
+        super(context, null);
+        mHelper =
+                new RestrictedPreferenceHelper(context, /* preference= */ this, /* attrs= */ null);
+    }
+
+    /**
+     * Constructor to create a preference.
+     *
+     * @param context The Context this is associated with.
+     */
+    public RestrictedSelectorWithWidgetPreference(@NonNull Context context) {
+        this(context, null);
+        mHelper =
+                new RestrictedPreferenceHelper(context, /* preference= */ this, /* attrs= */ null);
+    }
+
+    @Override
+    public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
+        super.onBindViewHolder(holder);
+        mHelper.onBindViewHolder(holder);
+    }
+
+    @Override
+    public void performClick() {
+        if (!mHelper.performClick()) {
+            super.performClick();
+        }
+    }
+
+    @Override
+    protected void onAttachedToHierarchy(@NonNull PreferenceManager preferenceManager) {
+        mHelper.onAttachedToHierarchy();
+        super.onAttachedToHierarchy(preferenceManager);
+    }
+
+    /**
+     * Set the user restriction and disable this preference.
+     *
+     * @param userRestriction constant from {@link android.os.UserManager}
+     */
+    public void checkRestrictionAndSetDisabled(@NonNull String userRestriction) {
+        mHelper.checkRestrictionAndSetDisabled(userRestriction, UserHandle.myUserId());
+    }
+
+    /**
+     * Set the user restriction and disable this preference for the given user.
+     *
+     * @param userRestriction constant from {@link android.os.UserManager}
+     * @param userId user to check the restriction for.
+     */
+    public void checkRestrictionAndSetDisabled(@NonNull String userRestriction, int userId) {
+        mHelper.checkRestrictionAndSetDisabled(userRestriction, userId);
+    }
+
+    /**
+     * Checks if the given setting is subject to Enhanced Confirmation Mode restrictions for this
+     * package. Marks the preference as disabled if so.
+     *
+     * @param settingIdentifier The key identifying the setting
+     * @param packageName the package to check the settingIdentifier for
+     */
+    public void checkEcmRestrictionAndSetDisabled(
+            @NonNull String settingIdentifier, @NonNull String packageName) {
+        mHelper.checkEcmRestrictionAndSetDisabled(settingIdentifier, packageName);
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        if (enabled && isDisabledByAdmin()) {
+            mHelper.setDisabledByAdmin(/* admin= */ null);
+            return;
+        }
+        super.setEnabled(enabled);
+    }
+
+    /**
+     * Check whether this preference is disabled by admin.
+     *
+     * @return true if this preference is disabled by admin.
+     */
+    public boolean isDisabledByAdmin() {
+        return mHelper.isDisabledByAdmin();
+    }
+
+    /**
+     * Disable preference based on the enforce admin.
+     *
+     * @param admin details of the admin who enforced the restriction. If it is {@code null}, then
+     *     this preference will be enabled. Otherwise, it will be disabled.
+     */
+    public void setDisabledByAdmin(@Nullable EnforcedAdmin admin) {
+        if (mHelper.setDisabledByAdmin(admin)) {
+            notifyChanged();
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index ad0e6f4..e95a506 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -67,7 +67,6 @@
 import com.android.settingslib.fuelgauge.BatteryStatus;
 import com.android.settingslib.utils.BuildCompatUtils;
 
-import java.time.Duration;
 import java.util.List;
 
 public class Utils {
@@ -76,21 +75,10 @@
 
     public static final String INCOMPATIBLE_CHARGER_WARNING_DISABLED =
             "incompatible_charger_warning_disabled";
-    public static final String WIRELESS_CHARGING_NOTIFICATION_TIMESTAMP =
-            "wireless_charging_notification_timestamp";
 
     @VisibleForTesting
     static final String STORAGE_MANAGER_ENABLED_PROPERTY = "ro.storage_manager.enabled";
 
-    @VisibleForTesting static final long WIRELESS_CHARGING_DEFAULT_TIMESTAMP = -1L;
-
-    @VisibleForTesting
-    static final long WIRELESS_CHARGING_NOTIFICATION_THRESHOLD_MILLIS =
-            Duration.ofDays(30).toMillis();
-
-    @VisibleForTesting
-    static final String WIRELESS_CHARGING_WARNING_ENABLED = "wireless_charging_warning_enabled";
-
     private static Signature[] sSystemSignature;
     private static String sPermissionControllerPackageName;
     private static String sServicesSystemSharedLibPackageName;
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java b/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
index 6b833cc..0282f03 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
@@ -16,6 +16,7 @@
 
 package com.android.settingslib.applications;
 
+import android.annotation.NonNull;
 import android.app.usage.StorageStats;
 import android.app.usage.StorageStatsManager;
 import android.content.Context;
@@ -25,6 +26,7 @@
 import androidx.annotation.VisibleForTesting;
 
 import java.io.IOException;
+import java.util.UUID;
 
 /**
  * StorageStatsSource wraps the StorageStatsManager for testability purposes.
@@ -59,6 +61,10 @@
         return mStorageStatsManager.getCacheQuotaBytes(volumeUuid, uid);
     }
 
+    public long getTotalBytes(@NonNull UUID storageUuid) throws IOException {
+        return mStorageStatsManager.getTotalBytes(storageUuid);
+    }
+
     /**
      * Static class that provides methods for querying the amount of external storage available as
      * well as breaking it up into several media types.
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
index 09b1eaf..57fcc74 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothUtils.java
@@ -542,6 +542,25 @@
     }
 
     /**
+     * Checks if the Bluetooth device is an available hearing device, which means:
+     * 1) currently connected
+     * 2) is Hearing Aid
+     * 3) connected profile match hearing aid related profiles (e.g. ASHA, HAP)
+     *
+     * @param cachedDevice the CachedBluetoothDevice
+     * @return if the device is Available hearing device
+     */
+    @WorkerThread
+    public static boolean isAvailableHearingDevice(CachedBluetoothDevice cachedDevice) {
+        if (isDeviceConnected(cachedDevice) && cachedDevice.isConnectedHearingAidDevice()) {
+            Log.d(TAG, "isFilterMatched() device : "
+                    + cachedDevice.getName() + ", the profile is connected.");
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Check if the Bluetooth device is a ConnectedBluetoothDevice, which means:
      * 1) currently connected
      * 2) is not Hearing Aid or LE Audio
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
index e34c50e..9b1e4b7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -174,6 +174,7 @@
 
     public void startScan() {
         mMediaDevices.clear();
+        registerRouter();
         startScanOnRouter();
         updateRouteListingPreference();
         refreshDevices();
@@ -188,10 +189,19 @@
         }
     }
 
-    public abstract void stopScan();
+    public final void stopScan() {
+        stopScanOnRouter();
+        unregisterRouter();
+    }
+
+    protected abstract void stopScanOnRouter();
 
     protected abstract void startScanOnRouter();
 
+    protected abstract void registerRouter();
+
+    protected abstract void unregisterRouter();
+
     protected abstract void transferToRoute(@NonNull MediaRoute2Info route);
 
     protected abstract void selectRoute(
@@ -244,8 +254,6 @@
     protected abstract List<MediaRoute2Info> getTransferableRoutes(@NonNull String packageName);
 
     protected final void rebuildDeviceList() {
-        mMediaDevices.clear();
-        mCurrentConnectedDevice = null;
         buildAvailableRoutes();
     }
 
@@ -514,17 +522,27 @@
     // MediaRoute2Info.getType was made public on API 34, but exists since API 30.
     @SuppressWarnings("NewApi")
     private synchronized void buildAvailableRoutes() {
-        for (MediaRoute2Info route : getAvailableRoutes()) {
+        mMediaDevices.clear();
+        RoutingSessionInfo activeSession = getActiveRoutingSession();
+
+        for (MediaRoute2Info route : getAvailableRoutes(activeSession)) {
             if (DEBUG) {
                 Log.d(TAG, "buildAvailableRoutes() route : " + route.getName() + ", volume : "
                         + route.getVolume() + ", type : " + route.getType());
             }
-            addMediaDevice(route);
+            addMediaDevice(route, activeSession);
+        }
+
+        // In practice, mMediaDevices should always have at least one route.
+        if (!mMediaDevices.isEmpty()) {
+            // First device on the list is always the first selected route.
+            mCurrentConnectedDevice = mMediaDevices.get(0);
         }
     }
-    private synchronized List<MediaRoute2Info> getAvailableRoutes() {
+
+    private synchronized List<MediaRoute2Info> getAvailableRoutes(
+            RoutingSessionInfo activeSession) {
         List<MediaRoute2Info> availableRoutes = new ArrayList<>();
-        RoutingSessionInfo activeSession = getActiveRoutingSession();
 
         List<MediaRoute2Info> selectedRoutes = getSelectedRoutes(activeSession);
         availableRoutes.addAll(selectedRoutes);
@@ -562,7 +580,7 @@
     // MediaRoute2Info.getType was made public on API 34, but exists since API 30.
     @SuppressWarnings("NewApi")
     @VisibleForTesting
-    void addMediaDevice(MediaRoute2Info route) {
+    void addMediaDevice(MediaRoute2Info route, RoutingSessionInfo activeSession) {
         final int deviceType = route.getType();
         MediaDevice mediaDevice = null;
         switch (deviceType) {
@@ -627,14 +645,10 @@
                 break;
         }
 
-        if (mediaDevice != null
-                && getActiveRoutingSession().getSelectedRoutes().contains(route.getId())) {
-            mediaDevice.setState(STATE_SELECTED);
-            if (mCurrentConnectedDevice == null) {
-                mCurrentConnectedDevice = mediaDevice;
-            }
-        }
         if (mediaDevice != null) {
+            if (activeSession.getSelectedRoutes().contains(route.getId())) {
+                mediaDevice.setState(STATE_SELECTED);
+            }
             mMediaDevices.add(mediaDevice);
         }
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/ManagerInfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/ManagerInfoMediaManager.java
index c4fac35..23063da 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/ManagerInfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/ManagerInfoMediaManager.java
@@ -62,22 +62,30 @@
     @Override
     protected void startScanOnRouter() {
         if (!mIsScanning) {
-            mRouterManager.registerCallback(mExecutor, mMediaRouterCallback);
             mRouterManager.registerScanRequest();
             mIsScanning = true;
         }
     }
 
     @Override
-    public void stopScan() {
+    protected void registerRouter() {
+        mRouterManager.registerCallback(mExecutor, mMediaRouterCallback);
+    }
+
+    @Override
+    protected void stopScanOnRouter() {
         if (mIsScanning) {
-            mRouterManager.unregisterCallback(mMediaRouterCallback);
             mRouterManager.unregisterScanRequest();
             mIsScanning = false;
         }
     }
 
     @Override
+    protected void unregisterRouter() {
+        mRouterManager.unregisterCallback(mMediaRouterCallback);
+    }
+
+    @Override
     protected void transferToRoute(@NonNull MediaRoute2Info route) {
         // TODO: b/279555229 - provide real user handle of a caller.
         mRouterManager.transfer(mPackageName, route, android.os.Process.myUserHandle());
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java
index 2b8c2dd..cf11c6d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/NoOpInfoMediaManager.java
@@ -63,12 +63,22 @@
     }
 
     @Override
-    public void stopScan() {
+    protected void startScanOnRouter() {
         // Do nothing.
     }
 
     @Override
-    protected void startScanOnRouter() {
+    protected void registerRouter() {
+        // Do nothing.
+    }
+
+    @Override
+    protected void stopScanOnRouter() {
+        // Do nothing.
+    }
+
+    @Override
+    protected void unregisterRouter() {
         // Do nothing.
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java
index 9c82cb1..0dceeba 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/RouterInfoMediaManager.java
@@ -97,11 +97,6 @@
 
     @Override
     protected void startScanOnRouter() {
-        mRouter.registerRouteCallback(mExecutor, mRouteCallback, RouteDiscoveryPreference.EMPTY);
-        mRouter.registerRouteListingPreferenceUpdatedCallback(
-                mExecutor, mRouteListingPreferenceCallback);
-        mRouter.registerTransferCallback(mExecutor, mTransferCallback);
-        mRouter.registerControllerCallback(mExecutor, mControllerCallback);
         if (Flags.enableScreenOffScanning()) {
             MediaRouter2.ScanRequest request = new MediaRouter2.ScanRequest.Builder().build();
             mScanToken.compareAndSet(null, mRouter.requestScan(request));
@@ -111,7 +106,16 @@
     }
 
     @Override
-    public void stopScan() {
+    protected void registerRouter() {
+        mRouter.registerRouteCallback(mExecutor, mRouteCallback, RouteDiscoveryPreference.EMPTY);
+        mRouter.registerRouteListingPreferenceUpdatedCallback(
+                mExecutor, mRouteListingPreferenceCallback);
+        mRouter.registerTransferCallback(mExecutor, mTransferCallback);
+        mRouter.registerControllerCallback(mExecutor, mControllerCallback);
+    }
+
+    @Override
+    protected void stopScanOnRouter() {
         if (Flags.enableScreenOffScanning()) {
             MediaRouter2.ScanToken token = mScanToken.getAndSet(null);
             if (token != null) {
@@ -120,6 +124,10 @@
         } else {
             mRouter.stopScan();
         }
+    }
+
+    @Override
+    protected void unregisterRouter() {
         mRouter.unregisterControllerCallback(mControllerCallback);
         mRouter.unregisterTransferCallback(mTransferCallback);
         mRouter.unregisterRouteListingPreferenceUpdatedCallback(mRouteListingPreferenceCallback);
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java b/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
index b2de5a9..cdc3f12 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
@@ -62,6 +62,9 @@
 
     private static final String AVATAR_PICKER_ACTION = "com.android.avatarpicker"
             + ".FULL_SCREEN_ACTIVITY";
+    private static final String EXTRA_FILE_AUTHORITY = "file_authority";
+    private static final String EXTRA_DEFAULT_ICON_TINT_COLOR = "default_icon_tint_color";
+
     static final String EXTRA_IS_USER_NEW = "is_user_new";
 
     private final Activity mActivity;
@@ -73,10 +76,12 @@
     private Bitmap mNewUserPhotoBitmap;
     private Drawable mNewUserPhotoDrawable;
     private String mCachedDrawablePath;
+
     public EditUserPhotoController(Activity activity, ActivityStarter activityStarter,
             ImageView view, Bitmap savedBitmap, Drawable savedDrawable, String fileAuthority) {
         this(activity, activityStarter, view, savedBitmap, savedDrawable, fileAuthority, true);
     }
+
     public EditUserPhotoController(Activity activity, ActivityStarter activityStarter,
             ImageView view, Bitmap savedBitmap, Drawable savedDrawable, String fileAuthority,
             boolean isUserNew) {
@@ -104,9 +109,9 @@
         }
 
         if (requestCode == REQUEST_CODE_PICK_AVATAR) {
-            if (data.hasExtra(AvatarPickerActivity.EXTRA_DEFAULT_ICON_TINT_COLOR)) {
+            if (data.hasExtra(EXTRA_DEFAULT_ICON_TINT_COLOR)) {
                 int tintColor =
-                        data.getIntExtra(AvatarPickerActivity.EXTRA_DEFAULT_ICON_TINT_COLOR, -1);
+                        data.getIntExtra(EXTRA_DEFAULT_ICON_TINT_COLOR, -1);
                 onDefaultIconSelected(tintColor);
                 return true;
             }
@@ -123,15 +128,16 @@
     }
 
     private void showAvatarPicker(boolean isUserNew) {
-        Intent intent;
+        Intent intent = new Intent(AVATAR_PICKER_ACTION);
+        intent.addCategory(Intent.CATEGORY_DEFAULT);
         if (Flags.avatarSync()) {
-            intent = new Intent(AVATAR_PICKER_ACTION);
-            intent.addCategory(Intent.CATEGORY_DEFAULT);
             intent.putExtra(EXTRA_IS_USER_NEW, isUserNew);
         } else {
-            intent = new Intent(mImageView.getContext(), AvatarPickerActivity.class);
+            // SettingsLib is used by multiple apps therefore we need to know out of all apps
+            // using settingsLib which one is the one we return value to.
+            intent.setPackage(mImageView.getContext().getApplicationContext().getPackageName());
         }
-        intent.putExtra(AvatarPickerActivity.EXTRA_FILE_AUTHORITY, mFileAuthority);
+        intent.putExtra(EXTRA_FILE_AUTHORITY, mFileAuthority);
         mActivityStarter.startActivityForResult(intent, REQUEST_CODE_PICK_AVATAR);
     }
 
@@ -183,7 +189,8 @@
             }
 
             @Override
-            public void onFailure(Throwable t) {}
+            public void onFailure(Throwable t) {
+            }
         }, mImageView.getContext().getMainExecutor());
     }
 
diff --git a/packages/SettingsLib/tests/integ/Android.bp b/packages/SettingsLib/tests/integ/Android.bp
index f303ab5..33d23a3 100644
--- a/packages/SettingsLib/tests/integ/Android.bp
+++ b/packages/SettingsLib/tests/integ/Android.bp
@@ -57,6 +57,7 @@
         "mockito-target-extended-minus-junit4",
         "platform-test-annotations",
         "truth",
+        "SettingsLibAvatarPicker",
         "SettingsLibDeviceStateRotationLock",
         "SettingsLibSettingsSpinner",
         "SettingsLibUsageProgressBarPreference",
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AvatarPhotoControllerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AvatarPhotoControllerTest.java
index d988111..995314e 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AvatarPhotoControllerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AvatarPhotoControllerTest.java
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.settingslib.users;
+package com.android.settingslib.avatarpicker;
 
-import static com.android.settingslib.users.AvatarPhotoController.REQUEST_CODE_CHOOSE_PHOTO;
-import static com.android.settingslib.users.AvatarPhotoController.REQUEST_CODE_CROP_PHOTO;
-import static com.android.settingslib.users.AvatarPhotoController.REQUEST_CODE_TAKE_PHOTO;
+import static com.android.settingslib.avatarpicker.AvatarPhotoController.REQUEST_CODE_CHOOSE_PHOTO;
+import static com.android.settingslib.avatarpicker.AvatarPhotoController.REQUEST_CODE_CROP_PHOTO;
+import static com.android.settingslib.avatarpicker.AvatarPhotoController.REQUEST_CODE_TAKE_PHOTO;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
index 0931b68..5136e26 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/UtilsTest.java
@@ -72,7 +72,6 @@
     private static final String PERCENTAGE_49 = "49%";
     private static final String PERCENTAGE_50 = "50%";
     private static final String PERCENTAGE_100 = "100%";
-    private static final long CURRENT_TIMESTAMP = System.currentTimeMillis();
 
     private AudioManager mAudioManager;
     private Context mContext;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
index 475a6d6..1246fd8 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothUtilsTest.java
@@ -430,4 +430,14 @@
         assertThat(BluetoothUtils.isExclusivelyManagedBluetoothDevice(mContext,
                 mBluetoothDevice)).isEqualTo(true);
     }
+
+    @Test
+    public void isAvailableHearingDevice_isConnectedHearingAid_returnTure() {
+        when(mCachedBluetoothDevice.isConnectedHearingAidDevice()).thenReturn(true);
+        when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
+        when(mBluetoothDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        when(mBluetoothDevice.isConnected()).thenReturn(true);
+
+        assertThat(BluetoothUtils.isAvailableHearingDevice(mCachedBluetoothDevice)).isEqualTo(true);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
index d85d253..d793867 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
@@ -86,6 +86,41 @@
     private static final String TEST_DUPLICATED_ID_2 = "test_duplicated_id_2";
     private static final String TEST_DUPLICATED_ID_3 = "test_duplicated_id_3";
 
+    private static final String TEST_SYSTEM_ROUTE_ID = "TEST_SYSTEM_ROUTE_ID";
+    private static final String TEST_BLUETOOTH_ROUTE_ID = "TEST_BT_ROUTE_ID";
+
+    private static final RoutingSessionInfo TEST_SYSTEM_ROUTING_SESSION =
+            new RoutingSessionInfo.Builder("FAKE_SYSTEM_ROUTING_SESSION_ID", TEST_PACKAGE_NAME)
+                    .addSelectedRoute(TEST_SYSTEM_ROUTE_ID)
+                    .addTransferableRoute(TEST_BLUETOOTH_ROUTE_ID)
+                    .setSystemSession(true)
+                    .build();
+
+    private static final MediaRoute2Info TEST_SELECTED_SYSTEM_ROUTE =
+            new MediaRoute2Info.Builder(TEST_SYSTEM_ROUTE_ID, "SELECTED_SYSTEM_ROUTE")
+                    .setSystemRoute(true)
+                    .addFeature(MediaRoute2Info.FEATURE_LIVE_AUDIO)
+                    .build();
+
+    private static final MediaRoute2Info TEST_BLUETOOTH_ROUTE =
+            new MediaRoute2Info.Builder(TEST_BLUETOOTH_ROUTE_ID, "BLUETOOTH_ROUTE")
+                    .setSystemRoute(true)
+                    .addFeature(MediaRoute2Info.FEATURE_LIVE_AUDIO)
+                    .setType(TYPE_BLUETOOTH_A2DP)
+                    .setAddress("00:00:00:00:00:00")
+                    .build();
+
+    private static final RoutingSessionInfo TEST_REMOTE_ROUTING_SESSION =
+            new RoutingSessionInfo.Builder("FAKE_REMOTE_ROUTING_SESSION_ID", TEST_PACKAGE_NAME)
+                    .addSelectedRoute(TEST_ID_1)
+                    .build();
+
+    private static final MediaRoute2Info TEST_REMOTE_ROUTE =
+            new MediaRoute2Info.Builder(TEST_ID_1, "REMOTE_ROUTE")
+                    .setSystemRoute(true)
+                    .addFeature(MediaRoute2Info.FEATURE_LIVE_AUDIO)
+                    .build();
+
     @Mock
     private MediaRouter2Manager mRouterManager;
     @Mock
@@ -127,7 +162,10 @@
         RoutingSessionInfo sessionInfo = mock(RoutingSessionInfo.class);
         mInfoMediaManager.mRouterManager = mRouterManager;
         // Since test is running in Robolectric, return a fake session to avoid NPE.
-        when(mRouterManager.getRoutingSessions(anyString())).thenReturn(List.of(sessionInfo));
+        when(mRouterManager.getRoutingSessions(anyString()))
+                .thenReturn(List.of(TEST_SYSTEM_ROUTING_SESSION));
+        when(mRouterManager.getSelectedRoutes(any()))
+                .thenReturn(List.of(TEST_SELECTED_SYSTEM_ROUTE));
 
         mInfoMediaManager.startScan();
         mInfoMediaManager.stopScan();
@@ -167,52 +205,27 @@
 
     @Test
     public void onSessionReleased_shouldUpdateConnectedDevice() {
-        final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
-        final RoutingSessionInfo sessionInfo1 = mock(RoutingSessionInfo.class);
-        routingSessionInfos.add(sessionInfo1);
-        final RoutingSessionInfo sessionInfo2 = mock(RoutingSessionInfo.class);
-        routingSessionInfos.add(sessionInfo2);
+        mInfoMediaManager.mRouterManager = mRouterManager;
 
-        final List<String> selectedRoutesSession1 = new ArrayList<>();
-        selectedRoutesSession1.add(TEST_ID_1);
-        when(sessionInfo1.getSelectedRoutes()).thenReturn(selectedRoutesSession1);
-
-        final List<String> selectedRoutesSession2 = new ArrayList<>();
-        selectedRoutesSession2.add(TEST_ID_2);
-        when(sessionInfo2.getSelectedRoutes()).thenReturn(selectedRoutesSession2);
-
-        mShadowRouter2Manager.setRoutingSessions(routingSessionInfos);
-
-        final MediaRoute2Info info1 = mock(MediaRoute2Info.class);
-        when(info1.getId()).thenReturn(TEST_ID_1);
-        when(info1.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
-
-        final MediaRoute2Info info2 = mock(MediaRoute2Info.class);
-        when(info2.getId()).thenReturn(TEST_ID_2);
-        when(info2.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
-
-        final List<MediaRoute2Info> routes = new ArrayList<>();
-        routes.add(info1);
-        routes.add(info2);
-        mShadowRouter2Manager.setAllRoutes(routes);
-        mShadowRouter2Manager.setTransferableRoutes(routes);
-
-        final MediaDevice mediaDevice1 = mInfoMediaManager.findMediaDevice(TEST_ID_1);
-        assertThat(mediaDevice1).isNull();
-        final MediaDevice mediaDevice2 = mInfoMediaManager.findMediaDevice(TEST_ID_2);
-        assertThat(mediaDevice2).isNull();
+        // Active routing session is last one in list.
+        when(mRouterManager.getRoutingSessions(anyString()))
+                .thenReturn(List.of(TEST_SYSTEM_ROUTING_SESSION, TEST_REMOTE_ROUTING_SESSION));
+        when(mRouterManager.getSelectedRoutes(TEST_SYSTEM_ROUTING_SESSION))
+                .thenReturn(List.of(TEST_SELECTED_SYSTEM_ROUTE));
+        when(mRouterManager.getSelectedRoutes(TEST_REMOTE_ROUTING_SESSION))
+                .thenReturn(List.of(TEST_REMOTE_ROUTE));
 
         mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();
-        final MediaDevice infoDevice1 = mInfoMediaManager.mMediaDevices.get(0);
-        assertThat(infoDevice1.getId()).isEqualTo(TEST_ID_1);
-        final MediaDevice infoDevice2 = mInfoMediaManager.mMediaDevices.get(1);
-        assertThat(infoDevice2.getId()).isEqualTo(TEST_ID_2);
-        // The active routing session is the last one in the list, which maps to infoDevice2.
-        assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(infoDevice2);
+        MediaDevice remoteDevice = mInfoMediaManager.findMediaDevice(TEST_REMOTE_ROUTE.getId());
+        assertThat(remoteDevice).isNotNull();
+        assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(remoteDevice);
 
-        routingSessionInfos.remove(sessionInfo2);
-        mInfoMediaManager.mMediaRouterCallback.onSessionReleased(sessionInfo2);
-        assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(infoDevice1);
+        when(mRouterManager.getRoutingSessions(anyString()))
+                .thenReturn(List.of(TEST_SYSTEM_ROUTING_SESSION));
+        mInfoMediaManager.mMediaRouterCallback.onSessionReleased(TEST_REMOTE_ROUTING_SESSION);
+        MediaDevice systemRoute = mInfoMediaManager.findMediaDevice(TEST_SYSTEM_ROUTE_ID);
+        assertThat(systemRoute).isNotNull();
+        assertThat(mInfoMediaManager.getCurrentConnectedDevice()).isEqualTo(systemRoute);
     }
 
     @Test
@@ -770,18 +783,16 @@
 
     @Test
     public void onSessionUpdated_shouldDispatchDeviceListAdded() {
-        final MediaRoute2Info info = mock(MediaRoute2Info.class);
-        when(info.getId()).thenReturn(TEST_ID);
-        when(info.getClientPackageName()).thenReturn(TEST_PACKAGE_NAME);
-        when(info.isSystemRoute()).thenReturn(true);
-
-        final List<MediaRoute2Info> routes = new ArrayList<>();
-        routes.add(info);
-        mShadowRouter2Manager.setAllRoutes(routes);
+        mInfoMediaManager.mRouterManager = mRouterManager;
+        // Since test is running in Robolectric, return a fake session to avoid NPE.
+        when(mRouterManager.getRoutingSessions(anyString()))
+                .thenReturn(List.of(TEST_SYSTEM_ROUTING_SESSION));
+        when(mRouterManager.getSelectedRoutes(any()))
+                .thenReturn(List.of(TEST_SELECTED_SYSTEM_ROUTE));
 
         mInfoMediaManager.registerCallback(mCallback);
 
-        mInfoMediaManager.mMediaRouterCallback.onSessionUpdated(mock(RoutingSessionInfo.class));
+        mInfoMediaManager.mMediaRouterCallback.onSessionUpdated(TEST_SYSTEM_ROUTING_SESSION);
 
         verify(mCallback).onDeviceListAdded(any());
     }
@@ -795,19 +806,19 @@
 
         when(route2Info.getType()).thenReturn(TYPE_REMOTE_SPEAKER);
         when(route2Info.getId()).thenReturn(TEST_ID);
-        mInfoMediaManager.addMediaDevice(route2Info);
+        mInfoMediaManager.addMediaDevice(route2Info, TEST_SYSTEM_ROUTING_SESSION);
         assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof InfoMediaDevice).isTrue();
 
         when(route2Info.getType()).thenReturn(TYPE_USB_DEVICE);
         when(route2Info.getId()).thenReturn(TEST_ID);
         mInfoMediaManager.mMediaDevices.clear();
-        mInfoMediaManager.addMediaDevice(route2Info);
+        mInfoMediaManager.addMediaDevice(route2Info, TEST_SYSTEM_ROUTING_SESSION);
         assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof PhoneMediaDevice).isTrue();
 
         when(route2Info.getType()).thenReturn(TYPE_WIRED_HEADSET);
         when(route2Info.getId()).thenReturn(TEST_ID);
         mInfoMediaManager.mMediaDevices.clear();
-        mInfoMediaManager.addMediaDevice(route2Info);
+        mInfoMediaManager.addMediaDevice(route2Info, TEST_SYSTEM_ROUTING_SESSION);
         assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof PhoneMediaDevice).isTrue();
 
         when(route2Info.getType()).thenReturn(TYPE_BLUETOOTH_A2DP);
@@ -818,12 +829,12 @@
         when(cachedBluetoothDeviceManager.findDevice(any(BluetoothDevice.class)))
                 .thenReturn(cachedDevice);
         mInfoMediaManager.mMediaDevices.clear();
-        mInfoMediaManager.addMediaDevice(route2Info);
+        mInfoMediaManager.addMediaDevice(route2Info, TEST_SYSTEM_ROUTING_SESSION);
         assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof BluetoothMediaDevice).isTrue();
 
         when(route2Info.getType()).thenReturn(TYPE_BUILTIN_SPEAKER);
         mInfoMediaManager.mMediaDevices.clear();
-        mInfoMediaManager.addMediaDevice(route2Info);
+        mInfoMediaManager.addMediaDevice(route2Info, TEST_SYSTEM_ROUTING_SESSION);
         assertThat(mInfoMediaManager.mMediaDevices.get(0) instanceof PhoneMediaDevice).isTrue();
     }
 
@@ -841,34 +852,35 @@
                 .thenReturn(null);
 
         mInfoMediaManager.mMediaDevices.clear();
-        mInfoMediaManager.addMediaDevice(route2Info);
+        mInfoMediaManager.addMediaDevice(route2Info, TEST_SYSTEM_ROUTING_SESSION);
 
         assertThat(mInfoMediaManager.mMediaDevices.size()).isEqualTo(0);
     }
 
     @Test
-    public void addMediaDevice_deviceIncludedInSelectedDevices_shouldSetAsCurrentConnected() {
-        final MediaRoute2Info route2Info = mock(MediaRoute2Info.class);
+    public void onRoutesUpdated_setsFirstSelectedRouteAsCurrentConnectedDevice() {
         final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
                 mock(CachedBluetoothDeviceManager.class);
-        final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
-        final List<RoutingSessionInfo> routingSessionInfos = new ArrayList<>();
-        final RoutingSessionInfo sessionInfo = mock(RoutingSessionInfo.class);
-        routingSessionInfos.add(sessionInfo);
 
-        when(mRouterManager.getRoutingSessions(TEST_PACKAGE_NAME)).thenReturn(routingSessionInfos);
-        when(sessionInfo.getSelectedRoutes()).thenReturn(ImmutableList.of(TEST_ID));
-        when(route2Info.getType()).thenReturn(TYPE_BLUETOOTH_A2DP);
-        when(route2Info.getAddress()).thenReturn("00:00:00:00:00:00");
-        when(route2Info.getId()).thenReturn(TEST_ID);
+        final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
+        RoutingSessionInfo selectedBtSession =
+                new RoutingSessionInfo.Builder(TEST_SYSTEM_ROUTING_SESSION)
+                        .clearSelectedRoutes()
+                        .clearTransferableRoutes()
+                        .addSelectedRoute(TEST_BLUETOOTH_ROUTE_ID)
+                        .addTransferableRoute(TEST_SYSTEM_ROUTE_ID)
+                        .build();
+
+        when(mRouterManager.getRoutingSessions(TEST_PACKAGE_NAME))
+                .thenReturn(List.of(selectedBtSession));
+        when(mRouterManager.getSelectedRoutes(any())).thenReturn(List.of(TEST_BLUETOOTH_ROUTE));
         when(mLocalBluetoothManager.getCachedDeviceManager())
                 .thenReturn(cachedBluetoothDeviceManager);
         when(cachedBluetoothDeviceManager.findDevice(any(BluetoothDevice.class)))
                 .thenReturn(cachedDevice);
         mInfoMediaManager.mRouterManager = mRouterManager;
 
-        mInfoMediaManager.mMediaDevices.clear();
-        mInfoMediaManager.addMediaDevice(route2Info);
+        mInfoMediaManager.mMediaRouterCallback.onRoutesUpdated();
 
         MediaDevice device = mInfoMediaManager.mMediaDevices.get(0);
 
diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp
index bf4f60d..e9c2672 100644
--- a/packages/SettingsProvider/Android.bp
+++ b/packages/SettingsProvider/Android.bp
@@ -32,6 +32,7 @@
         "unsupportedappusage",
     ],
     static_libs: [
+        "aconfig_demo_flags_java_lib",
         "device_config_service_flags_java",
         "libaconfig_java_proto_lite",
         "SettingsLibDeviceStateRotationLock",
@@ -87,6 +88,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/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 38a3a2a..a33c160 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -258,6 +258,7 @@
         Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED,
         Settings.Secure.SEARCH_ALL_ENTRYPOINTS_ENABLED,
         Settings.Secure.HUB_MODE_TUTORIAL_STATE,
+        Settings.Secure.GLANCEABLE_HUB_ENABLED,
         Settings.Secure.STYLUS_BUTTONS_ENABLED,
         Settings.Secure.STYLUS_HANDWRITING_ENABLED,
         Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index 6def40b..c274534 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -161,10 +161,6 @@
                 Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, PERCENTAGE_INTEGER_VALIDATOR);
         VALIDATORS.put(Global.BLUETOOTH_ON, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Global.CLOCKWORK_HOME_READY, ANY_STRING_VALIDATOR);
-        VALIDATORS.put(Global.ENABLE_TARE,
-                new DiscreteValueValidator(new String[] {"0", "1", "2"}));
-        VALIDATORS.put(Global.TARE_ALARM_MANAGER_CONSTANTS, ANY_STRING_VALIDATOR);
-        VALIDATORS.put(Global.TARE_JOB_SCHEDULER_CONSTANTS, ANY_STRING_VALIDATOR);
         VALIDATORS.put(Global.PRIVATE_DNS_MODE, ANY_STRING_VALIDATOR);
         VALIDATORS.put(Global.PRIVATE_DNS_SPECIFIER, ANY_STRING_VALIDATOR);
         VALIDATORS.put(Global.SOFT_AP_TIMEOUT_ENABLED, BOOLEAN_VALIDATOR);
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 252cb8f..1bff592 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -416,6 +416,7 @@
                 BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.DND_CONFIGS_MIGRATED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.HUB_MODE_TUTORIAL_STATE, NON_NEGATIVE_INTEGER_VALIDATOR);
+        VALIDATORS.put(Secure.GLANCEABLE_HUB_ENABLED, new InclusiveIntegerRangeValidator(0, 1));
         VALIDATORS.put(Secure.STYLUS_BUTTONS_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.STYLUS_HANDWRITING_ENABLED,
                 new DiscreteValueValidator(new String[] {"-1", "0", "1"}));
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 4e4c22f..68167e1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -60,16 +60,17 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
-import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.PosixFileAttributes;
+import java.nio.file.attribute.PosixFilePermission;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -165,8 +166,8 @@
 
     private static final String STORAGE_MIGRATION_FLAG =
             "core_experiments_team_internal/com.android.providers.settings.storage_test_mission_1";
-    private static final String STORAGE_MIGRATION_LOG =
-            "/metadata/aconfig/flags/storage_migration.log";
+    private static final String STORAGE_MIGRATION_MARKER_FILE =
+            "/metadata/aconfig/storage_test_mission_1";
 
     /**
      * This tag is applied to all aconfig default value-loaded flags.
@@ -1126,7 +1127,7 @@
                     Slog.i(LOG_TAG, "[PERSIST END]");
                 }
             } catch (Throwable t) {
-                Slog.wtf(LOG_TAG, "Failed to write settings, restoring old file", t);
+                Slog.e(LOG_TAG, "Failed to write settings, restoring old file", t);
                 if (t instanceof IOException) {
                     if (t.getMessage().contains("Couldn't create directory")) {
                         if (DEBUG) {
@@ -1467,16 +1468,29 @@
                     }
                 }
 
-                if (name != null && name.equals(STORAGE_MIGRATION_FLAG) && value.equals("true")) {
-                    File file = new File(STORAGE_MIGRATION_LOG);
-                    if (!file.exists()) {
-                        try (BufferedWriter writer =
-                                new BufferedWriter(new FileWriter(STORAGE_MIGRATION_LOG))) {
-                            final long timestamp = System.currentTimeMillis();
-                            String entry = String.format("%d | Log init", timestamp);
-                            writer.write(entry);
-                        } catch (IOException e) {
-                            Slog.e(LOG_TAG, "failed to write storage migration file", e);
+                if (isConfigSettingsKey(mKey) && name != null
+                        && name.equals(STORAGE_MIGRATION_FLAG)) {
+                    if (value.equals("true")) {
+                        Path path = Paths.get(STORAGE_MIGRATION_MARKER_FILE);
+                        if (!Files.exists(path)) {
+                            Files.createFile(path);
+                        }
+
+                        Set<PosixFilePermission> perms =
+                                Files.readAttributes(path, PosixFileAttributes.class).permissions();
+                        perms.add(PosixFilePermission.OWNER_WRITE);
+                        perms.add(PosixFilePermission.OWNER_READ);
+                        perms.add(PosixFilePermission.GROUP_READ);
+                        perms.add(PosixFilePermission.OTHERS_READ);
+                        try {
+                            Files.setPosixFilePermissions(path, perms);
+                        } catch (Exception e) {
+                            Slog.e(LOG_TAG, "failed to set permissions on migration marker", e);
+                        }
+                    } else {
+                        java.nio.file.Path path = Paths.get(STORAGE_MIGRATION_MARKER_FILE);
+                        if (Files.exists(path)) {
+                            Files.delete(path);
                         }
                     }
                 }
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 c572bdb..d20fbf5 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/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 8cafe5f..f42efe2 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -223,7 +223,6 @@
                     Settings.Global.ENABLE_DELETION_HELPER_NO_THRESHOLD_TOGGLE,
                     Settings.Global.ENABLE_DISKSTATS_LOGGING,
                     Settings.Global.ENABLE_EPHEMERAL_FEATURE,
-                    Settings.Global.ENABLE_TARE,
                     Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED,
                     Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD,
                     Settings.Global.SMART_REPLIES_IN_NOTIFICATIONS_FLAGS,
@@ -408,7 +407,6 @@
                     Settings.Global.SHOW_PEOPLE_SPACE,
                     Settings.Global.SHOW_NEW_NOTIF_DISMISS,
                     Settings.Global.SHOW_RESTART_IN_CRASH_DIALOG,
-                    Settings.Global.SHOW_TARE_DEVELOPER_OPTIONS,
                     Settings.Global.SHOW_TEMPERATURE_WARNING,
                     Settings.Global.SHOW_USB_TEMPERATURE_ALARM,
                     Settings.Global.SIGNED_CONFIG_VERSION,
@@ -435,8 +433,6 @@
                     Settings.Global.SYS_UIDCPUPOWER,
                     Settings.Global.SYS_TRACED,
                     Settings.Global.FPS_DEVISOR,
-                    Settings.Global.TARE_ALARM_MANAGER_CONSTANTS,
-                    Settings.Global.TARE_JOB_SCHEDULER_CONSTANTS,
                     Settings.Global.TCP_DEFAULT_INIT_RWND,
                     Settings.Global.TETHER_DUN_APN,
                     Settings.Global.TETHER_DUN_REQUIRED,
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 5804071..b94e224 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -896,7 +896,6 @@
 
     <!-- Permissions required for CTS test - CtsVoiceInteractionTestCases -->
     <uses-permission android:name="android.permission.RESET_HOTWORD_TRAINING_DATA_EGRESS_COUNT" />
-    <uses-permission android:name="android.permission.RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA" />
     <uses-permission android:name="android.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO" />
 
     <uses-permission android:name="android.permission.GET_BINDING_UID_IMPORTANCE" />
diff --git a/packages/SoundPicker/res/values-nl/strings.xml b/packages/SoundPicker/res/values-nl/strings.xml
index 5b6fb70..d38858c 100644
--- a/packages/SoundPicker/res/values-nl/strings.xml
+++ b/packages/SoundPicker/res/values-nl/strings.xml
@@ -18,7 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="ringtone_default" msgid="798836092118824500">"Standaardbeltoon"</string>
     <string name="notification_sound_default" msgid="8133121186242636840">"Standaard meldingsgeluid"</string>
-    <string name="alarm_sound_default" msgid="4787646764557462649">"Standaard alarmgeluid"</string>
+    <string name="alarm_sound_default" msgid="4787646764557462649">"Standaard wekkergeluid"</string>
     <string name="add_ringtone_text" msgid="6642389991738337529">"Ringtone toevoegen"</string>
     <string name="add_alarm_text" msgid="3545497316166999225">"Wekker toevoegen"</string>
     <string name="add_notification_text" msgid="4431129543300614788">"Melding toevoegen"</string>
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index dc7850f..40db52e 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -57,6 +57,7 @@
         "src-release/**/*.kt",
         "src-release/**/*.java",
     ],
+    visibility: ["//visibility:private"],
 }
 
 filegroup {
@@ -65,6 +66,7 @@
         "src-debug/**/*.kt",
         "src-debug/**/*.java",
     ],
+    visibility: ["//visibility:private"],
 }
 
 //Create a library to expose SystemUI's resources to other modules.
@@ -105,6 +107,7 @@
     },
     use_resource_processor: true,
     static_libs: [
+        "//frameworks/libs/systemui:compilelib",
         "SystemUI-res",
         "WifiTrackerLib",
         "WindowManager-Shell",
@@ -117,7 +120,7 @@
         "SystemUI-statsd",
         "SettingsLib",
         "com_android_systemui_flags_lib",
-        "com_android_systemui_shared_flags_lib",
+        "//frameworks/libs/systemui:com_android_systemui_shared_flags_lib",
         "androidx.core_core-ktx",
         "androidx.viewpager2_viewpager2",
         "androidx.legacy_legacy-support-v4",
@@ -145,7 +148,7 @@
         "device_state_flags_lib",
         "kotlinx_coroutines_android",
         "kotlinx_coroutines",
-        "iconloader_base",
+        "//frameworks/libs/systemui:iconloader_base",
         "SystemUI-tags",
         "SystemUI-proto",
         "monet",
@@ -156,7 +159,7 @@
         "lottie",
         "LowLightDreamLib",
         "TraceurCommon",
-        "motion_tool_lib",
+        "//frameworks/libs/systemui:motion_tool_lib",
         "notification_flags_lib",
         "PlatformComposeCore",
         "PlatformComposeSceneTransitionLayout",
@@ -188,7 +191,6 @@
         extra_check_modules: ["SystemUILintChecker"],
         warning_checks: ["MissingApacheLicenseDetector"],
     },
-    skip_jarjar_repackage: true,
 }
 
 filegroup {
@@ -198,12 +200,29 @@
 }
 
 filegroup {
+    name: "kosmos-src",
+    srcs: ["tests/utils/kosmos/src/**/*.kt"],
+    path: "tests/utils/kosmos",
+}
+
+java_library {
+    name: "kosmos",
+    host_supported: true,
+    srcs: [":kosmos-src"],
+    static_libs: [
+        "kotlin-reflect",
+        "kotlin-stdlib",
+    ],
+}
+
+filegroup {
     name: "SystemUI-tests-utils",
     srcs: [
         "tests/utils/src/**/*.java",
         "tests/utils/src/**/*.kt",
+        ":kosmos-src",
     ],
-    path: "tests/utils/src",
+    path: "tests/utils",
 }
 
 filegroup {
@@ -233,6 +252,9 @@
     resource_dirs: [
         "tests/res",
     ],
+    asset_dirs: [
+        "tests/goldens",
+    ],
     static_libs: [
         "SystemUI-res",
         "WifiTrackerLib",
@@ -244,7 +266,7 @@
         "SystemUI-statsd",
         "SettingsLib",
         "com_android_systemui_flags_lib",
-        "com_android_systemui_shared_flags_lib",
+        "//frameworks/libs/systemui:com_android_systemui_shared_flags_lib",
         "flag-junit-base",
         "platform-parametric-runner-lib",
         "androidx.viewpager2_viewpager2",
@@ -274,7 +296,7 @@
         "kotlinx-coroutines-core",
         "kotlinx_coroutines_test",
         "kotlin-reflect",
-        "iconloader_base",
+        "//frameworks/libs/systemui:iconloader_base",
         "SystemUI-tags",
         "SystemUI-proto",
         "metrics-helper-lib",
@@ -288,7 +310,7 @@
         "jsr330",
         "WindowManager-Shell",
         "LowLightDreamLib",
-        "motion_tool_lib",
+        "//frameworks/libs/systemui:motion_tool_lib",
         "androidx.core_core-animation-testing",
         "androidx.compose.ui_ui",
         "flag-junit",
@@ -304,7 +326,6 @@
         "androidx.compose.animation_animation-graphics",
         "TraceurCommon",
     ],
-    skip_jarjar_repackage: true,
 }
 
 android_library {
@@ -326,6 +347,7 @@
         "compose/facade/enabled/src/**/*.kt",
     ],
     static_libs: [
+        "//frameworks/libs/systemui:compilelib",
         "SystemUI-tests-base",
         "androidx.test.uiautomator_uiautomator",
         "androidx.core_core-animation-testing",
@@ -334,8 +356,11 @@
         "androidx.test.ext.junit",
         "androidx.test.ext.truth",
         "kotlin-test",
+        "platform-screenshot-diff-core",
+        "PlatformMotionTesting",
         "SystemUICustomizationTestUtils",
         "androidx.compose.runtime_runtime",
+        "kosmos",
     ],
     libs: [
         "android.test.runner",
@@ -356,7 +381,6 @@
         test: true,
         extra_check_modules: ["SystemUILintChecker"],
     },
-    skip_jarjar_repackage: true,
 }
 
 android_app {
@@ -378,6 +402,7 @@
         "compose/facade/enabled/src/**/*.kt",
     ],
     static_libs: [
+        "//frameworks/libs/systemui:compilelib",
         "SystemUI-tests-base",
         "androidx.compose.runtime_runtime",
     ],
@@ -419,6 +444,7 @@
         "inline-mockito-robolectric-prebuilt",
         "platform-parametric-runner-lib",
         "SystemUICustomizationTestUtils",
+        "kosmos",
     ],
     libs: [
         "android.test.runner",
@@ -452,6 +478,7 @@
         "androidx.test.uiautomator_uiautomator",
         "androidx.core_core-animation-testing",
         "androidx.test.ext.junit",
+        "kosmos",
     ],
     libs: [
         "android.test.runner",
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index e346e72..bbc9fe4 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -1059,6 +1059,13 @@
             </intent-filter>
         </receiver>
 
+        <receiver android:name=".accessibility.hearingaid.HearingDevicesDialogReceiver"
+            android:exported="false">
+            <intent-filter android:priority="1">
+                <action android:name="com.android.systemui.action.LAUNCH_HEARING_DEVICES_DIALOG" />
+            </intent-filter>
+        </receiver>
+
         <activity android:name=".logcat.LogAccessDialogActivity"
                   android:theme="@android:style/Theme.Translucent.NoTitleBar"
                   android:excludeFromRecents="true"
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp
index f74e59a..0ff856e 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp
+++ b/packages/SystemUI/accessibility/accessibilitymenu/aconfig/Android.bp
@@ -5,6 +5,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 f5db6a4..d868d5c 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/accessibility/accessibilitymenu/res/values-sk/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml
index c29002b..2647498 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sk/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="accessibility_menu_service_name" msgid="730136711554740131">"Ponuka dostupnosti"</string>
+    <string name="accessibility_menu_service_name" msgid="730136711554740131">"Ponuka Dostupnosť"</string>
     <string name="accessibility_menu_intro" msgid="3164193281544042394">"Ponukou dostupnosti sa rozumie veľká ponuka na obrazovke, pomocou ktorej môžete ovládať zariadenie. Môžete ho uzamknúť, ovládať hlasitosť a jas, vytvárať snímky obrazovky a mnoho ďalšieho."</string>
     <string name="assistant_label" msgid="6796392082252272356">"Asistent"</string>
     <string name="assistant_utterance" msgid="65509599221141377">"Asistent"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sv/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sv/strings.xml
index c02bbb2..fa43e4f 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-sv/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-sv/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="accessibility_menu_service_name" msgid="730136711554740131">"Till- gänglighetsmeny"</string>
+    <string name="accessibility_menu_service_name" msgid="730136711554740131">"Tillgänglighetsmeny"</string>
     <string name="accessibility_menu_intro" msgid="3164193281544042394">"Tillgänglighetsmenyn är en stor meny på skärmen som du kan styra enheten med. Du kan låsa enheten, ställa in volym och ljusstyrka, ta skärmbilder och annat."</string>
     <string name="assistant_label" msgid="6796392082252272356">"Assistent"</string>
     <string name="assistant_utterance" msgid="65509599221141377">"Assistent"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
index 4dd029c..f5baae2 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
@@ -375,6 +375,10 @@
         unregisterReceiver(mToggleMenuReceiver);
         mPrefs.unregisterOnSharedPreferenceChangeListener(mSharedPreferenceChangeListener);
         sInitialized = false;
+        if (mA11yMenuLayout != null) {
+            mA11yMenuLayout.clearLayout();
+            mA11yMenuLayout = null;
+        }
         return super.onUnbind(intent);
     }
 
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
index edd6a48..1be04f8 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/view/A11yMenuOverlayLayout.java
@@ -151,6 +151,14 @@
         return mLayout;
     }
 
+    public void clearLayout() {
+        if (mLayout != null) {
+            mWindowManager.removeView(mLayout);
+            mLayout.setOnTouchListener(null);
+            mLayout = null;
+        }
+    }
+
     /** Updates view layout with new layout parameters only. */
     public void updateViewLayout() {
         if (mLayout == null || mLayoutParameter == null) {
diff --git a/packages/SystemUI/aconfig/Android.bp b/packages/SystemUI/aconfig/Android.bp
index 76cb6bd..2a32b58 100644
--- a/packages/SystemUI/aconfig/Android.bp
+++ b/packages/SystemUI/aconfig/Android.bp
@@ -25,6 +25,8 @@
         "//visibility:override",
         "//frameworks/base/packages/SystemUI:__subpackages__",
         "//frameworks/libs/systemui/tracinglib:__subpackages__",
+        "//frameworks/base/services/accessibility:__subpackages__",
+        "//frameworks/base/services/tests:__subpackages__",
         "//platform_testing:__subpackages__",
         "//vendor:__subpackages__",
         "//cts:__subpackages__",
@@ -34,6 +36,7 @@
 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 866aa89..8137e40 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.
 
diff --git a/packages/SystemUI/aconfig/biometrics_framework.aconfig b/packages/SystemUI/aconfig/biometrics_framework.aconfig
index 7cc0c83..bd1a442 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.
 
@@ -14,4 +15,4 @@
     namespace: "biometrics_framework"
     description: "Refactors Biometric Prompt to use a ConstraintLayout"
     bug: "288175072"
-}
\ 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/cross_device_control.aconfig b/packages/SystemUI/aconfig/cross_device_control.aconfig
index d3f14c1..5f9a4f4 100644
--- a/packages/SystemUI/aconfig/cross_device_control.aconfig
+++ b/packages/SystemUI/aconfig/cross_device_control.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.systemui"
+container: "system"
 
 flag {
     name: "legacy_le_audio_sharing"
diff --git a/packages/SystemUI/aconfig/predictive_back.aconfig b/packages/SystemUI/aconfig/predictive_back.aconfig
index 7bbe82c..46eb9e1 100644
--- a/packages/SystemUI/aconfig/predictive_back.aconfig
+++ b/packages/SystemUI/aconfig/predictive_back.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.systemui"
+container: "system"
 
 flag {
     name: "predictive_back_sysui"
@@ -26,4 +27,4 @@
     namespace: "systemui"
     description: "Enable Predictive Back Animation for SysUI dialogs"
     bug: "327721544"
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index c845ab3..f6616db 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"
@@ -25,6 +26,21 @@
 }
 
 flag {
+   name: "refactor_keyguard_dismiss_intent"
+   namespace: "systemui"
+   description: "Update how keyguard dismiss intents are stored."
+   bug: "275069969"
+}
+
+flag {
+
+    name: "notification_heads_up_cycling"
+    namespace: "systemui"
+    description: "Heads-up notification cycling animation for the Notification Avalanche feature."
+    bug: "316404716"
+}
+
+flag {
    name: "notification_minimalism_prototype"
    namespace: "systemui"
    description: "Prototype of notification minimalism; the new 'Intermediate' lockscreen customization proposal."
@@ -692,6 +708,16 @@
 }
 
 flag {
+  name: "screenshare_notification_hiding_bug_fix"
+  namespace: "systemui"
+  description: "Various bug fixes for notification redaction while screensharing"
+  bug: "312784809"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
     name: "qs_ui_refactor"
     namespace: "systemui"
     description: "Enables the new QS UI pipeline that follows recommended architecture and uses"
diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp
index a6d750f..dec664f 100644
--- a/packages/SystemUI/animation/Android.bp
+++ b/packages/SystemUI/animation/Android.bp
@@ -47,7 +47,8 @@
         "com_android_systemui_flags_lib",
         "SystemUIShaderLib",
         "WindowManager-Shell-shared",
-        "animationlib",
+        "//frameworks/libs/systemui:animationlib",
+        "//frameworks/libs/systemui:com_android_systemui_shared_flags_lib",
     ],
 
     manifest: "AndroidManifest.xml",
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
index ea1cb34..9ce30fd 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
@@ -790,7 +790,7 @@
                     controller,
                     endState,
                     windowBackgroundColor,
-                    fadeOutWindowBackgroundLayer = !controller.isBelowAnimatingWindow,
+                    fadeWindowBackgroundLayer = !controller.isBelowAnimatingWindow,
                     drawHole = !controller.isBelowAnimatingWindow,
                 )
         }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogTransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogTransitionAnimator.kt
index 24cc8a4..b89ebfc 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/DialogTransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/DialogTransitionAnimator.kt
@@ -916,6 +916,12 @@
                         endController.transitionContainer = value
                     }
 
+                // We tell TransitionController that this is always a launch, and handle the launch
+                // vs return logic internally.
+                // TODO(b/323863002): maybe move the launch vs return logic out of this class and
+                //     delegate it to TransitionController?
+                override val isLaunching: Boolean = true
+
                 override fun createAnimatorState(): TransitionAnimator.State {
                     return startController.createAnimatorState()
                 }
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewTransitionAnimatorController.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewTransitionAnimatorController.kt
index 3f57f88..9ad0fc5 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewTransitionAnimatorController.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewTransitionAnimatorController.kt
@@ -64,6 +64,7 @@
     private var interactionJankMonitor: InteractionJankMonitor =
         InteractionJankMonitor.getInstance(),
 ) : ActivityTransitionAnimator.Controller {
+    override val isLaunching: Boolean = true
 
     /** The container to which we will add the ghost view and expanding background. */
     override var transitionContainer = ghostedView.rootView as ViewGroup
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
index 5e4276c..9bf6b34 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/TransitionAnimator.kt
@@ -28,7 +28,9 @@
 import android.view.View
 import android.view.ViewGroup
 import android.view.animation.Interpolator
+import androidx.annotation.VisibleForTesting
 import com.android.app.animation.Interpolators.LINEAR
+import com.android.systemui.shared.Flags.returnAnimationFrameworkLibrary
 import kotlin.math.roundToInt
 
 private const val TAG = "TransitionAnimator"
@@ -70,13 +72,14 @@
     interface Controller {
         /**
          * The container in which the view that started the animation will be animating together
-         * with the opening window.
+         * with the opening or closing window.
          *
          * This will be used to:
          * - Get the associated [Context].
-         * - Compute whether we are expanding fully above the transition container.
-         * - Get to overlay to which we initially put the window background layer, until the opening
-         *   window is made visible (see [openingWindowSyncView]).
+         * - Compute whether we are expanding to or contracting from fully above the transition
+         *   container.
+         * - Get the overlay into which we put the window background layer, while the animating
+         *   window is not visible (see [openingWindowSyncView]).
          *
          * This container can be changed to force this [Controller] to animate the expanding view
          * inside a different location, for instance to ensure correct layering during the
@@ -84,12 +87,17 @@
          */
         var transitionContainer: ViewGroup
 
+        /** Whether the animation being controlled is a launch or a return. */
+        val isLaunching: Boolean
+
         /**
-         * The [View] with which the opening app window should be synchronized with once it starts
-         * to be visible.
+         * If [isLaunching], the [View] with which the opening app window should be synchronized
+         * once it starts to be visible. Otherwise, the [View] with which the closing app window
+         * should be synchronized until it stops being visible.
          *
          * We will also move the window background layer to this view's overlay once the opening
-         * window is visible.
+         * window is visible (if [isLaunching]), or from this view's overlay once the closing window
+         * stop being visible (if ![isLaunching]).
          *
          * If null, this will default to [transitionContainer].
          */
@@ -203,17 +211,56 @@
      * layer with [windowBackgroundColor] will fade in then (optionally) fade out above the
      * expanding view, and should be the same background color as the opening (or closing) window.
      *
-     * If [fadeOutWindowBackgroundLayer] is true, then this intermediary layer will fade out during
-     * the second half of the animation, and will have SRC blending mode (ultimately punching a hole
-     * in the [transition container][Controller.transitionContainer]) iff [drawHole] is true.
+     * If [fadeWindowBackgroundLayer] is true, then this intermediary layer will fade out during the
+     * second half of the animation (if [Controller.isLaunching] or fade in during the first half of
+     * the animation (if ![Controller.isLaunching]), and will have SRC blending mode (ultimately
+     * punching a hole in the [transition container][Controller.transitionContainer]) iff [drawHole]
+     * is true.
      */
     fun startAnimation(
         controller: Controller,
         endState: State,
         windowBackgroundColor: Int,
-        fadeOutWindowBackgroundLayer: Boolean = true,
+        fadeWindowBackgroundLayer: Boolean = true,
         drawHole: Boolean = false,
     ): Animation {
+        if (!controller.isLaunching) checkReturnAnimationFrameworkFlag()
+
+        // We add an extra layer with the same color as the dialog/app splash screen background
+        // color, which is usually the same color of the app background. We first fade in this layer
+        // to hide the expanding view, then we fade it out with SRC mode to draw a hole in the
+        // transition container and reveal the opening window.
+        val windowBackgroundLayer =
+            GradientDrawable().apply {
+                setColor(windowBackgroundColor)
+                alpha = 0
+            }
+
+        val animator =
+            createAnimator(
+                controller,
+                endState,
+                windowBackgroundLayer,
+                fadeWindowBackgroundLayer,
+                drawHole
+            )
+        animator.start()
+
+        return object : Animation {
+            override fun cancel() {
+                animator.cancel()
+            }
+        }
+    }
+
+    @VisibleForTesting
+    fun createAnimator(
+        controller: Controller,
+        endState: State,
+        windowBackgroundLayer: GradientDrawable,
+        fadeWindowBackgroundLayer: Boolean = true,
+        drawHole: Boolean = false
+    ): ValueAnimator {
         val state = controller.createAnimatorState()
 
         // Start state.
@@ -255,31 +302,24 @@
         val transitionContainer = controller.transitionContainer
         val isExpandingFullyAbove = isExpandingFullyAbove(transitionContainer, endState)
 
-        // We add an extra layer with the same color as the dialog/app splash screen background
-        // color, which is usually the same color of the app background. We first fade in this layer
-        // to hide the expanding view, then we fade it out with SRC mode to draw a hole in the
-        // transition container and reveal the opening window.
-        val windowBackgroundLayer =
-            GradientDrawable().apply {
-                setColor(windowBackgroundColor)
-                alpha = 0
-            }
-
         // Update state.
         val animator = ValueAnimator.ofFloat(0f, 1f)
         animator.duration = timings.totalDuration
         animator.interpolator = LINEAR
 
         // Whether we should move the [windowBackgroundLayer] into the overlay of
-        // [Controller.openingWindowSyncView] once the opening app window starts to be visible.
+        // [Controller.openingWindowSyncView] once the opening app window starts to be visible, or
+        // from it once the closing app window stops being visible.
+        // This is necessary as a one-off sync so we can avoid syncing at every frame, especially
+        // in complex interactions like launching an activity from a dialog. See
+        // b/214961273#comment2 for more details.
         val openingWindowSyncView = controller.openingWindowSyncView
         val openingWindowSyncViewOverlay = openingWindowSyncView?.overlay
-        val moveBackgroundLayerWhenAppIsVisible =
+        val moveBackgroundLayerWhenAppVisibilityChanges =
             openingWindowSyncView != null &&
                 openingWindowSyncView.viewRootImpl != controller.transitionContainer.viewRootImpl
 
         val transitionContainerOverlay = transitionContainer.overlay
-        var cancelled = false
         var movedBackgroundLayer = false
 
         animator.addListener(
@@ -293,7 +333,11 @@
                     // Add the drawable to the transition container overlay. Overlays always draw
                     // drawables after views, so we know that it will be drawn above any view added
                     // by the controller.
-                    transitionContainerOverlay.add(windowBackgroundLayer)
+                    if (controller.isLaunching || openingWindowSyncViewOverlay == null) {
+                        transitionContainerOverlay.add(windowBackgroundLayer)
+                    } else {
+                        openingWindowSyncViewOverlay.add(windowBackgroundLayer)
+                    }
                 }
 
                 override fun onAnimationEnd(animation: Animator) {
@@ -303,7 +347,7 @@
                     controller.onTransitionAnimationEnd(isExpandingFullyAbove)
                     transitionContainerOverlay.remove(windowBackgroundLayer)
 
-                    if (moveBackgroundLayerWhenAppIsVisible) {
+                    if (moveBackgroundLayerWhenAppVisibilityChanges && controller.isLaunching) {
                         openingWindowSyncViewOverlay?.remove(windowBackgroundLayer)
                     }
                 }
@@ -311,12 +355,6 @@
         )
 
         animator.addUpdateListener { animation ->
-            if (cancelled) {
-                // TODO(b/184121838): Cancel the animator directly instead of just skipping the
-                // update.
-                return@addUpdateListener
-            }
-
             maybeUpdateEndState()
 
             // TODO(b/184121838): Use reverse interpolators to get the same path/arc as the non
@@ -338,20 +376,34 @@
             state.bottomCornerRadius =
                 MathUtils.lerp(startBottomCornerRadius, endBottomCornerRadius, progress)
 
-            // The expanding view can/should be hidden once it is completely covered by the opening
-            // window.
             state.visible =
-                getProgress(
-                    timings,
-                    linearProgress,
-                    timings.contentBeforeFadeOutDelay,
-                    timings.contentBeforeFadeOutDuration
-                ) < 1
+                if (controller.isLaunching) {
+                    // The expanding view can/should be hidden once it is completely covered by the
+                    // opening window.
+                    getProgress(
+                        timings,
+                        linearProgress,
+                        timings.contentBeforeFadeOutDelay,
+                        timings.contentBeforeFadeOutDuration
+                    ) < 1
+                } else {
+                    getProgress(
+                        timings,
+                        linearProgress,
+                        timings.contentAfterFadeInDelay,
+                        timings.contentAfterFadeInDuration
+                    ) > 0
+                }
 
-            if (moveBackgroundLayerWhenAppIsVisible && !state.visible && !movedBackgroundLayer) {
-                // The expanding view is not visible, so the opening app is visible. If this is the
-                // first frame when it happens, trigger a one-off sync and move the background layer
-                // in its new container.
+            if (
+                controller.isLaunching &&
+                    moveBackgroundLayerWhenAppVisibilityChanges &&
+                    !state.visible &&
+                    !movedBackgroundLayer
+            ) {
+                // The expanding view is not visible, so the opening app is visible. If this is
+                // the first frame when it happens, trigger a one-off sync and move the
+                // background layer in its new container.
                 movedBackgroundLayer = true
 
                 transitionContainerOverlay.remove(windowBackgroundLayer)
@@ -362,6 +414,25 @@
                     openingWindowSyncView,
                     then = {}
                 )
+            } else if (
+                !controller.isLaunching &&
+                    moveBackgroundLayerWhenAppVisibilityChanges &&
+                    state.visible &&
+                    !movedBackgroundLayer
+            ) {
+                // The contracting view is now visible, so the closing app is not. If this is
+                // the first frame when it happens, trigger a one-off sync and move the
+                // background layer in its new container.
+                movedBackgroundLayer = true
+
+                openingWindowSyncViewOverlay!!.remove(windowBackgroundLayer)
+                transitionContainerOverlay.add(windowBackgroundLayer)
+
+                ViewRootSync.synchronizeNextDraw(
+                    openingWindowSyncView,
+                    transitionContainer,
+                    then = {}
+                )
             }
 
             val container =
@@ -376,19 +447,14 @@
                 state,
                 linearProgress,
                 container,
-                fadeOutWindowBackgroundLayer,
-                drawHole
+                fadeWindowBackgroundLayer,
+                drawHole,
+                controller.isLaunching
             )
             controller.onTransitionAnimationProgress(state, progress, linearProgress)
         }
 
-        animator.start()
-        return object : Animation {
-            override fun cancel() {
-                cancelled = true
-                animator.cancel()
-            }
-        }
+        return animator
     }
 
     /** Return whether we are expanding fully above the [transitionContainer]. */
@@ -405,8 +471,9 @@
         state: State,
         linearProgress: Float,
         transitionContainer: View,
-        fadeOutWindowBackgroundLayer: Boolean,
-        drawHole: Boolean
+        fadeWindowBackgroundLayer: Boolean,
+        drawHole: Boolean,
+        isLaunching: Boolean
     ) {
         // Update position.
         transitionContainer.getLocationOnScreen(transitionContainerLocation)
@@ -437,27 +504,64 @@
                 timings.contentBeforeFadeOutDelay,
                 timings.contentBeforeFadeOutDuration
             )
-        if (fadeInProgress < 1) {
-            val alpha =
-                interpolators.contentBeforeFadeOutInterpolator.getInterpolation(fadeInProgress)
-            drawable.alpha = (alpha * 0xFF).roundToInt()
-        } else if (fadeOutWindowBackgroundLayer) {
-            val fadeOutProgress =
-                getProgress(
-                    timings,
-                    linearProgress,
-                    timings.contentAfterFadeInDelay,
-                    timings.contentAfterFadeInDuration
-                )
-            val alpha =
-                1 - interpolators.contentAfterFadeInInterpolator.getInterpolation(fadeOutProgress)
-            drawable.alpha = (alpha * 0xFF).roundToInt()
 
-            if (drawHole) {
-                drawable.setXfermode(SRC_MODE)
+        if (isLaunching) {
+            if (fadeInProgress < 1) {
+                val alpha =
+                    interpolators.contentBeforeFadeOutInterpolator.getInterpolation(fadeInProgress)
+                drawable.alpha = (alpha * 0xFF).roundToInt()
+            } else if (fadeWindowBackgroundLayer) {
+                val fadeOutProgress =
+                    getProgress(
+                        timings,
+                        linearProgress,
+                        timings.contentAfterFadeInDelay,
+                        timings.contentAfterFadeInDuration
+                    )
+                val alpha =
+                    1 -
+                        interpolators.contentAfterFadeInInterpolator.getInterpolation(
+                            fadeOutProgress
+                        )
+                drawable.alpha = (alpha * 0xFF).roundToInt()
+
+                if (drawHole) {
+                    drawable.setXfermode(SRC_MODE)
+                }
+            } else {
+                drawable.alpha = 0xFF
             }
         } else {
-            drawable.alpha = 0xFF
+            if (fadeInProgress < 1 && fadeWindowBackgroundLayer) {
+                val alpha =
+                    interpolators.contentBeforeFadeOutInterpolator.getInterpolation(fadeInProgress)
+                drawable.alpha = (alpha * 0xFF).roundToInt()
+
+                if (drawHole) {
+                    drawable.setXfermode(SRC_MODE)
+                }
+            } else {
+                val fadeOutProgress =
+                    getProgress(
+                        timings,
+                        linearProgress,
+                        timings.contentAfterFadeInDelay,
+                        timings.contentAfterFadeInDuration
+                    )
+                val alpha =
+                    1 -
+                        interpolators.contentAfterFadeInInterpolator.getInterpolation(
+                            fadeOutProgress
+                        )
+                drawable.alpha = (alpha * 0xFF).roundToInt()
+                drawable.setXfermode(null)
+            }
+        }
+    }
+
+    private fun checkReturnAnimationFrameworkFlag() {
+        check(returnAnimationFrameworkLibrary()) {
+            "isLaunching cannot be false when the returnAnimationFrameworkLibrary flag is disabled"
         }
     }
 }
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
index 974ee3a..c7f0a96 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
@@ -168,6 +168,9 @@
 
             override var transitionContainer: ViewGroup = composeViewRoot.rootView as ViewGroup
 
+            // TODO(b/323863002): update to be dependant on usage.
+            override val isLaunching: Boolean = true
+
             override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) {
                 animatorState.value = null
             }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
index ed80277..32c0313 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt
@@ -17,9 +17,11 @@
 package com.android.systemui.communal.ui.compose
 
 import android.appwidget.AppWidgetHostView
+import android.content.res.Configuration
 import android.graphics.drawable.Icon
 import android.os.Bundle
 import android.util.SizeF
+import android.view.ViewGroup
 import android.widget.FrameLayout
 import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.animation.core.animateFloatAsState
@@ -92,6 +94,7 @@
 import androidx.compose.ui.layout.onGloballyPositioned
 import androidx.compose.ui.layout.onSizeChanged
 import androidx.compose.ui.layout.positionInWindow
+import androidx.compose.ui.platform.LocalConfiguration
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.platform.testTag
@@ -110,8 +113,6 @@
 import androidx.compose.ui.window.Popup
 import androidx.core.view.setPadding
 import androidx.window.layout.WindowMetricsCalculator
-import com.android.compose.modifiers.height
-import com.android.compose.modifiers.padding
 import com.android.compose.modifiers.thenIf
 import com.android.compose.theme.LocalAndroidColorScheme
 import com.android.compose.ui.graphics.painter.rememberDrawablePainter
@@ -364,7 +365,7 @@
             liveContentKeys.indexOfFirst { !prevLiveContentKeys.contains(it) }
 
         // Scroll if current position is behind the first updated content
-        if (indexOfFirstUpdatedContent in 0..<gridState.firstVisibleItemIndex) {
+        if (indexOfFirstUpdatedContent in 0 until gridState.firstVisibleItemIndex) {
             // Launching with a scope to prevent the job from being canceled in the case of a
             // recomposition during scrolling
             coroutineScope.launch { gridState.animateScrollToItem(indexOfFirstUpdatedContent) }
@@ -834,6 +835,13 @@
     widgetConfigurator: WidgetConfigurator?,
     modifier: Modifier = Modifier,
 ) {
+    var widgetId: Int by remember { mutableStateOf(-1) }
+    var configuration: Configuration? by remember { mutableStateOf(null) }
+
+    // In addition to returning the current configuration, this also causes a recompose on
+    // configuration change.
+    val currentConfiguration = LocalConfiguration.current
+
     Box(
         modifier =
             modifier.thenIf(!viewModel.isEditMode && model.inQuietMode) {
@@ -849,18 +857,48 @@
         AndroidView(
             modifier = Modifier.fillMaxSize().allowGestures(allowed = !viewModel.isEditMode),
             factory = { context ->
-                model.appWidgetHost
-                    .createViewForCommunal(context, model.appWidgetId, model.providerInfo)
-                    .apply {
-                        updateAppWidgetSize(Bundle.EMPTY, listOf(size))
-                        // Remove the extra padding applied to AppWidgetHostView to allow widgets to
-                        // occupy the entire box.
-                        setPadding(0)
-                    }
+                // This FrameLayout becomes the container view for the AppWidgetHostView we add as a
+                // child in update below. Having a container view allows for updating the contained
+                // host view as needed (e.g. on configuration changes).
+                FrameLayout(context).apply {
+                    layoutParams =
+                        ViewGroup.LayoutParams(
+                            ViewGroup.LayoutParams.MATCH_PARENT,
+                            ViewGroup.LayoutParams.MATCH_PARENT
+                        )
+                    setPadding(0)
+                }
+            },
+            update = { widgetContainer: ViewGroup ->
+                if (widgetId == model.appWidgetId && currentConfiguration.equals(configuration)) {
+                    return@AndroidView
+                }
+
+                // Add the widget's host view to the FrameLayout parent (after removing any
+                // previously added host view).
+                widgetContainer.removeAllViews()
+                widgetContainer.addView(
+                    model.appWidgetHost
+                        .createViewForCommunal(
+                            widgetContainer.context,
+                            model.appWidgetId,
+                            model.providerInfo
+                        )
+                        .apply {
+                            updateAppWidgetSize(Bundle.EMPTY, listOf(size))
+                            // Remove the extra padding applied to AppWidgetHostView to allow
+                            // widgets to occupy the entire box.
+                            setPadding(0)
+                        }
+                )
+
+                widgetId = model.appWidgetId
+                configuration = currentConfiguration
             },
             // For reusing composition in lazy lists.
             onReset = {},
         )
+
         if (
             viewModel is CommunalEditModeViewModel &&
                 model.reconfigurable &&
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/BurnInState.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/BurnInState.kt
index 7a73c58..8129e41 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/BurnInState.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/blueprint/BurnInState.kt
@@ -71,7 +71,6 @@
 
     return remember(clock, topInset, topmostTop) {
         BurnInParameters(
-            clockControllerProvider = { clock },
             topInset = topInset,
             minViewY = topmostTop,
         )
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt
index 97d5b41..467dbca 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/BottomAreaSection.kt
@@ -32,6 +32,7 @@
 import com.android.compose.animation.scene.ElementKey
 import com.android.compose.animation.scene.SceneScope
 import com.android.systemui.animation.view.LaunchableImageView
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.ui.binder.KeyguardIndicationAreaBinder
 import com.android.systemui.keyguard.ui.binder.KeyguardQuickAffordanceViewBinder
 import com.android.systemui.keyguard.ui.view.KeyguardIndicationArea
@@ -43,6 +44,7 @@
 import com.android.systemui.statusbar.KeyguardIndicationController
 import com.android.systemui.statusbar.VibratorHelper
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.DisposableHandle
 import kotlinx.coroutines.flow.Flow
 
@@ -54,6 +56,7 @@
     private val vibratorHelper: VibratorHelper,
     private val indicationController: KeyguardIndicationController,
     private val indicationAreaViewModel: KeyguardIndicationAreaViewModel,
+    @Main private val mainImmediateDispatcher: CoroutineDispatcher,
 ) {
     /**
      * Renders a single lockscreen shortcut.
@@ -161,6 +164,7 @@
                         transitionAlpha,
                         falsingManager,
                         vibratorHelper,
+                        mainImmediateDispatcher,
                     ) {
                         indicationController.showTransientIndication(it)
                     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
index 1c938a6..eb389e6 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/DefaultClockSection.kt
@@ -34,7 +34,6 @@
 import androidx.core.view.contains
 import com.android.compose.animation.scene.SceneScope
 import com.android.compose.modifiers.padding
-import com.android.systemui.customization.R as customizationR
 import com.android.systemui.customization.R
 import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.largeClockElementKey
 import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys.smallClockElementKey
@@ -65,32 +64,25 @@
             return
         }
         val context = LocalContext.current
-        MovableElement(key = smallClockElementKey, modifier = modifier) {
-            content {
-                AndroidView(
-                    factory = { context ->
-                        FrameLayout(context).apply {
-                            ensureClockViewExists(checkNotNull(currentClock).smallClock.view)
-                        }
-                    },
-                    update = {
-                        it.ensureClockViewExists(checkNotNull(currentClock).smallClock.view)
-                    },
-                    modifier =
-                        Modifier.height(dimensionResource(R.dimen.small_clock_height))
-                            .padding(
-                                horizontal =
-                                    dimensionResource(customizationR.dimen.clock_padding_start)
-                            )
-                            .padding(top = { viewModel.getSmallClockTopMargin(context) })
-                            .onTopPlacementChanged(onTopChanged)
-                            .burnInAware(
-                                viewModel = aodBurnInViewModel,
-                                params = burnInParams,
-                            ),
-                )
-            }
-        }
+        AndroidView(
+            factory = { context ->
+                FrameLayout(context).apply {
+                    ensureClockViewExists(checkNotNull(currentClock).smallClock.view)
+                }
+            },
+            update = { it.ensureClockViewExists(checkNotNull(currentClock).smallClock.view) },
+            modifier =
+                modifier
+                    .height(dimensionResource(R.dimen.small_clock_height))
+                    .padding(horizontal = dimensionResource(R.dimen.clock_padding_start))
+                    .padding(top = { viewModel.getSmallClockTopMargin(context) })
+                    .onTopPlacementChanged(onTopChanged)
+                    .burnInAware(
+                        viewModel = aodBurnInViewModel,
+                        params = burnInParams,
+                    )
+                    .element(smallClockElementKey),
+        )
     }
 
     @Composable
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt
index 9f02201..48684a0 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/LockSection.kt
@@ -34,6 +34,7 @@
 import com.android.keyguard.LockIconViewController
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
 import com.android.systemui.flags.FeatureFlagsClassic
 import com.android.systemui.flags.Flags
@@ -50,12 +51,14 @@
 import com.android.systemui.statusbar.VibratorHelper
 import dagger.Lazy
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 
 class LockSection
 @Inject
 constructor(
     @Application private val applicationScope: CoroutineScope,
+    @Main private val mainImmediateDispatcher: CoroutineDispatcher,
     private val windowManager: WindowManager,
     private val authController: AuthController,
     private val featureFlags: FeatureFlagsClassic,
@@ -93,6 +96,7 @@
                                 deviceEntryBackgroundViewModel.get(),
                                 falsingManager.get(),
                                 vibratorHelper.get(),
+                                mainImmediateDispatcher,
                             )
                         }
                     } else {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt
index fa0a1c4..a31b533 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/section/NotificationSection.kt
@@ -33,7 +33,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.MigrateClocksToBlueprint
 import com.android.systemui.keyguard.ui.viewmodel.LockscreenContentViewModel
-import com.android.systemui.notifications.ui.composable.NotificationStack
+import com.android.systemui.notifications.ui.composable.ConstrainedNotificationStack
 import com.android.systemui.res.R
 import com.android.systemui.shade.LargeScreenHeaderHelper
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
@@ -94,7 +94,7 @@
             return
         }
 
-        NotificationStack(
+        ConstrainedNotificationStack(
             viewModel = viewModel,
             modifier =
                 modifier.fillMaxWidth().thenIf(shouldUseSplitNotificationShade) {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
index 9ba5e3b..579e837 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/notifications/ui/composable/Notifications.kt
@@ -36,12 +36,14 @@
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.snapshotFlow
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.draw.drawBehind
@@ -60,7 +62,6 @@
 import androidx.compose.ui.res.dimensionResource
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.IntOffset
-import androidx.compose.ui.unit.IntSize
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.util.lerp
 import com.android.compose.animation.scene.ElementKey
@@ -68,20 +69,21 @@
 import com.android.compose.animation.scene.SceneScope
 import com.android.compose.modifiers.height
 import com.android.systemui.common.ui.compose.windowinsets.LocalScreenCornerRadius
-import com.android.systemui.notifications.ui.composable.Notifications.Form
 import com.android.systemui.notifications.ui.composable.Notifications.TransitionThresholds.EXPANSION_FOR_MAX_CORNER_RADIUS
 import com.android.systemui.notifications.ui.composable.Notifications.TransitionThresholds.EXPANSION_FOR_MAX_SCRIM_ALPHA
 import com.android.systemui.res.R
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.ui.composable.ShadeHeader
-import com.android.systemui.statusbar.notification.stack.shared.model.StackRounding
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimRounding
 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
 import kotlin.math.roundToInt
 
 object Notifications {
     object Elements {
         val NotificationScrim = ElementKey("NotificationScrim")
-        val NotificationPlaceholder = ElementKey("NotificationPlaceholder")
+        val NotificationStackPlaceholder = ElementKey("NotificationStackPlaceholder")
+        val HeadsUpNotificationPlaceholder = ElementKey("HeadsUpNotificationPlaceholder")
         val ShelfSpace = ElementKey("ShelfSpace")
     }
 
@@ -91,12 +93,6 @@
         const val EXPANSION_FOR_MAX_CORNER_RADIUS = 0.1f
         const val EXPANSION_FOR_MAX_SCRIM_ALPHA = 0.3f
     }
-
-    enum class Form {
-        HunFromTop,
-        Stack,
-        HunFromBottom,
-    }
 }
 
 /**
@@ -109,24 +105,48 @@
     modifier: Modifier = Modifier,
     isPeekFromBottom: Boolean = false,
 ) {
-    NotificationPlaceholder(
-        viewModel = viewModel,
-        form = if (isPeekFromBottom) Form.HunFromBottom else Form.HunFromTop,
-        modifier = modifier,
-    )
+    val headsUpHeight = viewModel.headsUpHeight.collectAsState()
+
+    Element(
+        Notifications.Elements.HeadsUpNotificationPlaceholder,
+        modifier =
+            modifier
+                .height { headsUpHeight.value.roundToInt() }
+                .fillMaxWidth()
+                .debugBackground(viewModel, DEBUG_HUN_COLOR)
+                .onGloballyPositioned { coordinates: LayoutCoordinates ->
+                    val boundsInWindow = coordinates.boundsInWindow()
+                    debugLog(viewModel) {
+                        "HUNS onGloballyPositioned:" +
+                            " size=${coordinates.size}" +
+                            " bounds=$boundsInWindow"
+                    }
+                    viewModel.onHeadsUpTopChanged(boundsInWindow.top)
+                }
+    ) {
+        content {}
+    }
 }
 
 /** Adds the space where notification stack should appear in the scene. */
 @Composable
-fun SceneScope.NotificationStack(
+fun SceneScope.ConstrainedNotificationStack(
     viewModel: NotificationsPlaceholderViewModel,
     modifier: Modifier = Modifier,
 ) {
-    NotificationPlaceholder(
-        viewModel = viewModel,
-        form = Form.Stack,
-        modifier = modifier,
-    )
+    Box(
+        modifier =
+            modifier.onSizeChanged { viewModel.onConstrainedAvailableSpaceChanged(it.height) }
+    ) {
+        NotificationPlaceholder(
+            viewModel = viewModel,
+            modifier = Modifier.fillMaxSize(),
+        )
+        HeadsUpNotificationSpace(
+            viewModel = viewModel,
+            modifier = Modifier.align(Alignment.TopCenter),
+        )
+    }
 }
 
 /**
@@ -157,9 +177,9 @@
                 .toPx()
         } + navBarHeight
 
-    val contentHeight = viewModel.intrinsicContentHeight.collectAsState()
+    val stackHeight = viewModel.stackHeight.collectAsState()
 
-    val stackRounding = viewModel.stackRounding.collectAsState(StackRounding())
+    val scrimRounding = viewModel.shadeScrimRounding.collectAsState(ShadeScrimRounding())
 
     // the offset for the notifications scrim. Its upper bound is 0, and its lower bound is
     // calculated in minScrimOffset. The scrim is the same height as the screen minus the
@@ -169,6 +189,9 @@
     // entire height of the scrim is visible on screen.
     val scrimOffset = remember { mutableStateOf(0f) }
 
+    // set the bounds to null when the scrim disappears
+    DisposableEffect(Unit) { onDispose { viewModel.onScrimBoundsChanged(null) } }
+
     val minScrimTop = with(density) { ShadeHeader.Dimensions.CollapsedHeight.toPx() }
 
     // The minimum offset for the scrim. The scrim is considered fully expanded when it
@@ -186,8 +209,8 @@
 
     // if contentHeight drops below minimum visible scrim height while scrim is
     // expanded, reset scrim offset.
-    LaunchedEffect(contentHeight, scrimOffset) {
-        snapshotFlow { contentHeight.value < minVisibleScrimHeight() && scrimOffset.value < 0f }
+    LaunchedEffect(stackHeight, scrimOffset) {
+        snapshotFlow { stackHeight.value < minVisibleScrimHeight() && scrimOffset.value < 0f }
             .collect { shouldCollapse -> if (shouldCollapse) scrimOffset.value = 0f }
     }
 
@@ -232,9 +255,25 @@
                                 { expansionFraction },
                                 layoutState.isTransitioningBetween(Scenes.Gone, Scenes.Shade)
                             )
-                            .let { stackRounding.value.toRoundedCornerShape(it) }
+                            .let { scrimRounding.value.toRoundedCornerShape(it) }
                     clip = true
                 }
+                .onGloballyPositioned { coordinates ->
+                    val boundsInWindow = coordinates.boundsInWindow()
+                    debugLog(viewModel) {
+                        "SCRIM onGloballyPositioned:" +
+                            " size=${coordinates.size}" +
+                            " bounds=$boundsInWindow"
+                    }
+                    viewModel.onScrimBoundsChanged(
+                        ShadeScrimBounds(
+                            left = boundsInWindow.left,
+                            top = boundsInWindow.top,
+                            right = boundsInWindow.right,
+                            bottom = boundsInWindow.bottom,
+                        )
+                    )
+                }
     ) {
         // Creates a cutout in the background scrim in the shape of the notifications scrim.
         // Only visible when notif scrim alpha < 1, during shade expansion.
@@ -254,11 +293,10 @@
                             } else 1f
                     }
                     .background(MaterialTheme.colorScheme.surface)
-                    .debugBackground(viewModel, Color(0.5f, 0.5f, 0f, 0.2f))
+                    .debugBackground(viewModel, DEBUG_BOX_COLOR)
         ) {
             NotificationPlaceholder(
                 viewModel = viewModel,
-                form = Form.Stack,
                 modifier =
                     Modifier.verticalNestedScrollToScene(
                             topBehavior = NestedScrollBehavior.EdgeWithPreview,
@@ -274,16 +312,17 @@
                                     onScrimOffsetChanged = { scrimOffset.value = it },
                                     minScrimOffset = minScrimOffset,
                                     maxScrimOffset = 0f,
-                                    contentHeight = { contentHeight.value },
+                                    contentHeight = { stackHeight.value },
                                     minVisibleScrimHeight = minVisibleScrimHeight,
                                 )
                             }
                         )
                         .verticalScroll(scrollState)
                         .fillMaxWidth()
-                        .height { (contentHeight.value + navBarHeight).roundToInt() },
+                        .height { (stackHeight.value + navBarHeight).roundToInt() },
             )
         }
+        HeadsUpNotificationSpace(viewModel = viewModel)
     }
 }
 
@@ -304,14 +343,10 @@
         modifier
             .element(key = Notifications.Elements.ShelfSpace)
             .fillMaxWidth()
-            .onSizeChanged { size: IntSize ->
-                debugLog(viewModel) { "SHELF onSizeChanged: size=$size" }
-            }
             .onPlaced { coordinates: LayoutCoordinates ->
                 debugLog(viewModel) {
                     ("SHELF onPlaced:" +
                         " size=${coordinates.size}" +
-                        " position=${coordinates.positionInWindow()}" +
                         " bounds=${coordinates.boundsInWindow()}")
                 }
             }
@@ -326,32 +361,26 @@
 @Composable
 private fun SceneScope.NotificationPlaceholder(
     viewModel: NotificationsPlaceholderViewModel,
-    form: Form,
     modifier: Modifier = Modifier,
 ) {
-    val elementKey = Notifications.Elements.NotificationPlaceholder
     Element(
-        elementKey,
+        Notifications.Elements.NotificationStackPlaceholder,
         modifier =
             modifier
-                .debugBackground(viewModel)
-                .onSizeChanged { size: IntSize ->
-                    debugLog(viewModel) { "STACK onSizeChanged: size=$size" }
-                }
+                .debugBackground(viewModel, DEBUG_STACK_COLOR)
+                .onSizeChanged { size -> debugLog(viewModel) { "STACK onSizeChanged: size=$size" } }
                 .onGloballyPositioned { coordinates: LayoutCoordinates ->
-                    viewModel.onContentTopChanged(coordinates.positionInWindow().y)
+                    val positionInWindow = coordinates.positionInWindow()
                     debugLog(viewModel) {
                         "STACK onGloballyPositioned:" +
                             " size=${coordinates.size}" +
-                            " position=${coordinates.positionInWindow()}" +
+                            " position=$positionInWindow" +
                             " bounds=${coordinates.boundsInWindow()}"
                     }
-                    val boundsInWindow = coordinates.boundsInWindow()
-                    viewModel.onBoundsChanged(
-                        left = boundsInWindow.left,
-                        top = boundsInWindow.top,
-                        right = boundsInWindow.right,
-                        bottom = boundsInWindow.bottom,
+                    // NOTE: positionInWindow.y scrolls off screen, but boundsInWindow.top will not
+                    viewModel.onStackBoundsChanged(
+                        top = positionInWindow.y,
+                        bottom = positionInWindow.y + coordinates.size.height,
                     )
                 }
     ) {
@@ -388,7 +417,7 @@
 
 private fun Modifier.debugBackground(
     viewModel: NotificationsPlaceholderViewModel,
-    color: Color = DEBUG_COLOR,
+    color: Color,
 ): Modifier =
     if (viewModel.isVisualDebuggingEnabled) {
         background(color)
@@ -396,9 +425,9 @@
         this
     }
 
-fun StackRounding.toRoundedCornerShape(radius: Dp): RoundedCornerShape {
-    val topRadius = if (roundTop) radius else 0.dp
-    val bottomRadius = if (roundBottom) radius else 0.dp
+fun ShadeScrimRounding.toRoundedCornerShape(radius: Dp): RoundedCornerShape {
+    val topRadius = if (isTopRounded) radius else 0.dp
+    val bottomRadius = if (isBottomRounded) radius else 0.dp
     return RoundedCornerShape(
         topStart = topRadius,
         topEnd = topRadius,
@@ -408,4 +437,6 @@
 }
 
 private const val TAG = "FlexiNotifs"
-private val DEBUG_COLOR = Color(1f, 0f, 0f, 0.2f)
+private val DEBUG_STACK_COLOR = Color(1f, 0f, 0f, 0.2f)
+private val DEBUG_HUN_COLOR = Color(0f, 0f, 1f, 0.2f)
+private val DEBUG_BOX_COLOR = Color(0f, 1f, 0f, 0.2f)
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
index 5b9213a..244f480 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.qs.ui.composable
 
 import android.view.ViewGroup
+import androidx.activity.compose.BackHandler
 import androidx.compose.animation.AnimatedVisibility
 import androidx.compose.animation.core.tween
 import androidx.compose.animation.expandVertically
@@ -122,6 +123,13 @@
     // TODO(b/280887232): implement the real UI.
     Box(modifier = modifier.fillMaxSize()) {
         val isCustomizing by viewModel.qsSceneAdapter.isCustomizing.collectAsState()
+
+        BackHandler(
+            enabled = isCustomizing,
+        ) {
+            viewModel.qsSceneAdapter.requestCloseCustomizer()
+        }
+
         val collapsedHeaderHeight =
             with(LocalDensity.current) { ShadeHeader.Dimensions.CollapsedHeight.roundToPx() }
         val lifecycleOwner = LocalLifecycleOwner.current
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/anc/ui/composable/AncPopup.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/anc/ui/composable/AncPopup.kt
index b1fbe35..9f0da00 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/anc/ui/composable/AncPopup.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/anc/ui/composable/AncPopup.kt
@@ -19,6 +19,7 @@
 import android.content.Context
 import android.view.ContextThemeWrapper
 import android.view.View
+import androidx.compose.foundation.basicMarquee
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Text
@@ -55,6 +56,7 @@
     @Composable
     private fun Title() {
         Text(
+            modifier = Modifier.basicMarquee(),
             text = stringResource(R.string.volume_panel_noise_control_title),
             style = MaterialTheme.typography.titleMedium,
             textAlign = TextAlign.Center,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/button/ui/composable/ButtonComponent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/button/ui/composable/ButtonComponent.kt
index b721e41..8f187cc 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/button/ui/composable/ButtonComponent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/button/ui/composable/ButtonComponent.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.volume.panel.component.button.ui.composable
 
 import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.basicMarquee
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
@@ -37,7 +38,6 @@
 import androidx.compose.ui.semantics.contentDescription
 import androidx.compose.ui.semantics.role
 import androidx.compose.ui.semantics.semantics
-import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.dp
 import com.android.compose.animation.Expandable
 import com.android.systemui.animation.Expandable
@@ -81,11 +81,10 @@
                 }
             }
             Text(
-                modifier = Modifier.clearAndSetSemantics {},
+                modifier = Modifier.clearAndSetSemantics {}.basicMarquee(),
                 text = label,
                 style = MaterialTheme.typography.labelMedium,
-                maxLines = 1,
-                overflow = TextOverflow.Ellipsis,
+                maxLines = 2,
             )
         }
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/button/ui/composable/ToggleButtonComponent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/button/ui/composable/ToggleButtonComponent.kt
index 28fd785..51ec63b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/button/ui/composable/ToggleButtonComponent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/button/ui/composable/ToggleButtonComponent.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.volume.panel.component.button.ui.composable
 
 import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.basicMarquee
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxWidth
@@ -32,10 +33,11 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.semantics.Role
 import androidx.compose.ui.semantics.clearAndSetSemantics
 import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.role
 import androidx.compose.ui.semantics.semantics
-import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.dp
 import com.android.systemui.common.ui.compose.Icon
 import com.android.systemui.volume.panel.component.button.ui.viewmodel.ToggleButtonViewModel
@@ -62,7 +64,10 @@
         ) {
             OutlinedIconToggleButton(
                 modifier =
-                    Modifier.height(64.dp).fillMaxWidth().semantics { contentDescription = label },
+                    Modifier.height(64.dp).fillMaxWidth().semantics {
+                        role = Role.Switch
+                        contentDescription = label
+                    },
                 checked = viewModel.isChecked,
                 onCheckedChange = onCheckedChange,
                 shape = RoundedCornerShape(28.dp),
@@ -78,11 +83,10 @@
                 Icon(modifier = Modifier.size(24.dp), icon = viewModel.icon)
             }
             Text(
-                modifier = Modifier.clearAndSetSemantics {},
+                modifier = Modifier.clearAndSetSemantics {}.basicMarquee(),
                 text = label,
                 style = MaterialTheme.typography.labelMedium,
-                maxLines = 1,
-                overflow = TextOverflow.Ellipsis,
+                maxLines = 2,
             )
         }
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/popup/ui/composable/VolumePanelPopup.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/popup/ui/composable/VolumePanelPopup.kt
index 26086d1..9f9bc62 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/popup/ui/composable/VolumePanelPopup.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/popup/ui/composable/VolumePanelPopup.kt
@@ -33,6 +33,8 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.paneTitle
+import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.unit.dp
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.animation.Expandable
@@ -82,7 +84,8 @@
         title: @Composable (SystemUIDialog) -> Unit,
         content: @Composable (SystemUIDialog) -> Unit,
     ) {
-        Box(Modifier.fillMaxWidth()) {
+        val paneTitle = stringResource(R.string.accessibility_volume_settings)
+        Box(Modifier.fillMaxWidth().semantics(properties = { this.paneTitle = paneTitle })) {
             Column(
                 modifier = Modifier.fillMaxWidth().padding(vertical = 20.dp),
                 verticalArrangement = Arrangement.spacedBy(20.dp),
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/selector/ui/composable/VolumePanelRadioButtons.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/selector/ui/composable/VolumePanelRadioButtons.kt
index 98d1afd..e2d7d11 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/selector/ui/composable/VolumePanelRadioButtons.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/selector/ui/composable/VolumePanelRadioButtons.kt
@@ -19,10 +19,13 @@
 import androidx.compose.animation.core.Animatable
 import androidx.compose.animation.core.VectorConverter
 import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.RowScope
 import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.offset
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.shape.CornerSize
@@ -32,6 +35,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.Layout
@@ -108,9 +112,17 @@
                 horizontalArrangement = Arrangement.spacedBy(spacing)
             ) {
                 for (itemIndex in items.indices) {
-                    TextButton(
-                        modifier = Modifier.weight(1f),
-                        onClick = { items[itemIndex].onItemSelected() },
+                    Row(
+                        modifier =
+                            Modifier.height(48.dp)
+                                .weight(1f)
+                                .clickable(
+                                    interactionSource = null,
+                                    indication = null,
+                                    onClick = { items[itemIndex].onItemSelected() }
+                                ),
+                        horizontalArrangement = Arrangement.Center,
+                        verticalAlignment = Alignment.CenterVertically,
                     ) {
                         val item = items[itemIndex]
                         if (item.icon !== Empty) {
@@ -130,9 +142,12 @@
                 horizontalArrangement = Arrangement.spacedBy(spacing),
             ) {
                 for (itemIndex in items.indices) {
+                    val cornersRadius = 4.dp
                     TextButton(
                         modifier = Modifier.weight(1f),
                         onClick = { items[itemIndex].onItemSelected() },
+                        shape = RoundedCornerShape(cornersRadius),
+                        contentPadding = PaddingValues(cornersRadius)
                     ) {
                         val item = items[itemIndex]
                         if (item.icon !== Empty) {
@@ -246,7 +261,7 @@
     val DefaultSpacing = 24.dp
     val DefaultLabelIndicatorBackgroundSpacing = 12.dp
     val DefaultIndicatorCornerRadius = 20.dp
-    val DefaultIndicatorBackgroundCornerRadius = 20.dp
+    val DefaultIndicatorBackgroundCornerRadius = 28.dp
 
     /**
      * Returns the default VolumePanelRadioButtonBar colors.
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/spatialaudio/ui/composable/SpatialAudioPopup.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/spatialaudio/ui/composable/SpatialAudioPopup.kt
index 71b3e8a..6673afd 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/spatialaudio/ui/composable/SpatialAudioPopup.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/spatialaudio/ui/composable/SpatialAudioPopup.kt
@@ -16,12 +16,14 @@
 
 package com.android.systemui.volume.panel.component.spatialaudio.ui.composable
 
+import androidx.compose.foundation.basicMarquee
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.text.style.TextAlign
 import com.android.systemui.animation.Expandable
@@ -49,6 +51,7 @@
     @Composable
     private fun Title() {
         Text(
+            modifier = Modifier.basicMarquee(),
             text = stringResource(R.string.volume_panel_spatial_audio_title),
             style = MaterialTheme.typography.titleMedium,
             textAlign = TextAlign.Center,
@@ -82,9 +85,12 @@
                     },
                     label = {
                         Text(
+                            modifier = Modifier.basicMarquee(),
                             text = buttonViewModel.button.label.toString(),
                             style = MaterialTheme.typography.labelMedium,
                             color = buttonViewModel.labelColor.toColor(),
+                            textAlign = TextAlign.Center,
+                            maxLines = 2
                         )
                     }
                 )
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt
index e1cf3a5..f89669c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt
@@ -28,9 +28,8 @@
 import androidx.compose.animation.scaleIn
 import androidx.compose.animation.scaleOut
 import androidx.compose.animation.shrinkVertically
-import androidx.compose.animation.slideInVertically
-import androidx.compose.animation.slideOutVertically
 import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxWidth
@@ -57,6 +56,8 @@
 
 private const val EXPAND_DURATION_MILLIS = 500
 private const val COLLAPSE_DURATION_MILLIS = 300
+private const val SHRINK_FRACTION = 0.55f
+private const val SCALE_FRACTION = 0.9f
 
 /** Volume sliders laid out in a collapsable column */
 @OptIn(ExperimentalAnimationApi::class)
@@ -107,34 +108,33 @@
         transition.AnimatedVisibility(
             visible = { it },
             enter =
-                expandVertically(
-                    animationSpec = tween(durationMillis = EXPAND_DURATION_MILLIS),
-                    expandFrom = Alignment.CenterVertically,
-                ),
+                expandVertically(animationSpec = tween(durationMillis = EXPAND_DURATION_MILLIS)),
             exit =
-                shrinkVertically(
-                    animationSpec = tween(durationMillis = COLLAPSE_DURATION_MILLIS),
-                    shrinkTowards = Alignment.CenterVertically,
-                ),
+                shrinkVertically(animationSpec = tween(durationMillis = COLLAPSE_DURATION_MILLIS)),
         ) {
-            Column(modifier = Modifier.fillMaxWidth()) {
-                for (index in 1..viewModels.lastIndex) {
-                    val sliderViewModel: SliderViewModel = viewModels[index]
-                    val sliderState by sliderViewModel.slider.collectAsState()
-                    transition.AnimatedVisibility(
-                        visible = { it },
-                        enter = enterTransition(index = index, totalCount = viewModels.size),
-                        exit = exitTransition(index = index, totalCount = viewModels.size)
-                    ) {
-                        VolumeSlider(
-                            modifier = Modifier.fillMaxWidth().padding(top = 16.dp),
-                            state = sliderState,
-                            onValueChange = { newValue: Float ->
-                                sliderViewModel.onValueChanged(sliderState, newValue)
-                            },
-                            onIconTapped = { sliderViewModel.toggleMuted(sliderState) },
-                            sliderColors = sliderColors,
-                        )
+            // This box allows sliders to slide towards top when the container is shrinking and
+            // slide from top when the container is expanding.
+            Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.BottomCenter) {
+                Column {
+                    for (index in 1..viewModels.lastIndex) {
+                        val sliderViewModel: SliderViewModel = viewModels[index]
+                        val sliderState by sliderViewModel.slider.collectAsState()
+                        transition.AnimatedVisibility(
+                            modifier = Modifier.padding(top = 16.dp),
+                            visible = { it },
+                            enter = enterTransition(index = index, totalCount = viewModels.size),
+                            exit = exitTransition(index = index, totalCount = viewModels.size)
+                        ) {
+                            VolumeSlider(
+                                modifier = Modifier.fillMaxWidth(),
+                                state = sliderState,
+                                onValueChange = { newValue: Float ->
+                                    sliderViewModel.onValueChanged(sliderState, newValue)
+                                },
+                                onIconTapped = { sliderViewModel.toggleMuted(sliderState) },
+                                sliderColors = sliderColors,
+                            )
+                        }
                     }
                 }
             }
@@ -175,19 +175,14 @@
 private fun enterTransition(index: Int, totalCount: Int): EnterTransition {
     val enterDelay = ((totalCount - index + 1) * 10).coerceAtLeast(0)
     val enterDuration = (EXPAND_DURATION_MILLIS - enterDelay).coerceAtLeast(100)
-    return slideInVertically(
-        initialOffsetY = { (it * 0.25).toInt() },
+    return scaleIn(
+        initialScale = SCALE_FRACTION,
         animationSpec = tween(durationMillis = enterDuration, delayMillis = enterDelay),
     ) +
-        scaleIn(
-            initialScale = 0.9f,
-            animationSpec = tween(durationMillis = enterDuration, delayMillis = enterDelay),
-        ) +
         expandVertically(
-            initialHeight = { (it * 0.65).toInt() },
+            initialHeight = { (it * SHRINK_FRACTION).toInt() },
             animationSpec = tween(durationMillis = enterDuration, delayMillis = enterDelay),
             clip = false,
-            expandFrom = Alignment.CenterVertically,
         ) +
         fadeIn(
             animationSpec = tween(durationMillis = enterDuration, delayMillis = enterDelay),
@@ -196,19 +191,14 @@
 
 private fun exitTransition(index: Int, totalCount: Int): ExitTransition {
     val exitDuration = (COLLAPSE_DURATION_MILLIS - (totalCount - index + 1) * 10).coerceAtLeast(100)
-    return slideOutVertically(
-        targetOffsetY = { (it * 0.25).toInt() },
+    return scaleOut(
+        targetScale = SCALE_FRACTION,
         animationSpec = tween(durationMillis = exitDuration),
     ) +
-        scaleOut(
-            targetScale = 0.9f,
-            animationSpec = tween(durationMillis = exitDuration),
-        ) +
         shrinkVertically(
-            targetHeight = { (it * 0.65).toInt() },
+            targetHeight = { (it * SHRINK_FRACTION).toInt() },
             animationSpec = tween(durationMillis = exitDuration),
             clip = false,
-            shrinkTowards = Alignment.CenterVertically,
         ) +
         fadeOut(animationSpec = tween(durationMillis = exitDuration))
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
index d31064a..19d3f59 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
@@ -17,10 +17,10 @@
 package com.android.systemui.volume.panel.component.volume.ui.composable
 
 import androidx.compose.animation.core.animateFloatAsState
+import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.size
-import androidx.compose.material3.IconButton
-import androidx.compose.material3.IconButtonColors
 import androidx.compose.material3.LocalContentColor
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
@@ -32,7 +32,6 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.semantics.ProgressBarRangeInfo
 import androidx.compose.ui.semantics.clearAndSetSemantics
 import androidx.compose.ui.semantics.contentDescription
@@ -130,24 +129,20 @@
     isTappable: Boolean,
     modifier: Modifier = Modifier
 ) {
-    if (isTappable) {
-        IconButton(
-            modifier = modifier,
-            onClick = onIconTapped,
-            colors =
-                IconButtonColors(
-                    contentColor = LocalContentColor.current,
-                    containerColor = Color.Transparent,
-                    disabledContentColor = LocalContentColor.current,
-                    disabledContainerColor = Color.Transparent,
-                ),
-            content = { Icon(modifier = Modifier.size(24.dp), icon = icon) },
-        )
-    } else {
-        Box(
-            modifier = modifier,
-            contentAlignment = Alignment.Center,
-            content = { Icon(modifier = Modifier.size(24.dp), icon = icon) },
-        )
-    }
+    val boxModifier =
+        if (isTappable) {
+                modifier.clickable(
+                    onClick = onIconTapped,
+                    interactionSource = null,
+                    indication = null
+                )
+            } else {
+                modifier
+            }
+            .fillMaxSize()
+    Box(
+        modifier = boxModifier,
+        contentAlignment = Alignment.Center,
+        content = { Icon(modifier = Modifier.size(24.dp), icon = icon) },
+    )
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VerticalVolumePanelContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VerticalVolumePanelContent.kt
index dd76781..9ea20b9 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VerticalVolumePanelContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VerticalVolumePanelContent.kt
@@ -20,6 +20,7 @@
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.wrapContentHeight
 import androidx.compose.foundation.rememberScrollState
@@ -27,6 +28,7 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastSumBy
 import com.android.systemui.volume.panel.ui.layout.ComponentsLayout
 
 @Composable
@@ -53,6 +55,14 @@
                 modifier = Modifier.fillMaxWidth().wrapContentHeight(),
                 horizontalArrangement = Arrangement.spacedBy(if (isLargeScreen) 28.dp else 20.dp),
             ) {
+                val visibleComponentsCount =
+                    layout.footerComponents.fastSumBy { if (it.isVisible) 1 else 0 }
+
+                // Center footer component if there is only one present
+                if (visibleComponentsCount == 1) {
+                    Spacer(modifier = Modifier.weight(0.5f))
+                }
+
                 for (component in layout.footerComponents) {
                     AnimatedVisibility(
                         visible = component.isVisible,
@@ -63,6 +73,10 @@
                         }
                     }
                 }
+
+                if (visibleComponentsCount == 1) {
+                    Spacer(modifier = Modifier.weight(0.5f))
+                }
             }
         }
     }
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
index e7cb5a4..a8a1d88 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/Element.kt
@@ -261,16 +261,19 @@
     scene: Scene,
     element: Element,
 ): Boolean {
-    val transition = layoutImpl.state.currentTransition
+    val transition = layoutImpl.state.currentTransition ?: return true
 
-    // Always draw the element if there is no ongoing transition or if the element is not shared or
-    // if the current scene is the one that is currently over scrolling with [OverscrollSpec].
-    if (
-        transition == null ||
-            transition.fromScene !in element.sceneStates ||
-            transition.toScene !in element.sceneStates ||
-            transition.currentOverscrollSpec?.scene == scene.key
-    ) {
+    val inFromScene = transition.fromScene in element.sceneStates
+    val inToScene = transition.toScene in element.sceneStates
+
+    // If an element is not present in any scene, it should not be drawn.
+    if (!inFromScene && !inToScene) {
+        return false
+    }
+
+    // Always draw if the element is not shared or if the current scene is the one that is currently
+    // over scrolling with [OverscrollSpec].
+    if (!inFromScene || !inToScene || transition.currentOverscrollSpec?.scene == scene.key) {
         return true
     }
 
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
index 2453e25..458a2b9 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/ElementTest.kt
@@ -45,6 +45,7 @@
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.layout.intermediateLayout
 import androidx.compose.ui.platform.LocalViewConfiguration
+import androidx.compose.ui.test.assertIsNotDisplayed
 import androidx.compose.ui.test.assertTopPositionInRootIsEqualTo
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onNodeWithTag
@@ -175,6 +176,60 @@
     }
 
     @Test
+    fun elementsNotInTransition_shouldNotBeDrawn() {
+        val nFrames = 20
+        val frameDuration = 16L
+        val tween = tween<Float>(nFrames * frameDuration.toInt())
+        val layoutSize = 100.dp
+        val elementSize = 50.dp
+        val elementOffset = 20.dp
+
+        lateinit var changeScene: (SceneKey) -> Unit
+
+        rule.testTransition(
+            from = TestScenes.SceneA,
+            to = TestScenes.SceneB,
+            transitionLayout = { currentScene, onChangeScene ->
+                changeScene = onChangeScene
+
+                SceneTransitionLayout(
+                    currentScene,
+                    onChangeScene,
+                    transitions {
+                        from(TestScenes.SceneA, to = TestScenes.SceneB) { spec = tween }
+                        from(TestScenes.SceneB, to = TestScenes.SceneC) { spec = tween }
+                    },
+                ) {
+                    scene(TestScenes.SceneA) {
+                        Box(Modifier.size(layoutSize)) {
+                            // Transformed element
+                            Element(
+                                TestElements.Bar,
+                                elementSize,
+                                elementOffset,
+                            )
+                        }
+                    }
+                    scene(TestScenes.SceneB) { Box(Modifier.size(layoutSize)) }
+                    scene(TestScenes.SceneC) { Box(Modifier.size(layoutSize)) }
+                }
+            },
+        ) {
+            // Start transition from SceneA to SceneB
+            at(1 * frameDuration) {
+                onElement(TestElements.Bar).assertExists()
+
+                // Start transition from SceneB to SceneC
+                changeScene(TestScenes.SceneC)
+            }
+
+            at(2 * frameDuration) { onElement(TestElements.Bar).assertIsNotDisplayed() }
+
+            at(3 * frameDuration) { onElement(TestElements.Bar).assertDoesNotExist() }
+        }
+    }
+
+    @Test
     fun onlyMovingElements_noLayout_onlyPlacement() {
         val nFrames = 20
         val layoutSize = 100.dp
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
index e086cda..003c572 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
@@ -190,12 +190,20 @@
         refreshFormat()
     }
 
+    override fun setTextSize(type: Int, size: Float) {
+        super.setTextSize(type, size)
+        if (type == TypedValue.COMPLEX_UNIT_PX) {
+            lastUnconstrainedTextSize = size
+        }
+    }
+
     @SuppressLint("DrawAllocation")
     override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
         logger.d("onMeasure")
         if (migratedClocks && !isSingleLineInternal &&
                 MeasureSpec.getMode(heightMeasureSpec) == EXACTLY) {
-            setTextSize(TypedValue.COMPLEX_UNIT_PX,
+            // Call straight into TextView.setTextSize to avoid setting lastUnconstrainedTextSize
+            super.setTextSize(TypedValue.COMPLEX_UNIT_PX,
                     min(lastUnconstrainedTextSize, MeasureSpec.getSize(heightMeasureSpec) / 2F))
         }
         super.onMeasure(widthMeasureSpec, heightMeasureSpec)
diff --git a/packages/SystemUI/docs/scene.md b/packages/SystemUI/docs/scene.md
index 105e438..f331c9b 100644
--- a/packages/SystemUI/docs/scene.md
+++ b/packages/SystemUI/docs/scene.md
@@ -65,25 +65,23 @@
 [`SceneContainerFlags.kt`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt)
 file evalutes to `true`.
 
-1.  Set **`SCENE_CONTAINER_ENABLED`** to `true` in the
-    [`Flags.kt`](https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/packages/SystemUI/src/com/android/systemui/flags/Flags.kt)
-    file
-2.  Set the **`migrate_keyguard_status_bar_view`** classic flag to `true` by
+1.  Set the **`migrate_keyguard_status_bar_view`** classic flag to `true` by
     running: `console $ adb shell statusbar cmd migrate_keyguard_status_bar_view
     true`
-3.  Set a collection of **aconfig flags** to `true` by running the following
+2.  Set a collection of **aconfig flags** to `true` by running the following
     commands:
     ```console
     $ adb shell device_config put systemui com.android.systemui.scene_container true
+    $ adb shell device_config put systemui com.android.systemui.compose_lockscreen true
     $ adb shell device_config put systemui com.android.systemui.keyguard_bottom_area_refactor true
-    $ adb shell device_config put systemui com.android.systemui.keyguard_shade_migration_nssl true
     $ adb shell device_config put systemui com.android.systemui.media_in_scene_container true
+    $ adb shell device_config put systemui com.android.systemui.migrate_clocks_to_blueprint true
     ```
-4.  **Restart** System UI by issuing the following command:
+3.  **Restart** System UI by issuing the following command:
     ```console
     $ adb shell am crash com.android.systemui
     ```
-5.  **Verify** that the scene framework was turned on. There are two ways to do
+4.  **Verify** that the scene framework was turned on. There are two ways to do
     this:
 
     *(a)* look for the sash/ribbon UI at the bottom-right corner of the display:
diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
index 9dbeeda..1120914 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
@@ -47,15 +47,16 @@
 import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants
 import com.android.systemui.classifier.FalsingA11yDelegate
 import com.android.systemui.classifier.FalsingCollector
-import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.flags.FakeFeatureFlags
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyboard.data.repository.FakeKeyboardRepository
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.log.SessionTracker
@@ -832,7 +833,9 @@
 
             // While listening, going from the bouncer scene to the gone scene, does dismiss the
             // keyguard.
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
             runCurrent()
             fakeSceneDataSource.pause()
             sceneInteractor.changeScene(Scenes.Gone, "reason")
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
index cb8cebf..81878aa 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
@@ -179,10 +179,14 @@
                 setAutoConfirmFeatureEnabled(true)
             }
             assertThat(isAutoConfirmEnabled).isTrue()
-            val shorterPin =
-                FakeAuthenticationRepository.DEFAULT_PIN.toMutableList().apply { removeLast() }
+            val defaultPin = FakeAuthenticationRepository.DEFAULT_PIN.toMutableList()
 
-            assertSkipped(underTest.authenticate(shorterPin, tryAutoConfirm = true))
+            assertSkipped(
+                underTest.authenticate(
+                    defaultPin.subList(0, defaultPin.size - 1),
+                    tryAutoConfirm = true
+                )
+            )
             assertThat(underTest.lockoutEndTimestamp).isNull()
             assertThat(kosmos.fakeAuthenticationRepository.lockoutStartedReportCount).isEqualTo(0)
         }
@@ -201,7 +205,6 @@
 
             assertFailed(
                 underTest.authenticate(wrongPin, tryAutoConfirm = true),
-                assertNoResultEvents = true,
             )
         }
 
@@ -219,7 +222,6 @@
 
             assertFailed(
                 underTest.authenticate(longerPin, tryAutoConfirm = true),
-                assertNoResultEvents = true,
             )
         }
 
@@ -547,14 +549,9 @@
 
     private fun assertFailed(
         authenticationResult: AuthenticationResult,
-        assertNoResultEvents: Boolean = false,
     ) {
         assertThat(authenticationResult).isEqualTo(AuthenticationResult.FAILED)
-        if (assertNoResultEvents) {
-            assertThat(onAuthenticationResult).isNull()
-        } else {
-            assertThat(onAuthenticationResult).isFalse()
-        }
+        assertThat(onAuthenticationResult).isFalse()
     }
 
     private fun assertSkipped(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt
index 16ec9aa..f9f7df8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModelTest.kt
@@ -122,7 +122,6 @@
             repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT) {
                 bouncerInteractor.authenticate(WRONG_PIN)
             }
-            assertThat(message?.isUpdateAnimated).isFalse()
 
             val lockoutEndMs = authenticationInteractor.lockoutEndTimestamp ?: 0
             advanceTimeBy(lockoutEndMs - testScope.currentTime)
@@ -133,6 +132,7 @@
     fun lockoutMessage() =
         testScope.runTest {
             val message by collectLastValue(underTest.message)
+            val lockoutSeconds = FakeAuthenticationRepository.LOCKOUT_DURATION_SECONDS
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(Pin)
             assertThat(kosmos.fakeAuthenticationRepository.lockoutEndTimestamp).isNull()
             runCurrent()
@@ -140,14 +140,14 @@
             repeat(FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT) { times ->
                 bouncerInteractor.authenticate(WRONG_PIN)
                 runCurrent()
-                if (times < FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT - 1) {
+                if (times == FakeAuthenticationRepository.MAX_FAILED_AUTH_TRIES_BEFORE_LOCKOUT) {
+                    assertTryAgainMessage(message?.text, lockoutSeconds)
+                    assertThat(message?.isUpdateAnimated).isFalse()
+                } else {
                     assertThat(message?.text).isEqualTo("Wrong PIN. Try again.")
                     assertThat(message?.isUpdateAnimated).isTrue()
                 }
             }
-            val lockoutSeconds = FakeAuthenticationRepository.LOCKOUT_DURATION_SECONDS
-            assertTryAgainMessage(message?.text, lockoutSeconds)
-            assertThat(message?.isUpdateAnimated).isFalse()
 
             repeat(FakeAuthenticationRepository.LOCKOUT_DURATION_SECONDS) { time ->
                 advanceTimeBy(1.seconds)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
index 71c5785..c28cf34 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
 import com.android.systemui.inputmethod.data.model.InputMethodModel
 import com.android.systemui.inputmethod.data.repository.fakeInputMethodRepository
 import com.android.systemui.inputmethod.domain.interactor.inputMethodInteractor
@@ -153,7 +152,6 @@
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.Password
             )
-            kosmos.fakeDeviceEntryRepository.setUnlocked(false)
             switchToScene(Scenes.Bouncer)
 
             // No input entered.
@@ -329,7 +327,6 @@
         kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
             AuthenticationMethodModel.Password
         )
-        kosmos.fakeDeviceEntryRepository.setUnlocked(false)
         switchToScene(Scenes.Bouncer)
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
index 51b73ee9..14d3634 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PatternBouncerViewModelTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.authentication.shared.model.AuthenticationPatternCoordinate as Point
 import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.res.R
 import com.android.systemui.scene.domain.interactor.sceneInteractor
@@ -373,7 +372,6 @@
         kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
             AuthenticationMethodModel.Pattern
         )
-        kosmos.fakeDeviceEntryRepository.setUnlocked(false)
         switchToScene(Scenes.Bouncer)
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
index 5647954..5bb36a0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModelTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.bouncer.domain.interactor.bouncerInteractor
 import com.android.systemui.bouncer.domain.interactor.simBouncerInteractor
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.res.R
 import com.android.systemui.scene.domain.interactor.sceneInteractor
@@ -253,7 +252,14 @@
     @Test
     fun onAutoConfirm_whenCorrect() =
         testScope.runTest {
+            // TODO(b/332768183) remove this after the bug if fixed.
+            // Collect the flow so that it is hot, in the real application this is done by using a
+            // refreshingFlow that relies on the UI to make this flow hot.
+            val autoConfirmEnabled by
+                collectLastValue(authenticationInteractor.isAutoConfirmEnabled)
             kosmos.fakeAuthenticationRepository.setAutoConfirmFeatureEnabled(true)
+
+            assertThat(autoConfirmEnabled).isTrue()
             val authResult by collectLastValue(authenticationInteractor.onAuthenticationResult)
             lockDeviceAndOpenPinBouncer()
 
@@ -265,9 +271,17 @@
     @Test
     fun onAutoConfirm_whenWrong() =
         testScope.runTest {
+            // TODO(b/332768183) remove this after the bug if fixed.
+            // Collect the flow so that it is hot, in the real application this is done by using a
+            // refreshingFlow that relies on the UI to make this flow hot.
+            val autoConfirmEnabled by
+                collectLastValue(authenticationInteractor.isAutoConfirmEnabled)
+
             val currentScene by collectLastValue(sceneInteractor.currentScene)
             val pin by collectLastValue(underTest.pinInput.map { it.getPin() })
             kosmos.fakeAuthenticationRepository.setAutoConfirmFeatureEnabled(true)
+
+            assertThat(autoConfirmEnabled).isTrue()
             lockDeviceAndOpenPinBouncer()
 
             FakeAuthenticationRepository.DEFAULT_PIN.dropLast(1).forEach { digit ->
@@ -387,7 +401,6 @@
 
     private fun TestScope.lockDeviceAndOpenPinBouncer() {
         kosmos.fakeAuthenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
-        kosmos.fakeDeviceEntryRepository.setUnlocked(false)
         switchToScene(Scenes.Bouncer)
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/BrightnessPolicyRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/BrightnessPolicyRepositoryImplTest.kt
new file mode 100644
index 0000000..312c14d
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/BrightnessPolicyRepositoryImplTest.kt
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.data.repository
+
+import android.content.applicationContext
+import android.os.UserManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.user.data.repository.fakeUserRepository
+import com.android.systemui.user.data.repository.userRepository
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.utils.PolicyRestriction
+import com.android.systemui.utils.UserRestrictionChecker
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyString
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BrightnessPolicyRepositoryImplTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+
+    private val fakeUserRepository = kosmos.fakeUserRepository
+
+    private val mockUserRestrictionChecker: UserRestrictionChecker = mock {
+        whenever(checkIfRestrictionEnforced(any(), anyString(), anyInt())).thenReturn(null)
+        whenever(hasBaseUserRestriction(any(), anyString(), anyInt())).thenReturn(false)
+    }
+
+    private val underTest =
+        with(kosmos) {
+            BrightnessPolicyRepositoryImpl(
+                userRepository,
+                mockUserRestrictionChecker,
+                applicationContext,
+                testDispatcher,
+            )
+        }
+
+    @Test
+    fun noRestrictionByDefaultForAllUsers() =
+        with(kosmos) {
+            testScope.runTest {
+                val restrictions by collectLastValue(underTest.restrictionPolicy)
+
+                assertThat(restrictions).isEqualTo(PolicyRestriction.NoRestriction)
+
+                fakeUserRepository.asMainUser()
+
+                assertThat(restrictions).isEqualTo(PolicyRestriction.NoRestriction)
+            }
+        }
+
+    @Test
+    fun restrictDefaultUser() =
+        with(kosmos) {
+            testScope.runTest {
+                val enforcedAdmin: EnforcedAdmin =
+                    EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(RESTRICTION)
+
+                whenever(
+                        mockUserRestrictionChecker.checkIfRestrictionEnforced(
+                            any(),
+                            eq(RESTRICTION),
+                            eq(userRepository.getSelectedUserInfo().id)
+                        )
+                    )
+                    .thenReturn(enforcedAdmin)
+
+                val restrictions by collectLastValue(underTest.restrictionPolicy)
+
+                assertThat(restrictions).isEqualTo(PolicyRestriction.Restricted(enforcedAdmin))
+
+                fakeUserRepository.asMainUser()
+
+                assertThat(restrictions).isEqualTo(PolicyRestriction.NoRestriction)
+            }
+        }
+
+    @Test
+    fun restrictMainUser() =
+        with(kosmos) {
+            testScope.runTest {
+                val enforcedAdmin: EnforcedAdmin =
+                    EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(RESTRICTION)
+
+                whenever(
+                        mockUserRestrictionChecker.checkIfRestrictionEnforced(
+                            any(),
+                            eq(RESTRICTION),
+                            eq(userRepository.mainUserId)
+                        )
+                    )
+                    .thenReturn(enforcedAdmin)
+
+                val restrictions by collectLastValue(underTest.restrictionPolicy)
+
+                assertThat(restrictions).isEqualTo(PolicyRestriction.NoRestriction)
+
+                fakeUserRepository.asMainUser()
+
+                assertThat(restrictions).isEqualTo(PolicyRestriction.Restricted(enforcedAdmin))
+            }
+        }
+
+    private companion object {
+        val RESTRICTION = UserManager.DISALLOW_CONFIG_BRIGHTNESS
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt
new file mode 100644
index 0000000..e39ad4f
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/data/repository/ScreenBrightnessDisplayManagerRepositoryTest.kt
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.data.repository
+
+import android.hardware.display.BrightnessInfo
+import android.hardware.display.BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE
+import android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF
+import android.hardware.display.DisplayManager
+import android.hardware.display.DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS
+import android.view.Display
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.brightness.data.model.LinearBrightness
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyFloat
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.Mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ScreenBrightnessDisplayManagerRepositoryTest : SysuiTestCase() {
+    @Rule @JvmField val mockitoRule: MockitoRule = MockitoJUnit.rule()
+
+    private val kosmos = testKosmos()
+
+    private var currentBrightnessInfo = BrightnessInfo()
+
+    @Mock private lateinit var displayManager: DisplayManager
+    @Mock private lateinit var display: Display
+
+    private val displayId = 0
+
+    private lateinit var underTest: ScreenBrightnessDisplayManagerRepository
+
+    @Before
+    fun setUp() {
+        underTest =
+            ScreenBrightnessDisplayManagerRepository(
+                displayId,
+                displayManager,
+                kosmos.applicationCoroutineScope,
+                kosmos.testDispatcher,
+            )
+
+        whenever(displayManager.getDisplay(displayId)).thenReturn(display)
+        // Using then answer so it will be retrieved in every call
+        whenever(display.brightnessInfo).thenAnswer { currentBrightnessInfo }
+    }
+
+    @Test
+    fun startingBrightnessInfo() =
+        with(kosmos) {
+            testScope.runTest {
+                val brightness by collectLastValue(underTest.linearBrightness)
+                val minBrightness by collectLastValue(underTest.minLinearBrightness)
+                val maxBrightness by collectLastValue(underTest.maxLinearBrightness)
+                runCurrent()
+
+                assertThat(brightness?.floatValue).isEqualTo(currentBrightnessInfo.brightness)
+                assertThat(minBrightness?.floatValue)
+                    .isEqualTo(currentBrightnessInfo.brightnessMinimum)
+                assertThat(maxBrightness?.floatValue)
+                    .isEqualTo(currentBrightnessInfo.brightnessMaximum)
+            }
+        }
+
+    @Test
+    fun followsChangingBrightnessInfo() =
+        with(kosmos) {
+            testScope.runTest {
+                val listenerCaptor = argumentCaptor<DisplayManager.DisplayListener>()
+
+                val brightness by collectLastValue(underTest.linearBrightness)
+                val minBrightness by collectLastValue(underTest.minLinearBrightness)
+                val maxBrightness by collectLastValue(underTest.maxLinearBrightness)
+                runCurrent()
+
+                verify(displayManager)
+                    .registerDisplayListener(
+                        capture(listenerCaptor),
+                        eq(null),
+                        eq(EVENT_FLAG_DISPLAY_BRIGHTNESS),
+                    )
+
+                val newBrightness = BrightnessInfo(0.6f, 0.3f, 0.9f)
+                changeBrightnessInfoAndNotify(newBrightness, listenerCaptor.value)
+
+                assertThat(brightness?.floatValue).isEqualTo(currentBrightnessInfo.brightness)
+                assertThat(minBrightness?.floatValue)
+                    .isEqualTo(currentBrightnessInfo.brightnessMinimum)
+                assertThat(maxBrightness?.floatValue)
+                    .isEqualTo(currentBrightnessInfo.brightnessMaximum)
+            }
+        }
+
+    @Test
+    fun minMaxWhenNotCollecting() =
+        with(kosmos) {
+            testScope.runTest {
+                currentBrightnessInfo = BrightnessInfo(0.5f, 0.1f, 0.7f)
+                val (min, max) = underTest.getMinMaxLinearBrightness()
+                assertThat(min.floatValue).isEqualTo(currentBrightnessInfo.brightnessMinimum)
+                assertThat(max.floatValue).isEqualTo(currentBrightnessInfo.brightnessMaximum)
+            }
+        }
+
+    @Test
+    fun minMaxWhenCollecting() =
+        with(kosmos) {
+            testScope.runTest {
+                val listenerCaptor = argumentCaptor<DisplayManager.DisplayListener>()
+
+                val brightness by collectLastValue(underTest.linearBrightness)
+                runCurrent()
+
+                verify(displayManager)
+                    .registerDisplayListener(
+                        capture(listenerCaptor),
+                        eq(null),
+                        eq(EVENT_FLAG_DISPLAY_BRIGHTNESS),
+                    )
+
+                changeBrightnessInfoAndNotify(
+                    BrightnessInfo(0.5f, 0.1f, 0.7f),
+                    listenerCaptor.value
+                )
+                runCurrent()
+
+                val (min, max) = underTest.getMinMaxLinearBrightness()
+                assertThat(min.floatValue).isEqualTo(currentBrightnessInfo.brightnessMinimum)
+                assertThat(max.floatValue).isEqualTo(currentBrightnessInfo.brightnessMaximum)
+            }
+        }
+
+    @Test
+    fun setTemporaryBrightness_insideBounds() =
+        with(kosmos) {
+            testScope.runTest {
+                val brightness = 0.3f
+                underTest.setTemporaryBrightness(LinearBrightness(brightness))
+                runCurrent()
+
+                verify(displayManager).setTemporaryBrightness(displayId, brightness)
+                verify(displayManager, never()).setBrightness(anyInt(), anyFloat())
+            }
+        }
+
+    @Test
+    fun setTemporaryBrightness_outsideBounds() =
+        with(kosmos) {
+            testScope.runTest {
+                val brightness = 1.3f
+                underTest.setTemporaryBrightness(LinearBrightness(brightness))
+                runCurrent()
+
+                verify(displayManager)
+                    .setTemporaryBrightness(displayId, currentBrightnessInfo.brightnessMaximum)
+                verify(displayManager, never()).setBrightness(anyInt(), anyFloat())
+            }
+        }
+
+    @Test
+    fun setBrightness_insideBounds() =
+        with(kosmos) {
+            testScope.runTest {
+                val brightness = 0.3f
+                underTest.setBrightness(LinearBrightness(brightness))
+                runCurrent()
+
+                verify(displayManager).setBrightness(displayId, brightness)
+                verify(displayManager, never()).setTemporaryBrightness(anyInt(), anyFloat())
+            }
+        }
+
+    @Test
+    fun setBrightness_outsideBounds() =
+        with(kosmos) {
+            testScope.runTest {
+                val brightness = 1.3f
+                underTest.setBrightness(LinearBrightness(brightness))
+                runCurrent()
+
+                verify(displayManager)
+                    .setBrightness(displayId, currentBrightnessInfo.brightnessMaximum)
+                verify(displayManager, never()).setTemporaryBrightness(anyInt(), anyFloat())
+            }
+        }
+
+    private fun changeBrightnessInfoAndNotify(
+        newValue: BrightnessInfo,
+        listener: DisplayManager.DisplayListener,
+    ) {
+        currentBrightnessInfo = newValue
+        listener.onDisplayChanged(displayId)
+    }
+
+    companion object {
+        fun BrightnessInfo(
+            brightness: Float = 0f,
+            minBrightness: Float = 0f,
+            maxBrightness: Float = 1f,
+        ): BrightnessInfo {
+            return BrightnessInfo(
+                brightness,
+                minBrightness,
+                maxBrightness,
+                HIGH_BRIGHTNESS_MODE_OFF,
+                1f,
+                BRIGHTNESS_MAX_REASON_NONE,
+            )
+        }
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/domain/interactor/BrightnessPolicyEnforcementInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/domain/interactor/BrightnessPolicyEnforcementInteractorTest.kt
new file mode 100644
index 0000000..85a4bcf
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/domain/interactor/BrightnessPolicyEnforcementInteractorTest.kt
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.domain.interactor
+
+import android.content.ComponentName
+import android.content.Intent
+import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.settingslib.RestrictedLockUtils
+import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.brightness.data.repository.BrightnessPolicyRepository
+import com.android.systemui.brightness.data.repository.brightnessPolicyRepository
+import com.android.systemui.brightness.data.repository.fakeBrightnessPolicyRepository
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.plugins.activityStarter
+import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.utils.PolicyRestriction
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BrightnessPolicyEnforcementInteractorTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+
+    private val mockActivityStarter = kosmos.activityStarter
+    private val fakeBrightnessPolicyEnforcementInteractor = kosmos.fakeBrightnessPolicyRepository
+
+    private val underTest =
+        with(kosmos) {
+            BrightnessPolicyEnforcementInteractor(
+                brightnessPolicyRepository,
+                activityStarter,
+            )
+        }
+
+    @Test
+    fun restriction() =
+        with(kosmos) {
+            testScope.runTest {
+                fakeBrightnessPolicyRepository.setCurrentUserUnrestricted()
+
+                val restriction by collectLastValue(underTest.brightnessPolicyRestriction)
+
+                assertThat(restriction).isEqualTo(PolicyRestriction.NoRestriction)
+
+                fakeBrightnessPolicyRepository.setCurrentUserRestricted()
+
+                assertThat(restriction).isInstanceOf(PolicyRestriction.Restricted::class.java)
+            }
+        }
+
+    @Test
+    fun startRestrictionDialog() =
+        with(kosmos) {
+            testScope.runTest {
+                val enforcedAdmin =
+                    EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(
+                            BrightnessPolicyRepository.RESTRICTION
+                        )
+                        .apply {
+                            component = TEST_COMPONENT
+                            user = UserHandle.of(TEST_USER)
+                        }
+
+                underTest.startAdminSupportDetailsDialog(
+                    PolicyRestriction.Restricted(enforcedAdmin)
+                )
+
+                val intentCaptor = argumentCaptor<Intent>()
+
+                verify(mockActivityStarter)
+                    .postStartActivityDismissingKeyguard(
+                        capture(intentCaptor),
+                        eq(0),
+                    )
+
+                val expectedIntent =
+                    RestrictedLockUtils.getShowAdminSupportDetailsIntent(enforcedAdmin)
+
+                with(intentCaptor.value) {
+                    assertThat(action).isEqualTo(expectedIntent.action)
+                    assertThat(extras!!.kindofEquals(expectedIntent.extras)).isTrue()
+                }
+            }
+        }
+
+    private companion object {
+        val TEST_COMPONENT = ComponentName("pkg", ".cls")
+        val TEST_USER = 10
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractorTest.kt
new file mode 100644
index 0000000..33c44f8
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractorTest.kt
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.domain.interactor
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.settingslib.display.BrightnessUtils
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.brightness.data.model.LinearBrightness
+import com.android.systemui.brightness.data.repository.fakeScreenBrightnessRepository
+import com.android.systemui.brightness.data.repository.screenBrightnessRepository
+import com.android.systemui.brightness.shared.GammaBrightness
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ScreenBrightnessInteractorTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+
+    private val underTest = ScreenBrightnessInteractor(kosmos.screenBrightnessRepository)
+
+    @Test
+    fun gammaBrightness() =
+        with(kosmos) {
+            testScope.runTest {
+                val gammaBrightness by collectLastValue(underTest.gammaBrightness)
+
+                val brightness = 0.3f
+                val min = 0f
+                val max = 1f
+
+                with(fakeScreenBrightnessRepository) {
+                    setBrightness(LinearBrightness(brightness))
+                    setMinMaxBrightness(LinearBrightness(min), LinearBrightness(max))
+                }
+                runCurrent()
+
+                assertThat(gammaBrightness?.value)
+                    .isEqualTo(BrightnessUtils.convertLinearToGammaFloat(brightness, min, max))
+            }
+        }
+
+    @Test
+    fun gammaBrightness_constrained() =
+        with(kosmos) {
+            testScope.runTest {
+                val gammaBrightness by collectLastValue(underTest.gammaBrightness)
+
+                val brightness = 0.3f
+                val min = 0.2f
+                val max = 0.8f
+
+                with(fakeScreenBrightnessRepository) {
+                    setBrightness(LinearBrightness(brightness))
+                    setMinMaxBrightness(LinearBrightness(min), LinearBrightness(max))
+                }
+                runCurrent()
+
+                assertThat(gammaBrightness?.value)
+                    .isEqualTo(BrightnessUtils.convertLinearToGammaFloat(brightness, min, max))
+            }
+        }
+
+    @Test
+    fun setTemporaryBrightness() =
+        with(kosmos) {
+            testScope.runTest {
+                val temporaryBrightness by
+                    collectLastValue(fakeScreenBrightnessRepository.temporaryBrightness)
+                val brightness by collectLastValue(underTest.gammaBrightness)
+
+                val gammaBrightness = 30000
+                underTest.setTemporaryBrightness(GammaBrightness(gammaBrightness))
+
+                val (min, max) = fakeScreenBrightnessRepository.getMinMaxLinearBrightness()
+
+                val expectedTemporaryBrightness =
+                    BrightnessUtils.convertGammaToLinearFloat(
+                        gammaBrightness,
+                        min.floatValue,
+                        max.floatValue
+                    )
+                assertThat(temporaryBrightness!!.floatValue)
+                    .isWithin(1e-5f)
+                    .of(expectedTemporaryBrightness)
+                assertThat(brightness!!.value).isNotEqualTo(gammaBrightness)
+            }
+        }
+
+    @Test
+    fun setBrightness() =
+        with(kosmos) {
+            testScope.runTest {
+                val brightness by collectLastValue(fakeScreenBrightnessRepository.linearBrightness)
+
+                val gammaBrightness = 30000
+                underTest.setBrightness(GammaBrightness(gammaBrightness))
+
+                val (min, max) = fakeScreenBrightnessRepository.getMinMaxLinearBrightness()
+
+                val expectedBrightness =
+                    BrightnessUtils.convertGammaToLinearFloat(
+                        gammaBrightness,
+                        min.floatValue,
+                        max.floatValue
+                    )
+                assertThat(brightness!!.floatValue).isWithin(1e-5f).of(expectedBrightness)
+            }
+        }
+
+    @Test
+    fun maxGammaBrightness() {
+        assertThat(underTest.maxGammaBrightness)
+            .isEqualTo(GammaBrightness(BrightnessUtils.GAMMA_SPACE_MAX))
+    }
+
+    @Test
+    fun minGammaBrightness() {
+        assertThat(underTest.minGammaBrightness)
+            .isEqualTo(GammaBrightness(BrightnessUtils.GAMMA_SPACE_MIN))
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt
new file mode 100644
index 0000000..0058ee4
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModelTest.kt
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.ui.viewmodel
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.settingslib.display.BrightnessUtils
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.brightness.data.model.LinearBrightness
+import com.android.systemui.brightness.data.repository.fakeScreenBrightnessRepository
+import com.android.systemui.brightness.domain.interactor.brightnessPolicyEnforcementInteractor
+import com.android.systemui.brightness.domain.interactor.screenBrightnessInteractor
+import com.android.systemui.brightness.shared.GammaBrightness
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.common.shared.model.Text
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BrightnessSliderViewModelTest : SysuiTestCase() {
+
+    private val minBrightness = 0f
+    private val maxBrightness = 1f
+
+    private val kosmos = testKosmos()
+
+    private val underTest =
+        with(kosmos) {
+            BrightnessSliderViewModel(
+                screenBrightnessInteractor,
+                brightnessPolicyEnforcementInteractor,
+            )
+        }
+
+    @Before
+    fun setUp() {
+        kosmos.fakeScreenBrightnessRepository.setMinMaxBrightness(
+            LinearBrightness(minBrightness),
+            LinearBrightness(maxBrightness)
+        )
+    }
+
+    @Test
+    fun brightnessChangeInRepository_changeInFlow() =
+        with(kosmos) {
+            testScope.runTest {
+                val gammaBrightness by collectLastValue(underTest.currentBrightness)
+
+                var brightness = 0.6f
+                fakeScreenBrightnessRepository.setBrightness(LinearBrightness(brightness))
+
+                assertThat(gammaBrightness!!.value)
+                    .isEqualTo(
+                        BrightnessUtils.convertLinearToGammaFloat(
+                            brightness,
+                            minBrightness,
+                            maxBrightness
+                        )
+                    )
+
+                brightness = 0.2f
+                fakeScreenBrightnessRepository.setBrightness(LinearBrightness(brightness))
+
+                assertThat(gammaBrightness!!.value)
+                    .isEqualTo(
+                        BrightnessUtils.convertLinearToGammaFloat(
+                            brightness,
+                            minBrightness,
+                            maxBrightness
+                        )
+                    )
+            }
+        }
+
+    @Test
+    fun maxGammaBrightness() {
+        assertThat(underTest.maxBrightness)
+            .isEqualTo(GammaBrightness(BrightnessUtils.GAMMA_SPACE_MAX))
+    }
+
+    @Test
+    fun minGammaBrightness() {
+        assertThat(underTest.minBrightness)
+            .isEqualTo(GammaBrightness(BrightnessUtils.GAMMA_SPACE_MIN))
+    }
+
+    @Test
+    fun dragging_temporaryBrightnessSet_currentBrightnessDoesntChange() =
+        with(kosmos) {
+            testScope.runTest {
+                val temporaryBrightness by
+                    collectLastValue(fakeScreenBrightnessRepository.temporaryBrightness)
+                val brightness by collectLastValue(underTest.currentBrightness)
+
+                val newBrightness = underTest.maxBrightness.value / 3
+                val expectedTemporaryBrightness =
+                    BrightnessUtils.convertGammaToLinearFloat(
+                        newBrightness,
+                        minBrightness,
+                        maxBrightness
+                    )
+                val drag = Drag.Dragging(GammaBrightness(newBrightness))
+
+                underTest.onDrag(drag)
+
+                assertThat(temporaryBrightness!!.floatValue)
+                    .isWithin(1e-5f)
+                    .of(expectedTemporaryBrightness)
+                assertThat(brightness!!.value).isNotEqualTo(newBrightness)
+            }
+        }
+
+    @Test
+    fun draggingStopped_currentBrightnessChanges() =
+        with(kosmos) {
+            testScope.runTest {
+                val brightness by collectLastValue(underTest.currentBrightness)
+
+                val newBrightness = underTest.maxBrightness.value / 3
+                val drag = Drag.Stopped(GammaBrightness(newBrightness))
+
+                underTest.onDrag(drag)
+
+                assertThat(brightness!!.value).isEqualTo(newBrightness)
+            }
+        }
+
+    @Test
+    fun label() {
+        assertThat(underTest.label)
+            .isEqualTo(Text.Resource(R.string.quick_settings_brightness_dialog_title))
+    }
+
+    @Test
+    fun icon() {
+        assertThat(underTest.icon)
+            .isEqualTo(
+                Icon.Resource(
+                    R.drawable.ic_brightness_full,
+                    ContentDescription.Resource(underTest.label.res),
+                )
+            )
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalPrefsRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalPrefsRepositoryImplTest.kt
index 6bff0dc7..5e120b5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalPrefsRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalPrefsRepositoryImplTest.kt
@@ -16,11 +16,15 @@
 
 package com.android.systemui.communal.data.repository
 
+import android.content.Context
+import android.content.Intent
 import android.content.SharedPreferences
 import android.content.pm.UserInfo
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.backup.BackupHelper
+import com.android.systemui.broadcast.broadcastDispatcher
 import com.android.systemui.communal.data.repository.CommunalPrefsRepositoryImpl.Companion.FILE_NAME
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.testDispatcher
@@ -34,16 +38,22 @@
 import com.android.systemui.util.FakeSharedPreferences
 import com.google.common.truth.Truth.assertThat
 import java.io.File
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.atLeastOnce
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@android.platform.test.annotations.EnabledOnRavenwood
 class CommunalPrefsRepositoryImplTest : SysuiTestCase() {
     @Mock private lateinit var tableLogBuffer: TableLogBuffer
 
@@ -69,20 +79,12 @@
                     USER_INFOS[1].id to FakeSharedPreferences()
                 )
             )
-        underTest =
-            CommunalPrefsRepositoryImpl(
-                testScope.backgroundScope,
-                kosmos.testDispatcher,
-                userRepository,
-                userFileManager,
-                logcatLogBuffer("CommunalPrefsRepositoryImplTest"),
-                tableLogBuffer,
-            )
     }
 
     @Test
     fun isCtaDismissedValue_byDefault_isFalse() =
         testScope.runTest {
+            underTest = createCommunalPrefsRepositoryImpl(userFileManager)
             val isCtaDismissed by collectLastValue(underTest.isCtaDismissed)
             assertThat(isCtaDismissed).isFalse()
         }
@@ -90,6 +92,7 @@
     @Test
     fun isCtaDismissedValue_onSet_isTrue() =
         testScope.runTest {
+            underTest = createCommunalPrefsRepositoryImpl(userFileManager)
             val isCtaDismissed by collectLastValue(underTest.isCtaDismissed)
 
             underTest.setCtaDismissedForCurrentUser()
@@ -99,6 +102,7 @@
     @Test
     fun isCtaDismissedValue_whenSwitchUser() =
         testScope.runTest {
+            underTest = createCommunalPrefsRepositoryImpl(userFileManager)
             val isCtaDismissed by collectLastValue(underTest.isCtaDismissed)
             underTest.setCtaDismissedForCurrentUser()
 
@@ -118,6 +122,44 @@
             assertThat(isCtaDismissed).isTrue()
         }
 
+    @Test
+    fun getSharedPreferences_whenFileRestored() =
+        testScope.runTest {
+            val userFileManagerSpy = Mockito.spy(userFileManager)
+            underTest = createCommunalPrefsRepositoryImpl(userFileManagerSpy)
+
+            val isCtaDismissed by collectLastValue(underTest.isCtaDismissed)
+            userRepository.setSelectedUserInfo(USER_INFOS[0])
+            assertThat(isCtaDismissed).isFalse()
+            clearInvocations(userFileManagerSpy)
+
+            // Received restore finished event.
+            kosmos.broadcastDispatcher.sendIntentToMatchingReceiversOnly(
+                context,
+                Intent(BackupHelper.ACTION_RESTORE_FINISHED),
+            )
+            runCurrent()
+
+            // Get shared preferences from the restored file.
+            verify(userFileManagerSpy, atLeastOnce())
+                .getSharedPreferences(
+                    FILE_NAME,
+                    Context.MODE_PRIVATE,
+                    userRepository.getSelectedUserInfo().id
+                )
+        }
+
+    private fun createCommunalPrefsRepositoryImpl(userFileManager: UserFileManager) =
+        CommunalPrefsRepositoryImpl(
+            testScope.backgroundScope,
+            kosmos.testDispatcher,
+            userRepository,
+            userFileManager,
+            kosmos.broadcastDispatcher,
+            logcatLogBuffer("CommunalPrefsRepositoryImplTest"),
+            tableLogBuffer,
+        )
+
     private class FakeUserFileManager(private val sharedPrefs: Map<Int, SharedPreferences>) :
         UserFileManager {
         override fun getFile(fileName: String, userId: Int): File {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
index 6b28319..f71121c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/data/repository/CommunalSettingsRepositoryImplTest.kt
@@ -25,13 +25,13 @@
 import android.content.pm.UserInfo
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
+import android.provider.Settings
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.broadcastDispatcher
 import com.android.systemui.communal.data.model.DisabledReason
-import com.android.systemui.communal.data.repository.CommunalSettingsRepositoryImpl.Companion.GLANCEABLE_HUB_ENABLED
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
 import com.android.systemui.flags.fakeFeatureFlagsClassic
@@ -95,15 +95,27 @@
     @Test
     fun hubIsDisabledByUser() =
         testScope.runTest {
-            kosmos.fakeSettings.putIntForUser(GLANCEABLE_HUB_ENABLED, 0, PRIMARY_USER.id)
+            kosmos.fakeSettings.putIntForUser(
+                Settings.Secure.GLANCEABLE_HUB_ENABLED,
+                0,
+                PRIMARY_USER.id
+            )
             val enabledState by collectLastValue(underTest.getEnabledState(PRIMARY_USER))
             assertThat(enabledState?.enabled).isFalse()
             assertThat(enabledState).containsExactly(DisabledReason.DISABLED_REASON_USER_SETTING)
 
-            kosmos.fakeSettings.putIntForUser(GLANCEABLE_HUB_ENABLED, 1, SECONDARY_USER.id)
+            kosmos.fakeSettings.putIntForUser(
+                Settings.Secure.GLANCEABLE_HUB_ENABLED,
+                1,
+                SECONDARY_USER.id
+            )
             assertThat(enabledState?.enabled).isFalse()
 
-            kosmos.fakeSettings.putIntForUser(GLANCEABLE_HUB_ENABLED, 1, PRIMARY_USER.id)
+            kosmos.fakeSettings.putIntForUser(
+                Settings.Secure.GLANCEABLE_HUB_ENABLED,
+                1,
+                PRIMARY_USER.id
+            )
             assertThat(enabledState?.enabled).isTrue()
         }
 
@@ -126,7 +138,11 @@
             val enabledState by collectLastValue(underTest.getEnabledState(PRIMARY_USER))
             assertThat(enabledState?.enabled).isTrue()
 
-            kosmos.fakeSettings.putIntForUser(GLANCEABLE_HUB_ENABLED, 0, PRIMARY_USER.id)
+            kosmos.fakeSettings.putIntForUser(
+                Settings.Secure.GLANCEABLE_HUB_ENABLED,
+                0,
+                PRIMARY_USER.id
+            )
             setKeyguardFeaturesDisabled(PRIMARY_USER, KEYGUARD_DISABLE_WIDGETS_ALL)
 
             assertThat(enabledState?.enabled).isFalse()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt
index 2c9d72c..6cae5d3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt
@@ -19,11 +19,11 @@
 import android.appwidget.AppWidgetProviderInfo
 import android.content.pm.UserInfo
 import android.os.UserHandle
+import android.provider.Settings
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.communal.data.repository.CommunalSettingsRepositoryImpl.Companion.GLANCEABLE_HUB_ENABLED
 import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository
 import com.android.systemui.communal.domain.interactor.communalInteractor
 import com.android.systemui.communal.shared.model.CommunalWidgetContentModel
@@ -220,7 +220,11 @@
             fakeUserRepository.setSelectedUserInfo(MAIN_USER_INFO)
             fakeKeyguardRepository.setKeyguardShowing(true)
             val settingsValue = if (available) 1 else 0
-            fakeSettings.putIntForUser(GLANCEABLE_HUB_ENABLED, settingsValue, MAIN_USER_INFO.id)
+            fakeSettings.putIntForUser(
+                Settings.Secure.GLANCEABLE_HUB_ENABLED,
+                settingsValue,
+                MAIN_USER_INFO.id
+            )
         }
 
     private fun createWidgetForUser(appWidgetId: Int, userId: Int): CommunalWidgetContentModel =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
index 9536084..73373d55 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepositoryTest.kt
@@ -5,15 +5,11 @@
 import androidx.test.filters.SmallTest
 import com.android.internal.widget.LockPatternUtils
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.statusbar.phone.KeyguardBypassController
-import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.testKosmos
 import com.android.systemui.user.data.repository.FakeUserRepository
-import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
@@ -25,7 +21,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
-import org.mockito.Mockito
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
@@ -37,12 +32,10 @@
 
     @Mock private lateinit var lockPatternUtils: LockPatternUtils
     @Mock private lateinit var keyguardBypassController: KeyguardBypassController
-    @Mock private lateinit var keyguardStateController: KeyguardStateController
 
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val userRepository = FakeUserRepository()
-    private val keyguardRepository = FakeKeyguardRepository()
 
     private lateinit var underTest: DeviceEntryRepository
 
@@ -59,35 +52,9 @@
                 userRepository = userRepository,
                 lockPatternUtils = lockPatternUtils,
                 keyguardBypassController = keyguardBypassController,
-                keyguardStateController = keyguardStateController,
-                keyguardRepository = keyguardRepository,
             )
         testScope.runCurrent()
     }
-
-    @Test
-    fun isUnlocked() =
-        testScope.runTest {
-            whenever(keyguardStateController.isUnlocked).thenReturn(false)
-            val isUnlocked by collectLastValue(underTest.isUnlocked)
-
-            runCurrent()
-            assertThat(isUnlocked).isFalse()
-
-            val captor = argumentCaptor<KeyguardStateController.Callback>()
-            verify(keyguardStateController, Mockito.atLeastOnce()).addCallback(captor.capture())
-
-            whenever(keyguardStateController.isUnlocked).thenReturn(true)
-            captor.value.onUnlockedChanged()
-            runCurrent()
-            assertThat(isUnlocked).isTrue()
-
-            whenever(keyguardStateController.isUnlocked).thenReturn(false)
-            captor.value.onKeyguardShowingChanged()
-            runCurrent()
-            assertThat(isUnlocked).isFalse()
-        }
-
     @Test
     fun isLockscreenEnabled() =
         testScope.runTest {
@@ -102,17 +69,6 @@
         }
 
     @Test
-    fun reportSuccessfulAuthentication_updatesIsUnlocked() =
-        testScope.runTest {
-            val isUnlocked by collectLastValue(underTest.isUnlocked)
-            assertThat(isUnlocked).isFalse()
-
-            underTest.reportSuccessfulAuthentication()
-
-            assertThat(isUnlocked).isTrue()
-        }
-
-    @Test
     fun isBypassEnabled_disabledInController() =
         testScope.runTest {
             whenever(keyguardBypassController.isBypassEnabled).thenAnswer { false }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
index 70ceb2a..5caf35b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorTest.kt
@@ -41,8 +41,10 @@
 import com.android.systemui.flags.fakeSystemPropertiesHelper
 import com.android.systemui.keyguard.data.repository.fakeBiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.data.repository.fakeTrustRepository
 import com.android.systemui.keyguard.shared.model.AuthenticationFlags
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
@@ -89,22 +91,8 @@
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.None
             )
-            kosmos.fakeDeviceEntryRepository.apply {
-                setLockscreenEnabled(false)
-
-                // Toggle isUnlocked, twice.
-                //
-                // This is done because the underTest.isUnlocked flow doesn't receive values from
-                // just changing the state above; the actual isUnlocked state needs to change to
-                // cause the logic under test to "pick up" the current state again.
-                //
-                // It is done twice to make sure that we don't actually change the isUnlocked state
-                // from what it originally was.
-                setUnlocked(!isUnlocked.value)
-                runCurrent()
-                setUnlocked(!isUnlocked.value)
-                runCurrent()
-            }
+            kosmos.fakeDeviceEntryRepository.apply { setLockscreenEnabled(false) }
+            runCurrent()
 
             val isUnlocked by collectLastValue(underTest.isUnlocked)
             assertThat(isUnlocked).isTrue()
@@ -125,7 +113,9 @@
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.Sim
             )
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
 
             val isUnlocked by collectLastValue(underTest.isUnlocked)
             assertThat(isUnlocked).isFalse()
@@ -271,7 +261,6 @@
     @Test
     fun isAuthenticationRequired_lockedAndSecured_true() =
         testScope.runTest {
-            kosmos.fakeDeviceEntryRepository.setUnlocked(false)
             runCurrent()
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.Password
@@ -283,7 +272,6 @@
     @Test
     fun isAuthenticationRequired_lockedAndNotSecured_false() =
         testScope.runTest {
-            kosmos.fakeDeviceEntryRepository.setUnlocked(false)
             runCurrent()
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.None
@@ -295,7 +283,9 @@
     @Test
     fun isAuthenticationRequired_unlockedAndSecured_false() =
         testScope.runTest {
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
             runCurrent()
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.Password
@@ -307,7 +297,9 @@
     @Test
     fun isAuthenticationRequired_unlockedAndNotSecured_false() =
         testScope.runTest {
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
             runCurrent()
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.None
@@ -333,7 +325,9 @@
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.Pin
             )
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
             runCurrent()
 
             underTest.attemptDeviceEntry()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
index 51db451..a7a7bea3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.deviceentry.domain.interactor
 
+import android.content.pm.UserInfo
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -24,16 +25,30 @@
 import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
+import com.android.systemui.deviceentry.shared.model.DeviceUnlockSource
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.data.repository.fakeTrustRepository
+import com.android.systemui.keyguard.domain.interactor.trustInteractor
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
+import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
+import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.testKosmos
+import com.android.systemui.user.data.model.SelectionStatus
+import com.android.systemui.user.data.repository.fakeUserRepository
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
+import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-@android.platform.test.annotations.EnabledOnRavenwood
 class DeviceUnlockedInteractorTest : SysuiTestCase() {
 
     private val kosmos = testKosmos()
@@ -46,71 +61,170 @@
             applicationScope = testScope.backgroundScope,
             authenticationInteractor = kosmos.authenticationInteractor,
             deviceEntryRepository = deviceEntryRepository,
+            trustInteractor = kosmos.trustInteractor,
+            faceAuthInteractor = kosmos.deviceEntryFaceAuthInteractor,
+            fingerprintAuthInteractor = kosmos.deviceEntryFingerprintAuthInteractor,
+            powerInteractor = kosmos.powerInteractor,
         )
 
-    @Test
-    fun isDeviceUnlocked_whenUnlockedAndAuthMethodIsNone_isTrue() =
-        testScope.runTest {
-            val isUnlocked by collectLastValue(underTest.isDeviceUnlocked)
+    @Before
+    fun setup() {
+        kosmos.fakeUserRepository.setUserInfos(listOf(primaryUser, secondaryUser))
+    }
 
-            deviceEntryRepository.setUnlocked(true)
+    @Test
+    fun deviceUnlockStatus_whenUnlockedAndAuthMethodIsNone_isTrue() =
+        testScope.runTest {
+            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
+
             authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
 
-            assertThat(isUnlocked).isTrue()
+            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+            assertThat(deviceUnlockStatus?.deviceUnlockSource).isNull()
         }
 
     @Test
-    fun isDeviceUnlocked_whenUnlockedAndAuthMethodIsPin_isTrue() =
+    fun deviceUnlockStatus_whenUnlockedAndAuthMethodIsPin_isTrue() =
         testScope.runTest {
-            val isUnlocked by collectLastValue(underTest.isDeviceUnlocked)
+            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
 
-            deviceEntryRepository.setUnlocked(true)
             authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+            runCurrent()
 
-            assertThat(isUnlocked).isTrue()
+            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+            assertThat(deviceUnlockStatus?.deviceUnlockSource)
+                .isEqualTo(DeviceUnlockSource.Fingerprint)
         }
 
     @Test
-    fun isDeviceUnlocked_whenUnlockedAndAuthMethodIsSim_isFalse() =
+    fun deviceUnlockStatus_whenUnlockedAndAuthMethodIsSim_isFalse() =
         testScope.runTest {
-            val isUnlocked by collectLastValue(underTest.isDeviceUnlocked)
+            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
 
-            deviceEntryRepository.setUnlocked(true)
             authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Sim)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+            runCurrent()
 
-            assertThat(isUnlocked).isFalse()
+            assertThat(deviceUnlockStatus?.isUnlocked).isFalse()
         }
 
     @Test
-    fun isDeviceUnlocked_whenLockedAndAuthMethodIsNone_isTrue() =
+    fun deviceUnlockStatus_whenLockedAndAuthMethodIsNone_isTrue() =
         testScope.runTest {
-            val isUnlocked by collectLastValue(underTest.isDeviceUnlocked)
+            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
 
-            deviceEntryRepository.setUnlocked(false)
             authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.None)
 
-            assertThat(isUnlocked).isTrue()
+            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
         }
 
     @Test
-    fun isDeviceUnlocked_whenLockedAndAuthMethodIsPin_isFalse() =
+    fun deviceUnlockStatus_whenLockedAndAuthMethodIsPin_isFalse() =
         testScope.runTest {
-            val isUnlocked by collectLastValue(underTest.isDeviceUnlocked)
+            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
 
-            deviceEntryRepository.setUnlocked(false)
             authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin)
 
-            assertThat(isUnlocked).isFalse()
+            assertThat(deviceUnlockStatus?.isUnlocked).isFalse()
         }
 
     @Test
-    fun isDeviceUnlocked_whenLockedAndAuthMethodIsSim_isFalse() =
+    fun deviceUnlockStatus_whenLockedAndAuthMethodIsSim_isFalse() =
         testScope.runTest {
-            val isUnlocked by collectLastValue(underTest.isDeviceUnlocked)
+            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
 
-            deviceEntryRepository.setUnlocked(false)
             authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Sim)
 
-            assertThat(isUnlocked).isFalse()
+            assertThat(deviceUnlockStatus?.isUnlocked).isFalse()
         }
+
+    @Test
+    fun deviceUnlockStatus_whenFaceIsAuthenticatedWhileAwakeWithBypass_isTrue() =
+        testScope.runTest {
+            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
+            kosmos.powerInteractor.setAwakeForTest()
+
+            kosmos.fakeDeviceEntryFaceAuthRepository.isAuthenticated.value = true
+            kosmos.fakeDeviceEntryRepository.setBypassEnabled(true)
+            runCurrent()
+
+            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+            assertThat(deviceUnlockStatus?.deviceUnlockSource)
+                .isEqualTo(DeviceUnlockSource.FaceWithBypass)
+        }
+
+    @Test
+    fun deviceUnlockStatus_whenFaceIsAuthenticatedWithoutBypass_providesThatInfo() =
+        testScope.runTest {
+            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
+
+            kosmos.fakeDeviceEntryFaceAuthRepository.isAuthenticated.value = true
+            kosmos.fakeDeviceEntryRepository.setBypassEnabled(false)
+            runCurrent()
+
+            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+            assertThat(deviceUnlockStatus?.deviceUnlockSource)
+                .isEqualTo(DeviceUnlockSource.FaceWithoutBypass)
+        }
+
+    @Test
+    fun deviceUnlockStatus_whenFingerprintIsAuthenticated_providesThatInfo() =
+        testScope.runTest {
+            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
+
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+            runCurrent()
+
+            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+            assertThat(deviceUnlockStatus?.deviceUnlockSource)
+                .isEqualTo(DeviceUnlockSource.Fingerprint)
+        }
+
+    @Test
+    fun deviceUnlockStatus_whenUnlockedByTrustAgent_providesThatInfo() =
+        testScope.runTest {
+            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
+            kosmos.fakeUserRepository.setSelectedUserInfo(
+                primaryUser,
+                SelectionStatus.SELECTION_COMPLETE
+            )
+
+            kosmos.fakeTrustRepository.setCurrentUserTrusted(true)
+            runCurrent()
+
+            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+            assertThat(deviceUnlockStatus?.deviceUnlockSource)
+                .isEqualTo(DeviceUnlockSource.TrustAgent)
+        }
+
+    @Test
+    fun deviceUnlockStatus_isResetToFalse_whenDeviceGoesToSleep() =
+        testScope.runTest {
+            val deviceUnlockStatus by collectLastValue(underTest.deviceUnlockStatus)
+
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+            runCurrent()
+            assertThat(deviceUnlockStatus?.isUnlocked).isTrue()
+
+            kosmos.powerInteractor.setAsleepForTest()
+            runCurrent()
+
+            assertThat(deviceUnlockStatus?.isUnlocked).isFalse()
+        }
+
+    companion object {
+        private const val primaryUserId = 1
+        private val primaryUser = UserInfo(primaryUserId, "test user", UserInfo.FLAG_PRIMARY)
+
+        private val secondaryUser = UserInfo(2, "secondary user", 0)
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
index 6a86801..0f8fc38 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
@@ -63,7 +63,6 @@
 
 import java.util.Collections;
 import java.util.Optional;
-
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
@@ -119,6 +118,7 @@
     private static final float TOUCH_REGION = .3f;
     private static final int SCREEN_WIDTH_PX = 1024;
     private static final int SCREEN_HEIGHT_PX = 100;
+    private static final float MIN_BOUNCER_HEIGHT = .05f;
 
     private static final Rect SCREEN_BOUNDS = new Rect(0, 0, 1024, 100);
     private static final UserInfo CURRENT_USER_INFO = new UserInfo(
@@ -142,6 +142,7 @@
                 mFlingAnimationUtils,
                 mFlingAnimationUtilsClosing,
                 TOUCH_REGION,
+                MIN_BOUNCER_HEIGHT,
                 mUiEventLogger);
 
         when(mScrimManager.getCurrentController()).thenReturn(mScrimController);
@@ -160,9 +161,9 @@
      */
     @Test
     public void testSessionStart() {
-        mTouchHandler.getTouchInitiationRegion(SCREEN_BOUNDS, mRegion);
+        mTouchHandler.getTouchInitiationRegion(SCREEN_BOUNDS, mRegion, null);
 
-        verify(mRegion).op(mRectCaptor.capture(), eq(Region.Op.UNION));
+        verify(mRegion).union(mRectCaptor.capture());
         final Rect bounds = mRectCaptor.getValue();
 
         final Rect expected = new Rect();
@@ -194,6 +195,85 @@
         UP,
     }
 
+    @Test
+    public void testSwipeUp_whenBouncerInitiallyShowing_reduceHeightWithExclusionRects() {
+        mTouchHandler.getTouchInitiationRegion(SCREEN_BOUNDS, mRegion,
+                new Rect(0, 0, SCREEN_WIDTH_PX, SCREEN_HEIGHT_PX));
+        verify(mRegion).union(mRectCaptor.capture());
+        final Rect bounds = mRectCaptor.getValue();
+
+        final Rect expected = new Rect();
+        final float minBouncerHeight =
+                SCREEN_HEIGHT_PX * MIN_BOUNCER_HEIGHT;
+        final int minAllowableBottom = SCREEN_HEIGHT_PX - Math.round(minBouncerHeight);
+
+        expected.set(0, minAllowableBottom , SCREEN_WIDTH_PX, SCREEN_HEIGHT_PX);
+
+        assertThat(bounds).isEqualTo(expected);
+
+        onSessionStartHelper(mTouchHandler, mTouchSession, mNotificationShadeWindowController);
+    }
+
+    @Test
+    public void testSwipeUp_exclusionRectAtTop_doesNotIntersectGestureArea() {
+        mTouchHandler.getTouchInitiationRegion(SCREEN_BOUNDS, mRegion,
+                new Rect(0, 0, SCREEN_WIDTH_PX, SCREEN_HEIGHT_PX / 4));
+        verify(mRegion).union(mRectCaptor.capture());
+        final Rect bounds = mRectCaptor.getValue();
+
+        final Rect expected = new Rect();
+        final int gestureAreaTop = SCREEN_HEIGHT_PX - Math.round(SCREEN_HEIGHT_PX * TOUCH_REGION);
+        expected.set(0, gestureAreaTop, SCREEN_WIDTH_PX, SCREEN_HEIGHT_PX);
+
+        assertThat(bounds).isEqualTo(expected);
+        onSessionStartHelper(mTouchHandler, mTouchSession, mNotificationShadeWindowController);
+    }
+
+    @Test
+    public void testSwipeUp_exclusionRectBetweenNormalAndMinimumSwipeArea() {
+        final int normalSwipeAreaTop = SCREEN_HEIGHT_PX
+                - Math.round(SCREEN_HEIGHT_PX * TOUCH_REGION);
+        final int minimumSwipeAreaTop = SCREEN_HEIGHT_PX
+                - Math.round(SCREEN_HEIGHT_PX * MIN_BOUNCER_HEIGHT);
+
+        Rect exclusionRect = new Rect(0, 0, SCREEN_WIDTH_PX,
+                (normalSwipeAreaTop + minimumSwipeAreaTop) / 2);
+
+        mTouchHandler.getTouchInitiationRegion(SCREEN_BOUNDS, mRegion, exclusionRect);
+
+        verify(mRegion).union(mRectCaptor.capture());
+
+        final Rect bounds = mRectCaptor.getValue();
+        final Rect expected = new Rect();
+
+        final int expectedSwipeAreaBottom = exclusionRect.bottom;
+        expected.set(0, expectedSwipeAreaBottom, SCREEN_WIDTH_PX, SCREEN_HEIGHT_PX);
+
+        assertThat(bounds).isEqualTo(expected);
+
+        onSessionStartHelper(mTouchHandler, mTouchSession, mNotificationShadeWindowController);
+    }
+
+    private static void onSessionStartHelper(BouncerSwipeTouchHandler touchHandler,
+            DreamTouchHandler.TouchSession touchSession,
+            NotificationShadeWindowController notificationShadeWindowController) {
+        touchHandler.onSessionStart(touchSession);
+        verify(notificationShadeWindowController).setForcePluginOpen(eq(true), any());
+        ArgumentCaptor<InputChannelCompat.InputEventListener> eventListenerCaptor =
+                ArgumentCaptor.forClass(InputChannelCompat.InputEventListener.class);
+        ArgumentCaptor<GestureDetector.OnGestureListener> gestureListenerCaptor =
+                ArgumentCaptor.forClass(GestureDetector.OnGestureListener.class);
+        verify(touchSession).registerGestureListener(gestureListenerCaptor.capture());
+        verify(touchSession).registerInputListener(eventListenerCaptor.capture());
+
+        // A touch within range at the bottom of the screen should trigger listening
+        assertThat(gestureListenerCaptor.getValue()
+                .onScroll(Mockito.mock(MotionEvent.class),
+                        Mockito.mock(MotionEvent.class),
+                        1,
+                        2)).isTrue();
+    }
+
     /**
      * Makes sure swiping up when bouncer initially showing doesn't change the expansion amount.
      */
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
index eec74ef..6d7a0a9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
@@ -214,14 +214,16 @@
             )
 
             repository.setStatusBarState(StatusBarState.KEYGUARD)
-            shadeRepository.setLegacyShadeExpansion(1f)
+            // User begins to swipe up
+            shadeRepository.setLegacyShadeExpansion(0.99f)
 
             // When not dismissable, no alpha value (null) should emit
             repository.setKeyguardDismissible(false)
             assertThat(dismissAlpha).isNull()
 
             repository.setKeyguardDismissible(true)
-            assertThat(dismissAlpha).isGreaterThan(0.95f)
+            shadeRepository.setLegacyShadeExpansion(0.98f)
+            assertThat(dismissAlpha).isGreaterThan(0.5f)
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractorTest.kt
index 056a401..0f5e458 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractorTest.kt
@@ -37,14 +37,17 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
+import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
 import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.data.repository.keyguardOcclusionRepository
 import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.power.domain.interactor.PowerInteractor
@@ -247,14 +250,20 @@
             val occludingActivityWillDismissKeyguard by
                 collectLastValue(underTest.occludingActivityWillDismissKeyguard)
             assertThat(occludingActivityWillDismissKeyguard).isFalse()
+            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
+                AuthenticationMethodModel.Pin
+            )
+            runCurrent()
 
             // Unlock device:
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.deviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
             runCurrent()
             assertThat(occludingActivityWillDismissKeyguard).isTrue()
 
             // Re-lock device:
-            kosmos.fakeDeviceEntryRepository.setUnlocked(false)
+            kosmos.powerInteractor.setAsleepForTest()
             runCurrent()
             assertThat(occludingActivityWillDismissKeyguard).isFalse()
         }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
index f517cec..31337a6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModelTest.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.Flags as AConfigFlags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.keyguard.data.repository.fakeKeyguardClockRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
 import com.android.systemui.keyguard.domain.interactor.BurnInInteractor
 import com.android.systemui.keyguard.domain.interactor.burnInInteractor
@@ -60,10 +61,7 @@
     private val keyguardTransitionRepository = kosmos.fakeKeyguardTransitionRepository
     private lateinit var underTest: AodBurnInViewModel
 
-    private var burnInParameters =
-        BurnInParameters(
-            clockControllerProvider = { clockController },
-        )
+    private var burnInParameters = BurnInParameters()
     private val burnInFlow = MutableStateFlow(BurnInModel())
 
     @Before
@@ -76,6 +74,7 @@
         whenever(goneToAodTransitionViewModel.enterFromTopTranslationY(anyInt()))
             .thenReturn(emptyFlow())
         kosmos.goneToAodTransitionViewModel = goneToAodTransitionViewModel
+        kosmos.fakeKeyguardClockRepository.setCurrentClock(clockController)
 
         underTest = kosmos.aodBurnInViewModel
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
index 2fd2ef1..66f7e01 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenSceneViewModelTest.kt
@@ -121,7 +121,6 @@
                     AuthenticationMethodModel.Pin
                 }
             )
-            kosmos.fakeDeviceEntryRepository.setUnlocked(canSwipeToEnter)
             sceneInteractor.changeScene(Scenes.Lockscreen, "reason")
             kosmos.shadeRepository.setShadeMode(
                 if (isSingleShade) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/MediaTestHelper.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/MediaTestHelper.kt
index 8e44932..720bcb5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/MediaTestHelper.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/MediaTestHelper.kt
@@ -16,9 +16,7 @@
 
 package com.android.systemui.media.controls
 
-import android.R
 import android.app.smartspace.SmartspaceAction
-import android.content.Context
 import android.graphics.drawable.Icon
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
@@ -26,17 +24,9 @@
 class MediaTestHelper {
     companion object {
         /** Returns a list of three mocked recommendations */
-        fun getValidRecommendationList(context: Context): List<SmartspaceAction> {
+        fun getValidRecommendationList(mediaIcon: Icon): List<SmartspaceAction> {
             val mediaRecommendationItem =
-                mock<SmartspaceAction> {
-                    whenever(icon)
-                        .thenReturn(
-                            Icon.createWithResource(
-                                context,
-                                R.drawable.ic_media_play,
-                            )
-                        )
-                }
+                mock<SmartspaceAction> { whenever(icon).thenReturn(mediaIcon) }
             return listOf(mediaRecommendationItem, mediaRecommendationItem, mediaRecommendationItem)
         }
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaDataRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaDataRepositoryTest.kt
index 6c41bc3..2864f04 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaDataRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaDataRepositoryTest.kt
@@ -16,6 +16,8 @@
 
 package com.android.systemui.media.controls.data.repository
 
+import android.R
+import android.graphics.drawable.Icon
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -81,11 +83,12 @@
         testScope.runTest {
             kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, true)
             val smartspaceData by collectLastValue(underTest.smartspaceMediaData)
+            val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
             val recommendation =
                 SmartspaceMediaData(
                     targetId = KEY_MEDIA_SMARTSPACE,
                     isActive = true,
-                    recommendations = MediaTestHelper.getValidRecommendationList(context),
+                    recommendations = MediaTestHelper.getValidRecommendationList(icon),
                 )
 
             underTest.setRecommendation(recommendation)
@@ -102,11 +105,12 @@
     fun dismissRecommendation() =
         testScope.runTest {
             val smartspaceData by collectLastValue(underTest.smartspaceMediaData)
+            val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
             val recommendation =
                 SmartspaceMediaData(
                     targetId = KEY_MEDIA_SMARTSPACE,
                     isActive = true,
-                    recommendations = MediaTestHelper.getValidRecommendationList(context),
+                    recommendations = MediaTestHelper.getValidRecommendationList(icon),
                 )
 
             underTest.setRecommendation(recommendation)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt
index d39e77d..956ef66 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/data/repository/MediaFilterRepositoryTest.kt
@@ -16,8 +16,11 @@
 
 package com.android.systemui.media.controls.data.repository
 
+import android.R
+import android.graphics.drawable.Icon
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.testScope
@@ -44,16 +47,17 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(underTest.selectedUserEntries)
 
-            val userMedia = MediaData().copy(active = true)
+            val instanceId = InstanceId.fakeInstanceId(123)
+            val userMedia = MediaData().copy(active = true, instanceId = instanceId)
 
-            underTest.addSelectedUserMediaEntry(KEY, userMedia)
+            underTest.addSelectedUserMediaEntry(userMedia)
 
-            assertThat(selectedUserEntries?.get(KEY)).isEqualTo(userMedia)
+            assertThat(selectedUserEntries?.get(instanceId)).isEqualTo(userMedia)
 
-            underTest.addSelectedUserMediaEntry(KEY, userMedia.copy(active = false))
+            underTest.addSelectedUserMediaEntry(userMedia.copy(active = false))
 
-            assertThat(selectedUserEntries?.get(KEY)).isNotEqualTo(userMedia)
-            assertThat(selectedUserEntries?.get(KEY)?.active).isFalse()
+            assertThat(selectedUserEntries?.get(instanceId)).isNotEqualTo(userMedia)
+            assertThat(selectedUserEntries?.get(instanceId)?.active).isFalse()
         }
 
     @Test
@@ -61,13 +65,14 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(underTest.selectedUserEntries)
 
-            val userMedia = MediaData()
+            val instanceId = InstanceId.fakeInstanceId(123)
+            val userMedia = MediaData().copy(instanceId = instanceId)
 
-            underTest.addSelectedUserMediaEntry(KEY, userMedia)
+            underTest.addSelectedUserMediaEntry(userMedia)
 
-            assertThat(selectedUserEntries?.get(KEY)).isEqualTo(userMedia)
+            assertThat(selectedUserEntries?.get(instanceId)).isEqualTo(userMedia)
 
-            assertThat(underTest.removeSelectedUserMediaEntry(KEY, userMedia)).isTrue()
+            assertThat(underTest.removeSelectedUserMediaEntry(instanceId, userMedia)).isTrue()
         }
 
     @Test
@@ -75,13 +80,14 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(underTest.selectedUserEntries)
 
-            val userMedia = MediaData()
+            val instanceId = InstanceId.fakeInstanceId(123)
+            val userMedia = MediaData().copy(instanceId = instanceId)
 
-            underTest.addSelectedUserMediaEntry(KEY, userMedia)
+            underTest.addSelectedUserMediaEntry(userMedia)
 
-            assertThat(selectedUserEntries?.get(KEY)).isEqualTo(userMedia)
+            assertThat(selectedUserEntries?.get(instanceId)).isEqualTo(userMedia)
 
-            assertThat(underTest.removeSelectedUserMediaEntry(KEY)).isEqualTo(userMedia)
+            assertThat(underTest.removeSelectedUserMediaEntry(instanceId)).isEqualTo(userMedia)
         }
 
     @Test
@@ -120,11 +126,12 @@
         testScope.runTest {
             val smartspaceMediaData by collectLastValue(underTest.smartspaceMediaData)
 
+            val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
             val mediaRecommendation =
                 SmartspaceMediaData(
                     targetId = KEY_MEDIA_SMARTSPACE,
                     isActive = true,
-                    recommendations = MediaTestHelper.getValidRecommendationList(context),
+                    recommendations = MediaTestHelper.getValidRecommendationList(icon),
                 )
 
             underTest.setRecommendation(mediaRecommendation)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt
index 6e67000..d9d84f2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaCarouselInteractorTest.kt
@@ -16,6 +16,8 @@
 
 package com.android.systemui.media.controls.domain.interactor
 
+import android.R
+import android.graphics.drawable.Icon
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
@@ -56,13 +58,13 @@
 
             val userMedia = MediaData().copy(active = true)
 
-            mediaFilterRepository.addSelectedUserMediaEntry(KEY, userMedia)
+            mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
 
             assertThat(hasActiveMediaOrRecommendation).isTrue()
             assertThat(hasActiveMedia).isTrue()
             assertThat(hasAnyMedia).isTrue()
 
-            mediaFilterRepository.addSelectedUserMediaEntry(KEY, userMedia.copy(active = false))
+            mediaFilterRepository.addSelectedUserMediaEntry(userMedia.copy(active = false))
 
             assertThat(hasActiveMediaOrRecommendation).isFalse()
             assertThat(hasActiveMedia).isFalse()
@@ -78,14 +80,16 @@
             val hasAnyMedia by collectLastValue(underTest.hasAnyMedia)
 
             val userMedia = MediaData().copy(active = false)
+            val instanceId = userMedia.instanceId
 
-            mediaFilterRepository.addSelectedUserMediaEntry(KEY, userMedia)
+            mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
 
             assertThat(hasActiveMediaOrRecommendation).isFalse()
             assertThat(hasActiveMedia).isFalse()
             assertThat(hasAnyMedia).isTrue()
 
-            assertThat(mediaFilterRepository.removeSelectedUserMediaEntry(KEY, userMedia)).isTrue()
+            assertThat(mediaFilterRepository.removeSelectedUserMediaEntry(instanceId, userMedia))
+                .isTrue()
 
             assertThat(hasActiveMediaOrRecommendation).isFalse()
             assertThat(hasActiveMedia).isFalse()
@@ -101,11 +105,12 @@
                 collectLastValue(underTest.hasAnyMediaOrRecommendation)
             kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, false)
 
+            val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
             val userMediaRecommendation =
                 SmartspaceMediaData(
                     targetId = KEY_MEDIA_SMARTSPACE,
                     isActive = true,
-                    recommendations = MediaTestHelper.getValidRecommendationList(context),
+                    recommendations = MediaTestHelper.getValidRecommendationList(icon),
                 )
             val userMedia = MediaData().copy(active = false)
 
@@ -114,7 +119,7 @@
             assertThat(hasActiveMediaOrRecommendation).isTrue()
             assertThat(hasAnyMediaOrRecommendation).isTrue()
 
-            mediaFilterRepository.addSelectedUserMediaEntry(KEY, userMedia)
+            mediaFilterRepository.addSelectedUserMediaEntry(userMedia)
 
             assertThat(hasActiveMediaOrRecommendation).isTrue()
             assertThat(hasAnyMediaOrRecommendation).isTrue()
@@ -129,11 +134,12 @@
                 collectLastValue(underTest.hasAnyMediaOrRecommendation)
             kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, false)
 
+            val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
             val mediaRecommendation =
                 SmartspaceMediaData(
                     targetId = KEY_MEDIA_SMARTSPACE,
                     isActive = true,
-                    recommendations = MediaTestHelper.getValidRecommendationList(context),
+                    recommendations = MediaTestHelper.getValidRecommendationList(icon),
                 )
 
             mediaFilterRepository.setRecommendation(mediaRecommendation)
@@ -156,11 +162,12 @@
                 collectLastValue(underTest.hasAnyMediaOrRecommendation)
             kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, false)
 
+            val icon = Icon.createWithResource(context, R.drawable.ic_media_play)
             val mediaRecommendation =
                 SmartspaceMediaData(
                     targetId = KEY_MEDIA_SMARTSPACE,
                     isActive = true,
-                    recommendations = MediaTestHelper.getValidRecommendationList(context),
+                    recommendations = MediaTestHelper.getValidRecommendationList(icon),
                 )
 
             mediaFilterRepository.setRecommendation(mediaRecommendation)
@@ -193,7 +200,6 @@
         testScope.runTest { assertThat(underTest.hasActiveMediaOrRecommendation.value).isFalse() }
 
     companion object {
-        private const val KEY = "KEY"
         private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaControlInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaControlInteractorTest.kt
new file mode 100644
index 0000000..a1cee8a
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaControlInteractorTest.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.domain.interactor
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.InstanceId
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl
+import com.android.systemui.media.controls.domain.pipeline.interactor.MediaControlInteractor
+import com.android.systemui.media.controls.domain.pipeline.interactor.mediaControlInteractor
+import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
+import com.android.systemui.media.controls.shared.model.MediaData
+import com.android.systemui.media.controls.util.mediaInstanceId
+import com.android.systemui.statusbar.notificationLockscreenUserManager
+import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class MediaControlInteractorTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+
+    private val mediaDataFilter: MediaDataFilterImpl = kosmos.mediaDataFilter
+    private val instanceId: InstanceId = kosmos.mediaInstanceId
+    private val notificationLockscreenUserManager = kosmos.notificationLockscreenUserManager
+
+    private val underTest: MediaControlInteractor = kosmos.mediaControlInteractor
+
+    @Test
+    fun onMediaDataUpdated() =
+        testScope.runTest {
+            whenever(notificationLockscreenUserManager.isCurrentProfile(USER_ID)).thenReturn(true)
+            whenever(notificationLockscreenUserManager.isProfileAvailable(USER_ID)).thenReturn(true)
+            val controlModel by collectLastValue(underTest.mediaControl)
+            var mediaData =
+                MediaData(userId = USER_ID, instanceId = instanceId, artist = SESSION_ARTIST)
+
+            mediaDataFilter.onMediaDataLoaded(KEY, KEY, mediaData)
+
+            assertThat(controlModel?.instanceId).isEqualTo(instanceId)
+            assertThat(controlModel?.artistName).isEqualTo(SESSION_ARTIST)
+
+            mediaData =
+                MediaData(userId = USER_ID, instanceId = instanceId, artist = SESSION_ARTIST_2)
+
+            mediaDataFilter.onMediaDataLoaded(KEY, KEY, mediaData)
+
+            assertThat(controlModel?.instanceId).isEqualTo(instanceId)
+            assertThat(controlModel?.artistName).isEqualTo(SESSION_ARTIST_2)
+
+            mediaData =
+                MediaData(
+                    userId = USER_ID,
+                    instanceId = InstanceId.fakeInstanceId(2),
+                    artist = SESSION_ARTIST
+                )
+
+            mediaDataFilter.onMediaDataLoaded(KEY, KEY, mediaData)
+
+            assertThat(controlModel?.instanceId).isNotEqualTo(mediaData.instanceId)
+            assertThat(controlModel?.artistName).isEqualTo(SESSION_ARTIST_2)
+        }
+
+    companion object {
+        private const val USER_ID = 0
+        private const val KEY = "key"
+        private const val SESSION_ARTIST = "artist"
+        private const val SESSION_ARTIST_2 = "artist2"
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaRecommendationsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaRecommendationsInteractorTest.kt
new file mode 100644
index 0000000..9656511
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/domain/interactor/MediaRecommendationsInteractorTest.kt
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.domain.interactor
+
+import android.R
+import android.content.ComponentName
+import android.content.Intent
+import android.content.applicationContext
+import android.graphics.drawable.Icon
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.Expandable
+import com.android.systemui.broadcast.broadcastSender
+import com.android.systemui.broadcast.mockBroadcastSender
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.media.controls.MediaTestHelper
+import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl
+import com.android.systemui.media.controls.domain.pipeline.interactor.MediaRecommendationsInteractor
+import com.android.systemui.media.controls.domain.pipeline.interactor.MediaRecommendationsInteractor.Companion.EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME
+import com.android.systemui.media.controls.domain.pipeline.interactor.mediaRecommendationsInteractor
+import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
+import com.android.systemui.media.controls.shared.model.MediaRecModel
+import com.android.systemui.media.controls.shared.model.MediaRecommendationsModel
+import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
+import com.android.systemui.plugins.activityStarter
+import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.doNothing
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class MediaRecommendationsInteractorTest : SysuiTestCase() {
+
+    private val spyContext = spy(context)
+    private val kosmos = testKosmos().apply { applicationContext = spyContext }
+    private val testScope = kosmos.testScope
+
+    private val mediaDataFilter: MediaDataFilterImpl = kosmos.mediaDataFilter
+    private val activityStarter = kosmos.activityStarter
+    private val icon: Icon = Icon.createWithResource(context, R.drawable.ic_media_play)
+    private val smartspaceMediaData: SmartspaceMediaData =
+        SmartspaceMediaData(
+            targetId = KEY_MEDIA_SMARTSPACE,
+            isActive = true,
+            packageName = PACKAGE_NAME,
+            recommendations = MediaTestHelper.getValidRecommendationList(icon),
+        )
+
+    private val underTest: MediaRecommendationsInteractor =
+        with(kosmos) {
+            broadcastSender = mockBroadcastSender
+            kosmos.mediaRecommendationsInteractor
+        }
+
+    @Test
+    fun addRecommendation_smartspaceMediaDataUpdate() =
+        testScope.runTest {
+            val recommendations by collectLastValue(underTest.recommendations)
+
+            val model =
+                MediaRecommendationsModel(
+                    key = KEY_MEDIA_SMARTSPACE,
+                    packageName = PACKAGE_NAME,
+                    areRecommendationsValid = true,
+                    mediaRecs =
+                        listOf(
+                            MediaRecModel(icon = icon),
+                            MediaRecModel(icon = icon),
+                            MediaRecModel(icon = icon)
+                        )
+                )
+
+            mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)
+
+            assertThat(recommendations).isEqualTo(model)
+        }
+
+    @Test
+    fun setRecommendationInactive_isActiveUpdate() =
+        testScope.runTest {
+            kosmos.fakeFeatureFlagsClassic.set(Flags.MEDIA_RETAIN_RECOMMENDATIONS, true)
+            val isActive by collectLastValue(underTest.isActive)
+
+            mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)
+            assertThat(isActive).isTrue()
+
+            mediaDataFilter.onSmartspaceMediaDataLoaded(
+                KEY_MEDIA_SMARTSPACE,
+                smartspaceMediaData.copy(isActive = false)
+            )
+            assertThat(isActive).isFalse()
+        }
+
+    @Test
+    fun addInvalidRecommendation() =
+        testScope.runTest {
+            val recommendations by collectLastValue(underTest.recommendations)
+            val inValidData = smartspaceMediaData.copy(recommendations = listOf())
+
+            mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)
+            assertThat(recommendations?.areRecommendationsValid).isTrue()
+
+            mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, inValidData)
+            assertThat(recommendations?.areRecommendationsValid).isFalse()
+            assertThat(recommendations?.mediaRecs?.isEmpty()).isTrue()
+        }
+
+    @Test
+    fun removeRecommendation_noTrampolineActivity() {
+        val intent = Intent()
+
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+
+        underTest.removeMediaRecommendations(KEY_MEDIA_SMARTSPACE, intent, 0)
+
+        verify(kosmos.mockBroadcastSender).sendBroadcast(eq(intent))
+    }
+
+    @Test
+    fun removeRecommendation_usingTrampolineActivity() {
+        doNothing().whenever(spyContext).startActivity(any())
+        val intent = Intent()
+
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        intent.component = ComponentName(PACKAGE_NAME, EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME)
+
+        underTest.removeMediaRecommendations(KEY_MEDIA_SMARTSPACE, intent, 0)
+
+        verify(spyContext).startActivity(eq(intent))
+    }
+
+    @Test
+    fun startSettings() {
+        underTest.startSettings()
+
+        verify(activityStarter).startActivity(any(), eq(true))
+    }
+
+    @Test
+    fun startClickIntent() {
+        doNothing().whenever(spyContext).startActivity(any())
+        val intent = Intent()
+        val expandable = mock<Expandable>()
+
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+
+        underTest.startClickIntent(expandable, intent)
+
+        verify(spyContext).startActivity(eq(intent))
+    }
+
+    companion object {
+        private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
+        private const val PACKAGE_NAME = "com.example.app"
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModelTest.kt
new file mode 100644
index 0000000..51b1911
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModelTest.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.ui.viewmodel
+
+import android.R
+import android.content.packageManager
+import android.content.pm.ApplicationInfo
+import android.graphics.drawable.Icon
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.media.controls.MediaTestHelper
+import com.android.systemui.media.controls.domain.pipeline.MediaDataFilterImpl
+import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
+import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
+import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers
+import org.mockito.Mockito
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class MediaRecommendationsViewModelTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
+
+    private val mediaDataFilter: MediaDataFilterImpl = kosmos.mediaDataFilter
+    private val packageManager = kosmos.packageManager
+    private val icon: Icon = Icon.createWithResource(context, R.drawable.ic_media_play)
+    private val drawable = context.getDrawable(R.drawable.ic_media_play)
+    private val smartspaceMediaData: SmartspaceMediaData =
+        SmartspaceMediaData(
+            targetId = KEY_MEDIA_SMARTSPACE,
+            isActive = true,
+            packageName = PACKAGE_NAME,
+            recommendations = MediaTestHelper.getValidRecommendationList(icon),
+        )
+
+    private val underTest: MediaRecommendationsViewModel = kosmos.mediaRecommendationsViewModel
+
+    @Test
+    fun loadRecommendations_recsCardViewModelIsLoaded() =
+        testScope.runTest {
+            whenever(packageManager.getApplicationIcon(Mockito.anyString())).thenReturn(drawable)
+            whenever(packageManager.getApplicationIcon(any(ApplicationInfo::class.java)))
+                .thenReturn(drawable)
+            whenever(packageManager.getApplicationInfo(eq(PACKAGE_NAME), ArgumentMatchers.anyInt()))
+                .thenReturn(ApplicationInfo())
+            whenever(packageManager.getApplicationLabel(any())).thenReturn(PACKAGE_NAME)
+            val recsCardViewModel by collectLastValue(underTest.mediaRecsCard)
+
+            context.setMockPackageManager(packageManager)
+
+            mediaDataFilter.onSmartspaceMediaDataLoaded(KEY_MEDIA_SMARTSPACE, smartspaceMediaData)
+
+            assertThat(recsCardViewModel).isNotNull()
+            assertThat(recsCardViewModel?.mediaRecs?.size)
+                .isEqualTo(smartspaceMediaData.recommendations.size)
+        }
+
+    companion object {
+        private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
+        private const val PACKAGE_NAME = "com.example.app"
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
index 4a39ba2..b7e08da 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
@@ -104,6 +104,7 @@
         underTest.logUserActionRejectedByPolicy(
             QSTileUserAction.Click(null),
             TileSpec.create("test_spec"),
+            "test_restriction",
         )
 
         assertThat(logBuffer.getStringBuffer()).contains("tile click: rejected by policy")
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt
new file mode 100644
index 0000000..d0cd56fc
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.sensorprivacy.domain.interactor
+
+import android.hardware.SensorPrivacyManager.Sensors.CAMERA
+import android.hardware.SensorPrivacyManager.Sensors.MICROPHONE
+import android.os.UserHandle
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.impl.sensorprivacy.SensorPrivacyToggleTileDataInteractor
+import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.toCollection
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mockito.verify
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SensorPrivacyToggleTileDataInteractorTest : SysuiTestCase() {
+    private val kosmos = Kosmos()
+    private val testScope = kosmos.testScope
+    private val mockSensorPrivacyController =
+        mock<IndividualSensorPrivacyController> {
+            whenever(isSensorBlocked(eq(CAMERA))).thenReturn(false) // determines initial value
+        }
+    private val testUser = UserHandle.of(1)
+    private val underTest =
+        SensorPrivacyToggleTileDataInteractor(
+            testScope.testScheduler,
+            mockSensorPrivacyController,
+            CAMERA
+        )
+
+    @Test
+    fun availability_isTrue() =
+        testScope.runTest {
+            whenever(mockSensorPrivacyController.supportsSensorToggle(eq(CAMERA))).thenReturn(true)
+
+            val availability = underTest.availability(testUser).toCollection(mutableListOf())
+            runCurrent()
+
+            assertThat(availability).hasSize(1)
+            assertThat(availability.last()).isTrue()
+        }
+
+    @Test
+    fun tileData_matchesPrivacyControllerIsSensorBlocked() =
+        testScope.runTest {
+            val callbackCaptor = argumentCaptor<IndividualSensorPrivacyController.Callback>()
+            val data by
+                collectLastValue(
+                    underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest))
+                )
+            runCurrent()
+            verify(mockSensorPrivacyController).addCallback(callbackCaptor.capture())
+            val callback = callbackCaptor.value
+
+            runCurrent()
+            assertThat(data!!.isBlocked).isFalse()
+
+            callback.onSensorBlockedChanged(CAMERA, true)
+            runCurrent()
+            assertThat(data!!.isBlocked).isTrue()
+
+            callback.onSensorBlockedChanged(CAMERA, false)
+            runCurrent()
+            assertThat(data!!.isBlocked).isFalse()
+
+            callback.onSensorBlockedChanged(MICROPHONE, true)
+            runCurrent()
+            assertThat(data!!.isBlocked).isFalse() // We're NOT listening for MIC sensor changes
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractorTest.kt
new file mode 100644
index 0000000..562e6eb
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractorTest.kt
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.sensorprivacy.domain.interactor
+
+import android.hardware.SensorPrivacyManager
+import android.hardware.SensorPrivacyManager.Sensors.CAMERA
+import android.hardware.SensorPrivacyManager.Sensors.MICROPHONE
+import android.provider.Settings
+import android.safetycenter.SafetyCenterManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.plugins.activityStarter
+import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.SensorPrivacyToggleTileUserActionInteractor
+import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel
+import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SensorPrivacyToggleTileUserActionInteractorTest : SysuiTestCase() {
+    private val kosmos = Kosmos()
+    private val inputHandler = FakeQSTileIntentUserInputHandler()
+    private val keyguardInteractor = kosmos.keyguardInteractor
+    // The keyguard repository below is the same one kosmos used to create the interactor above
+    private val keyguardRepository = kosmos.fakeKeyguardRepository
+    private val mockActivityStarter = kosmos.activityStarter
+    private val mockSensorPrivacyController = mock<IndividualSensorPrivacyController>()
+    private val fakeSafetyCenterManager = mock<SafetyCenterManager>()
+
+    private val underTest =
+        SensorPrivacyToggleTileUserActionInteractor(
+            inputHandler,
+            keyguardInteractor,
+            mockActivityStarter,
+            mockSensorPrivacyController,
+            fakeSafetyCenterManager,
+            CAMERA
+        )
+
+    @Test
+    fun handleClickWhenNotBlocked() = runTest {
+        val originalIsBlocked = false
+
+        underTest.handleInput(
+            QSTileInputTestKtx.click(SensorPrivacyToggleTileModel(originalIsBlocked))
+        )
+
+        verify(mockSensorPrivacyController)
+            .setSensorBlocked(
+                eq(SensorPrivacyManager.Sources.QS_TILE),
+                eq(CAMERA),
+                eq(!originalIsBlocked)
+            )
+    }
+
+    @Test
+    fun handleClickWhenBlocked() = runTest {
+        val originalIsBlocked = true
+
+        underTest.handleInput(
+            QSTileInputTestKtx.click(SensorPrivacyToggleTileModel(originalIsBlocked))
+        )
+
+        verify(mockSensorPrivacyController)
+            .setSensorBlocked(
+                eq(SensorPrivacyManager.Sources.QS_TILE),
+                eq(CAMERA),
+                eq(!originalIsBlocked)
+            )
+    }
+
+    @Test
+    fun handleClick_whenKeyguardIsDismissableAndShowing_whenControllerRequiresAuth() = runTest {
+        whenever(mockSensorPrivacyController.requiresAuthentication()).thenReturn(true)
+        keyguardRepository.setKeyguardDismissible(true)
+        keyguardRepository.setKeyguardShowing(true)
+        val originalIsBlocked = true
+
+        underTest.handleInput(
+            QSTileInputTestKtx.click(SensorPrivacyToggleTileModel(originalIsBlocked))
+        )
+
+        verify(mockSensorPrivacyController, never())
+            .setSensorBlocked(
+                eq(SensorPrivacyManager.Sources.QS_TILE),
+                eq(CAMERA),
+                eq(!originalIsBlocked)
+            )
+        verify(mockActivityStarter).postQSRunnableDismissingKeyguard(any())
+    }
+
+    @Test
+    fun handleLongClick_whenSafetyManagerEnabled_privacyControlsIntent() = runTest {
+        whenever(fakeSafetyCenterManager.isSafetyCenterEnabled).thenReturn(true)
+
+        underTest.handleInput(QSTileInputTestKtx.longClick(SensorPrivacyToggleTileModel(false)))
+
+        QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
+            assertThat(it.intent.action).isEqualTo(Settings.ACTION_PRIVACY_CONTROLS)
+        }
+    }
+
+    @Test
+    fun handleLongClick_whenSafetyManagerDisabled_privacySettingsIntent() = runTest {
+        whenever(fakeSafetyCenterManager.isSafetyCenterEnabled).thenReturn(false)
+
+        underTest.handleInput(QSTileInputTestKtx.longClick(SensorPrivacyToggleTileModel(false)))
+
+        QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
+            assertThat(it.intent.action).isEqualTo(Settings.ACTION_PRIVACY_SETTINGS)
+        }
+    }
+
+    @Test
+    fun handleClick_microphone_flipsController() = runTest {
+        val micUserActionInteractor =
+            SensorPrivacyToggleTileUserActionInteractor(
+                inputHandler,
+                keyguardInteractor,
+                mockActivityStarter,
+                mockSensorPrivacyController,
+                fakeSafetyCenterManager,
+                MICROPHONE
+            )
+
+        micUserActionInteractor.handleInput(
+            QSTileInputTestKtx.click(SensorPrivacyToggleTileModel(false))
+        )
+        verify(mockSensorPrivacyController)
+            .setSensorBlocked(eq(SensorPrivacyManager.Sources.QS_TILE), eq(MICROPHONE), eq(true))
+
+        micUserActionInteractor.handleInput(
+            QSTileInputTestKtx.click(SensorPrivacyToggleTileModel(true))
+        )
+        verify(mockSensorPrivacyController)
+            .setSensorBlocked(eq(SensorPrivacyManager.Sources.QS_TILE), eq(MICROPHONE), eq(false))
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapperTest.kt
new file mode 100644
index 0000000..5e7aadc
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapperTest.kt
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.sensorprivacy.ui
+
+import android.graphics.drawable.TestStubDrawable
+import android.hardware.SensorPrivacyManager.Sensors.CAMERA
+import android.hardware.SensorPrivacyManager.Sensors.MICROPHONE
+import android.widget.Switch
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel
+import com.android.systemui.qs.tiles.impl.sensorprivacy.qsCameraSensorPrivacyToggleTileConfig
+import com.android.systemui.qs.tiles.impl.sensorprivacy.qsMicrophoneSensorPrivacyToggleTileConfig
+import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyTileResources.CameraPrivacyTileResources
+import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyTileResources.MicrophonePrivacyTileResources
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.res.R
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SensorPrivacyToggleTileMapperTest : SysuiTestCase() {
+    private val kosmos = Kosmos()
+    private val cameraConfig = kosmos.qsCameraSensorPrivacyToggleTileConfig
+    private val micConfig = kosmos.qsMicrophoneSensorPrivacyToggleTileConfig
+
+    @Test
+    fun mapCamera_notBlocked() {
+        val mapper = createMapper(CameraPrivacyTileResources)
+        val inputModel = SensorPrivacyToggleTileModel(false)
+
+        val outputState = mapper.map(cameraConfig, inputModel)
+
+        val expectedState =
+            createSensorPrivacyToggleTileState(
+                QSTileState.ActivationState.ACTIVE,
+                context.getString(R.string.quick_settings_camera_mic_available),
+                R.drawable.qs_camera_access_icon_on,
+                null,
+                CAMERA
+            )
+        QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
+    }
+
+    @Test
+    fun mapCamera_blocked() {
+        val mapper = createMapper(CameraPrivacyTileResources)
+        val inputModel = SensorPrivacyToggleTileModel(true)
+
+        val outputState = mapper.map(cameraConfig, inputModel)
+
+        val expectedState =
+            createSensorPrivacyToggleTileState(
+                QSTileState.ActivationState.INACTIVE,
+                context.getString(R.string.quick_settings_camera_mic_blocked),
+                R.drawable.qs_camera_access_icon_off,
+                null,
+                CAMERA
+            )
+        QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
+    }
+
+    @Test
+    fun mapMic_notBlocked() {
+        val mapper = createMapper(MicrophonePrivacyTileResources)
+        val inputModel = SensorPrivacyToggleTileModel(false)
+
+        val outputState = mapper.map(micConfig, inputModel)
+
+        val expectedState =
+            createSensorPrivacyToggleTileState(
+                QSTileState.ActivationState.ACTIVE,
+                context.getString(R.string.quick_settings_camera_mic_available),
+                R.drawable.qs_mic_access_on,
+                null,
+                MICROPHONE
+            )
+        QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
+    }
+
+    @Test
+    fun mapMic_blocked() {
+        val mapper = createMapper(MicrophonePrivacyTileResources)
+        val inputModel = SensorPrivacyToggleTileModel(true)
+
+        val outputState = mapper.map(micConfig, inputModel)
+
+        val expectedState =
+            createSensorPrivacyToggleTileState(
+                QSTileState.ActivationState.INACTIVE,
+                context.getString(R.string.quick_settings_camera_mic_blocked),
+                R.drawable.qs_mic_access_off,
+                null,
+                MICROPHONE
+            )
+        QSTileStateSubject.assertThat(outputState).isEqualTo(expectedState)
+    }
+
+    private fun createMapper(
+        sensorResources: SensorPrivacyTileResources
+    ): SensorPrivacyToggleTileMapper {
+        val mapper =
+            SensorPrivacyToggleTileMapper(
+                context.orCreateTestableResources
+                    .apply {
+                        addOverride(R.drawable.qs_camera_access_icon_off, TestStubDrawable())
+                        addOverride(R.drawable.qs_camera_access_icon_on, TestStubDrawable())
+                        addOverride(R.drawable.qs_mic_access_off, TestStubDrawable())
+                        addOverride(R.drawable.qs_mic_access_on, TestStubDrawable())
+                    }
+                    .resources,
+                context.theme,
+                sensorResources,
+            )
+        return mapper
+    }
+
+    private fun createSensorPrivacyToggleTileState(
+        activationState: QSTileState.ActivationState,
+        secondaryLabel: String,
+        iconRes: Int,
+        stateDescription: CharSequence?,
+        sensorId: Int,
+    ): QSTileState {
+        val label =
+            if (sensorId == CAMERA) context.getString(R.string.quick_settings_camera_label)
+            else context.getString(R.string.quick_settings_mic_label)
+
+        return QSTileState(
+            { Icon.Loaded(context.getDrawable(iconRes)!!, null) },
+            label,
+            activationState,
+            secondaryLabel,
+            setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK),
+            label,
+            stateDescription,
+            QSTileState.SideViewIcon.None,
+            QSTileState.EnabledState.ENABLED,
+            Switch::class.qualifiedName
+        )
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
index a8bc8d6..9ce2e0f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
@@ -60,7 +60,9 @@
     @Mock private lateinit var qsTileAnalytics: QSTileAnalytics
 
     private val tileConfig =
-        QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted("test_restriction") }
+        QSTileConfigTestBuilder.build {
+            policy = QSTilePolicy.Restricted(listOf("test_restriction"))
+        }
 
     private val userRepository = FakeUserRepository()
     private val tileDataInteractor = FakeQSTileDataInteractor<String>()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
index 18cdd71..6066d24 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
@@ -16,18 +16,17 @@
 
 package com.android.systemui.qs.tiles.viewmodel
 
-import android.platform.test.annotations.EnabledOnRavenwood
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
-import com.android.settingslib.RestrictedLockUtils
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.classifier.FalsingManagerFake
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics
 import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor
 import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor
+import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor.Companion.DISABLED_RESTRICTION
+import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor.Companion.ENABLED_RESTRICTION
 import com.android.systemui.qs.tiles.base.interactor.FakeQSTileDataInteractor
 import com.android.systemui.qs.tiles.base.interactor.FakeQSTileUserActionInteractor
 import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
@@ -54,7 +53,6 @@
 
 /** Tests all possible [QSTileUserAction]s. If you need */
 @MediumTest
-@EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
 @OptIn(ExperimentalCoroutinesApi::class)
 class QSTileViewModelUserInputTest : SysuiTestCase() {
@@ -65,8 +63,10 @@
     // TODO(b/299909989): this should be parametrised. b/299096521 blocks this.
     private val userAction: QSTileUserAction = QSTileUserAction.Click(null)
 
-    private val tileConfig =
-        QSTileConfigTestBuilder.build { policy = QSTilePolicy.Restricted("test_restriction") }
+    private var tileConfig =
+        QSTileConfigTestBuilder.build {
+            policy = QSTilePolicy.Restricted(listOf(ENABLED_RESTRICTION))
+        }
 
     private val userRepository = FakeUserRepository()
     private val tileDataInteractor = FakeQSTileDataInteractor<String>()
@@ -112,11 +112,13 @@
     @Test
     fun disabledByPolicyUserInputIsSkipped() =
         testScope.runTest {
+            tileConfig =
+                QSTileConfigTestBuilder.build {
+                    policy = QSTilePolicy.Restricted(listOf(DISABLED_RESTRICTION))
+                }
+            underTest = createViewModel(testScope)
             underTest.state.launchIn(backgroundScope)
-            disabledByPolicyInteractor.policyResult =
-                DisabledByPolicyInteractor.PolicyResult.TileDisabled(
-                    RestrictedLockUtils.EnforcedAdmin()
-                )
+
             runCurrent()
 
             underTest.onActionPerformed(userAction)
@@ -125,7 +127,81 @@
             assertThat(tileDataInteractor.triggers.last())
                 .isNotInstanceOf(DataUpdateTrigger.UserInput::class.java)
             verify(qsTileLogger)
-                .logUserActionRejectedByPolicy(eq(userAction), eq(tileConfig.tileSpec))
+                .logUserActionRejectedByPolicy(
+                    eq(userAction),
+                    eq(tileConfig.tileSpec),
+                    eq(DISABLED_RESTRICTION)
+                )
+            verify(qsTileAnalytics, never()).trackUserAction(any(), any())
+        }
+
+    @Test
+    fun disabledByPolicySecondRestriction_userInputIsSkipped() =
+        testScope.runTest {
+            tileConfig =
+                QSTileConfigTestBuilder.build {
+                    policy =
+                        QSTilePolicy.Restricted(listOf(ENABLED_RESTRICTION, DISABLED_RESTRICTION))
+                }
+
+            underTest = createViewModel(testScope)
+
+            underTest.state.launchIn(backgroundScope)
+
+            runCurrent()
+
+            underTest.onActionPerformed(userAction)
+            runCurrent()
+
+            assertThat(tileDataInteractor.triggers.last())
+                .isNotInstanceOf(DataUpdateTrigger.UserInput::class.java)
+            verify(qsTileLogger)
+                .logUserActionRejectedByPolicy(
+                    eq(userAction),
+                    eq(tileConfig.tileSpec),
+                    eq(DISABLED_RESTRICTION)
+                )
+            verify(qsTileAnalytics, never()).trackUserAction(any(), any())
+        }
+
+    /** This tests that the policies are applied sequentially */
+    @Test
+    fun disabledByPolicySecondRestriction_onlyFirstIsTriggered() =
+        testScope.runTest {
+            tileConfig =
+                QSTileConfigTestBuilder.build {
+                    policy =
+                        QSTilePolicy.Restricted(
+                            listOf(
+                                DISABLED_RESTRICTION,
+                                FakeDisabledByPolicyInteractor.DISABLED_RESTRICTION_2
+                            )
+                        )
+                }
+
+            underTest = createViewModel(testScope)
+
+            underTest.state.launchIn(backgroundScope)
+
+            runCurrent()
+
+            underTest.onActionPerformed(userAction)
+            runCurrent()
+
+            assertThat(tileDataInteractor.triggers.last())
+                .isNotInstanceOf(DataUpdateTrigger.UserInput::class.java)
+            verify(qsTileLogger)
+                .logUserActionRejectedByPolicy(
+                    eq(userAction),
+                    eq(tileConfig.tileSpec),
+                    eq(DISABLED_RESTRICTION)
+                )
+            verify(qsTileLogger, never())
+                .logUserActionRejectedByPolicy(
+                    eq(userAction),
+                    eq(tileConfig.tileSpec),
+                    eq(FakeDisabledByPolicyInteractor.DISABLED_RESTRICTION_2)
+                )
             verify(qsTileAnalytics, never()).trackUserAction(any(), any())
         }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
index 27c4ec1..1a9ad3c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
@@ -496,4 +496,16 @@
             runCurrent()
             verify(qsImpl!!).setInSplitShade(true)
         }
+
+    @Test
+    fun requestCloseCustomizer() =
+        testScope.runTest {
+            val qsImpl by collectLastValue(underTest.qsImpl)
+
+            underTest.inflate(context)
+            runCurrent()
+
+            underTest.requestCloseCustomizer()
+            verify(qsImpl!!).closeCustomizer()
+        }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
index ef38567..d9ab3b1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
@@ -133,18 +133,13 @@
         }
 
     @Test
-    fun destinationsCustomizing() =
+    fun destinationsCustomizing_noDestinations() =
         testScope.runTest {
             overrideResource(R.bool.config_use_split_notification_shade, false)
             val destinations by collectLastValue(underTest.destinationScenes)
             qsFlexiglassAdapter.setCustomizing(true)
 
-            assertThat(destinations)
-                .isEqualTo(
-                    mapOf(
-                        Back to UserActionResult(Scenes.QuickSettings),
-                    )
-                )
+            assertThat(destinations).isEmpty()
         }
 
     @Test
@@ -164,18 +159,13 @@
         }
 
     @Test
-    fun destinations_whenCustomizing_inSplitShade() =
+    fun destinations_whenCustomizing_inSplitShade_noDestinations() =
         testScope.runTest {
             overrideResource(R.bool.config_use_split_notification_shade, true)
             val destinations by collectLastValue(underTest.destinationScenes)
             qsFlexiglassAdapter.setCustomizing(true)
 
-            assertThat(destinations)
-                .isEqualTo(
-                    mapOf(
-                        Back to UserActionResult(Scenes.QuickSettings),
-                    )
-                )
+            assertThat(destinations).isEmpty()
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index efbdb7d..98cbda2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -48,7 +48,9 @@
 import com.android.systemui.communal.domain.interactor.communalInteractor
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
@@ -261,10 +263,9 @@
                 shadeInteractor = kosmos.shadeInteractor,
                 footerActionsController = kosmos.footerActionsController,
                 footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory,
+                sceneInteractor = sceneInteractor,
             )
 
-        kosmos.fakeDeviceEntryRepository.setUnlocked(false)
-
         val displayTracker = FakeDisplayTracker(context)
         val sysUiState = SysUiState(displayTracker, kosmos.sceneContainerPlugin)
         val startable =
@@ -288,6 +289,8 @@
                 centralSurfaces = mock(),
                 headsUpInteractor = kosmos.headsUpNotificationInteractor,
                 occlusionInteractor = kosmos.sceneContainerOcclusionInteractor,
+                faceUnlockInteractor = kosmos.deviceEntryFaceAuthInteractor,
+                deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor,
             )
         startable.start()
 
@@ -368,8 +371,11 @@
     fun swipeUpOnShadeScene_withAuthMethodSwipe_lockscreenDismissed_goesToGone() =
         testScope.runTest {
             val destinationScenes by collectLastValue(shadeSceneViewModel.destinationScenes)
+            val canSwipeToEnter by collectLastValue(deviceEntryInteractor.canSwipeToEnter)
+
             setAuthMethod(AuthenticationMethodModel.None, enableLockscreen = true)
-            assertThat(deviceEntryInteractor.canSwipeToEnter.value).isTrue()
+
+            assertThat(canSwipeToEnter).isTrue()
             assertCurrentScene(Scenes.Lockscreen)
 
             // Emulate a user swipe to dismiss the lockscreen.
@@ -434,17 +440,6 @@
         }
 
     @Test
-    fun deviceWakesUpWhileUnlocked_dismissesLockscreen() =
-        testScope.runTest {
-            unlockDevice()
-            assertCurrentScene(Scenes.Gone)
-            putDeviceToSleep(instantlyLockDevice = false)
-            assertCurrentScene(Scenes.Lockscreen)
-            wakeUpDevice()
-            assertCurrentScene(Scenes.Gone)
-        }
-
-    @Test
     fun swipeUpOnLockscreenWhileUnlocked_dismissesLockscreen() =
         testScope.runTest {
             unlockDevice()
@@ -537,7 +532,11 @@
             fakeSceneDataSource.pause()
             introduceLockedSim()
             emulatePendingTransitionProgress(expectedVisible = true)
-            enterSimPin(authMethodAfterSimUnlock = AuthenticationMethodModel.None)
+            enterSimPin(
+                authMethodAfterSimUnlock = AuthenticationMethodModel.None,
+                enableLockscreen = false
+            )
+
             assertCurrentScene(Scenes.Gone)
         }
 
@@ -705,7 +704,6 @@
             .that(authMethod.isSecure)
             .isTrue()
 
-        kosmos.fakeDeviceEntryRepository.setUnlocked(false)
         runCurrent()
     }
 
@@ -718,9 +716,7 @@
         emulateUserDrivenTransition(Scenes.Bouncer)
         fakeSceneDataSource.pause()
         enterPin()
-        // This repository state is not changed by the AuthInteractor, it relies on
-        // KeyguardStateController.
-        kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+
         emulatePendingTransitionProgress(
             expectedVisible = false,
         )
@@ -760,7 +756,8 @@
      * Does not assert that the device is locked or unlocked.
      */
     private fun TestScope.enterSimPin(
-        authMethodAfterSimUnlock: AuthenticationMethodModel = AuthenticationMethodModel.None
+        authMethodAfterSimUnlock: AuthenticationMethodModel = AuthenticationMethodModel.None,
+        enableLockscreen: Boolean = true,
     ) {
         assertWithMessage("Cannot enter PIN when not on the Bouncer scene!")
             .that(getCurrentSceneInUi())
@@ -775,9 +772,11 @@
             pinBouncerViewModel.onPinButtonClicked(digit)
         }
         pinBouncerViewModel.onAuthenticateButtonClicked()
-        setAuthMethod(authMethodAfterSimUnlock)
         kosmos.fakeMobileConnectionsRepository.isAnySimSecure.value = false
         runCurrent()
+
+        setAuthMethod(authMethodAfterSimUnlock, enableLockscreen)
+        runCurrent()
     }
 
     /** Changes device wakefulness state from asleep to awake, going through intermediary states. */
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index f645f1c..143c0f2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -23,7 +23,8 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.data.repository.sceneContainerRepository
 import com.android.systemui.scene.sceneContainerConfig
@@ -79,7 +80,9 @@
             val currentScene by collectLastValue(underTest.currentScene)
             assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
 
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
             runCurrent()
 
             underTest.changeScene(Scenes.Gone, "reason")
@@ -88,11 +91,7 @@
 
     @Test(expected = IllegalStateException::class)
     fun changeScene_toGoneWhenStillLocked_throws() =
-        testScope.runTest {
-            kosmos.fakeDeviceEntryRepository.setUnlocked(false)
-
-            underTest.changeScene(Scenes.Gone, "reason")
-        }
+        testScope.runTest { underTest.changeScene(Scenes.Gone, "reason") }
 
     @Test
     fun sceneChanged_inDataSource() =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index 605e5c0..3fd5306 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -37,12 +37,17 @@
 import com.android.systemui.classifier.falsingManager
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
+import com.android.systemui.deviceentry.domain.interactor.deviceEntryFaceAuthInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
+import com.android.systemui.keyguard.data.repository.deviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.model.SysUiState
+import com.android.systemui.model.sysUiState
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
 import com.android.systemui.power.domain.interactor.PowerInteractorFactory
@@ -51,6 +56,7 @@
 import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
+import com.android.systemui.shared.system.QuickStepContract
 import com.android.systemui.statusbar.NotificationShadeWindowController
 import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
 import com.android.systemui.statusbar.notification.data.repository.FakeHeadsUpRowRepository
@@ -78,6 +84,7 @@
 import org.mockito.Mock
 import org.mockito.Mockito.clearInvocations
 import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
@@ -99,7 +106,7 @@
     private val faceAuthRepository by lazy { kosmos.fakeDeviceEntryFaceAuthRepository }
     private val deviceEntryInteractor by lazy { kosmos.deviceEntryInteractor }
     private val keyguardInteractor by lazy { kosmos.keyguardInteractor }
-    private val sysUiState: SysUiState = mock()
+    private val sysUiState = spy(kosmos.sysUiState)
     private val falsingCollector: FalsingCollector = mock()
     private val powerInteractor = PowerInteractorFactory.create().powerInteractor
     private val fakeSceneDataSource = kosmos.fakeSceneDataSource
@@ -131,6 +138,8 @@
                 centralSurfaces = centralSurfaces,
                 headsUpInteractor = kosmos.headsUpNotificationInteractor,
                 occlusionInteractor = kosmos.sceneContainerOcclusionInteractor,
+                faceUnlockInteractor = kosmos.deviceEntryFaceAuthInteractor,
+                deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor,
             )
     }
 
@@ -141,6 +150,7 @@
             val isVisible by collectLastValue(sceneInteractor.isVisible)
             val transitionStateFlow =
                 prepareState(
+                    authenticationMethod = AuthenticationMethodModel.Pin,
                     isDeviceUnlocked = true,
                     initialSceneKey = Scenes.Gone,
                 )
@@ -194,6 +204,7 @@
         testScope.runTest {
             val isVisible by collectLastValue(sceneInteractor.isVisible)
             prepareState(
+                authenticationMethod = AuthenticationMethodModel.Pin,
                 isDeviceUnlocked = true,
                 initialSceneKey = Scenes.Lockscreen,
                 isDeviceProvisioned = false,
@@ -245,14 +256,14 @@
         testScope.runTest {
             val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
             prepareState(
+                authenticationMethod = AuthenticationMethodModel.Pin,
                 isDeviceUnlocked = true,
                 initialSceneKey = Scenes.Gone,
+                startsAwake = false,
             )
             assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
             underTest.start()
 
-            kosmos.fakeDeviceEntryRepository.setUnlocked(false)
-
             assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
         }
 
@@ -261,13 +272,16 @@
         testScope.runTest {
             val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
             prepareState(
+                authenticationMethod = AuthenticationMethodModel.Pin,
                 isDeviceUnlocked = false,
                 initialSceneKey = Scenes.Bouncer,
             )
             assertThat(currentSceneKey).isEqualTo(Scenes.Bouncer)
             underTest.start()
 
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
 
             assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
         }
@@ -277,13 +291,16 @@
         testScope.runTest {
             val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
             prepareState(
+                authenticationMethod = AuthenticationMethodModel.Pin,
                 isBypassEnabled = true,
                 initialSceneKey = Scenes.Lockscreen,
             )
             assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
             underTest.start()
 
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
 
             assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
         }
@@ -301,7 +318,6 @@
 
             // Authenticate using a passive auth method like face auth while bypass is disabled.
             faceAuthRepository.isAuthenticated.value = true
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
 
             assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
         }
@@ -323,7 +339,9 @@
             transitionStateFlowValue.value = ObservableTransitionState.Idle(Scenes.Shade)
             assertThat(currentSceneKey).isEqualTo(Scenes.Shade)
 
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
             runCurrent()
 
             assertThat(currentSceneKey).isEqualTo(Scenes.Shade)
@@ -342,7 +360,6 @@
 
             // Authenticate using a passive auth method like face auth while bypass is disabled.
             faceAuthRepository.isAuthenticated.value = true
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
 
             assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
         }
@@ -379,7 +396,9 @@
                 )
                 .forEachIndexed { index, sceneKey ->
                     if (sceneKey == Scenes.Gone) {
-                        kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+                        kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                            SuccessFingerprintAuthenticationStatus(0, true)
+                        )
                         runCurrent()
                     }
                     fakeSceneDataSource.pause()
@@ -398,6 +417,46 @@
         }
 
     @Test
+    fun hydrateSystemUiState_onLockscreen_basedOnOcclusion() =
+        testScope.runTest {
+            prepareState(
+                initialSceneKey = Scenes.Lockscreen,
+            )
+            underTest.start()
+            runCurrent()
+            clearInvocations(sysUiState)
+
+            kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop(
+                true,
+                mock()
+            )
+            runCurrent()
+            assertThat(
+                    sysUiState.flags and
+                        QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED != 0
+                )
+                .isTrue()
+            assertThat(
+                    sysUiState.flags and
+                        QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING != 0
+                )
+                .isFalse()
+
+            kosmos.keyguardOcclusionInteractor.setWmNotifiedShowWhenLockedActivityOnTop(false)
+            runCurrent()
+            assertThat(
+                    sysUiState.flags and
+                        QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED != 0
+                )
+                .isFalse()
+            assertThat(
+                    sysUiState.flags and
+                        QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING != 0
+                )
+                .isTrue()
+        }
+
+    @Test
     fun switchToGoneWhenDeviceStartsToWakeUp_authMethodNone() =
         testScope.runTest {
             val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
@@ -409,6 +468,7 @@
             assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
             underTest.start()
             powerInteractor.setAwakeForTest()
+            runCurrent()
 
             assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
         }
@@ -430,7 +490,7 @@
         }
 
     @Test
-    fun doesNotSwitchToGoneWhenDeviceStartsToWakeUp_authMethodSecure() =
+    fun doesNotSwitchToGone_whenDeviceStartsToWakeUp_authMethodSecure() =
         testScope.runTest {
             val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
             prepareState(
@@ -445,6 +505,34 @@
         }
 
     @Test
+    fun doesNotSwitchToGone_whenDeviceStartsToWakeUp_ifAlreadyTransitioningToLockscreen() =
+        testScope.runTest {
+            val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
+            val transitioningTo by collectLastValue(sceneInteractor.transitioningTo)
+            val transitionStateFlow =
+                prepareState(
+                    isDeviceUnlocked = true,
+                    initialSceneKey = Scenes.Gone,
+                    authenticationMethod = AuthenticationMethodModel.Pin,
+                )
+            transitionStateFlow.value =
+                ObservableTransitionState.Transition(
+                    fromScene = Scenes.Gone,
+                    toScene = Scenes.Lockscreen,
+                    progress = flowOf(0.1f),
+                    isInitiatedByUserInput = false,
+                    isUserInputOngoing = flowOf(false),
+                )
+            assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
+            assertThat(transitioningTo).isEqualTo(Scenes.Lockscreen)
+            underTest.start()
+            powerInteractor.setAwakeForTest()
+
+            assertThat(currentSceneKey).isEqualTo(Scenes.Gone)
+            assertThat(transitioningTo).isEqualTo(Scenes.Lockscreen)
+        }
+
+    @Test
     fun switchToGoneWhenDeviceStartsToWakeUp_authMethodSecure_deviceUnlocked() =
         testScope.runTest {
             val currentSceneKey by collectLastValue(sceneInteractor.currentScene)
@@ -457,7 +545,9 @@
             assertThat(currentSceneKey).isEqualTo(Scenes.Lockscreen)
             underTest.start()
 
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
             runCurrent()
             powerInteractor.setAwakeForTest()
             runCurrent()
@@ -492,7 +582,9 @@
                 }
 
             // Changing to the Gone scene should report a successful unlock.
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
             runCurrent()
             sceneInteractor.changeScene(Scenes.Gone, "reason")
             runCurrent()
@@ -687,7 +779,9 @@
             runCurrent()
             verify(falsingCollector).onBouncerShown()
 
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
             runCurrent()
             sceneInteractor.changeScene(Scenes.Gone, "reason")
             runCurrent()
@@ -758,6 +852,7 @@
             val currentDesiredSceneKey by collectLastValue(sceneInteractor.currentScene)
             val transitionStateFlow =
                 prepareState(
+                    authenticationMethod = AuthenticationMethodModel.Pin,
                     isDeviceUnlocked = true,
                     initialSceneKey = Scenes.Gone,
                 )
@@ -913,6 +1008,7 @@
         testScope.runTest {
             val transitionStateFlow =
                 prepareState(
+                    authenticationMethod = AuthenticationMethodModel.Pin,
                     isDeviceUnlocked = true,
                     initialSceneKey = Scenes.Gone,
                 )
@@ -1009,6 +1105,28 @@
             assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
         }
 
+    @Test
+    fun handleBouncerOverscroll() =
+        testScope.runTest {
+            val currentScene by collectLastValue(sceneInteractor.currentScene)
+            val transitionStateFlow = prepareState()
+            underTest.start()
+            emulateSceneTransition(transitionStateFlow, toScene = Scenes.Bouncer)
+            assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+
+            transitionStateFlow.value =
+                ObservableTransitionState.Transition(
+                    fromScene = Scenes.Bouncer,
+                    toScene = Scenes.Lockscreen,
+                    progress = flowOf(-0.4f),
+                    isInitiatedByUserInput = true,
+                    isUserInputOngoing = flowOf(true),
+                )
+            runCurrent()
+
+            assertThat(kosmos.fakeDeviceEntryFaceAuthRepository.isAuthRunning.value).isTrue()
+        }
+
     private fun TestScope.emulateSceneTransition(
         transitionStateFlow: MutableStateFlow<ObservableTransitionState>,
         toScene: SceneKey,
@@ -1053,6 +1171,11 @@
             assert(isLockscreenEnabled) {
                 "Lockscreen cannot be disabled while having a secure authentication method"
             }
+            if (isDeviceUnlocked) {
+                kosmos.deviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                    SuccessFingerprintAuthenticationStatus(0, true)
+                )
+            }
         }
 
         check(initialSceneKey != Scenes.Gone || isDeviceUnlocked) {
@@ -1060,8 +1183,13 @@
         }
 
         sceneContainerFlags.enabled = true
-        kosmos.fakeDeviceEntryRepository.setUnlocked(isDeviceUnlocked)
         kosmos.fakeDeviceEntryRepository.setBypassEnabled(isBypassEnabled)
+        authenticationMethod?.let {
+            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(authenticationMethod)
+            kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(
+                isLockscreenEnabled = isLockscreenEnabled
+            )
+        }
         runCurrent()
         val transitionStateFlow =
             MutableStateFlow<ObservableTransitionState>(
@@ -1072,12 +1200,6 @@
             transitionStateFlow.value = ObservableTransitionState.Idle(it)
             sceneInteractor.changeScene(it, "reason")
         }
-        authenticationMethod?.let {
-            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(authenticationMethod)
-            kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(
-                isLockscreenEnabled = isLockscreenEnabled
-            )
-        }
         if (startsAwake) {
             powerInteractor.setAwakeForTest()
         } else {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
index cd79ed1..cbbcce9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
@@ -21,10 +21,11 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.compose.animation.scene.SceneKey
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.flags.Flags
 import com.android.systemui.flags.fakeFeatureFlagsClassic
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.kosmos.testScope
@@ -38,6 +39,7 @@
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -53,7 +55,7 @@
 class ShadeControllerSceneImplTest : SysuiTestCase() {
     private val kosmos = Kosmos()
     private val testScope = kosmos.testScope
-    private val sceneInteractor = kosmos.sceneInteractor
+    private val sceneInteractor by lazy { kosmos.sceneInteractor }
     private val deviceEntryInteractor by lazy { kosmos.deviceEntryInteractor }
 
     private lateinit var shadeInteractor: ShadeInteractor
@@ -68,7 +70,9 @@
             set(Flags.NSSL_DEBUG_LINES, false)
             set(Flags.FULL_SCREEN_USER_SWITCHER, false)
         }
-        kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+        kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+            SuccessFingerprintAuthenticationStatus(0, true)
+        )
         testScope.runCurrent()
         shadeInteractor = kosmos.shadeInteractor
         underTest = kosmos.shadeControllerSceneImpl
@@ -161,6 +165,10 @@
         testScope.runTest {
             // GIVEN shade is collapsed and a post-collapse action is enqueued
             val testRunnable = mock<Runnable>()
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+            runCurrent()
             setCollapsed()
             underTest.postOnShadeExpanded(testRunnable)
 
@@ -179,7 +187,14 @@
         testScope.runCurrent()
     }
 
-    private fun setDeviceEntered(isEntered: Boolean) {
+    private fun TestScope.setDeviceEntered(isEntered: Boolean) {
+        if (isEntered) {
+            // Unlock the device marking the device has entered.
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+            runCurrent()
+        }
         setScene(
             if (isEntered) {
                 Scenes.Gone
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt
index ad40f8e..6485c47 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/PanelExpansionInteractorImplTest.kt
@@ -24,9 +24,12 @@
 import com.android.compose.animation.scene.SceneKey
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
+import com.android.systemui.deviceentry.shared.model.DeviceUnlockSource
+import com.android.systemui.deviceentry.shared.model.DeviceUnlockStatus
 import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.shared.model.Scenes
@@ -49,7 +52,6 @@
 
     private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
-    private val deviceEntryRepository = kosmos.fakeDeviceEntryRepository
     private val deviceUnlockedInteractor = kosmos.deviceUnlockedInteractor
     private val sceneInteractor = kosmos.sceneInteractor
     private val shadeAnimationInteractor = kosmos.shadeAnimationInteractor
@@ -71,7 +73,6 @@
     fun legacyPanelExpansion_whenIdle_whenLocked() =
         testScope.runTest {
             underTest = kosmos.panelExpansionInteractorImpl
-            setUnlocked(false)
             val panelExpansion by collectLastValue(underTest.legacyPanelExpansion)
 
             changeScene(Scenes.Lockscreen) { assertThat(panelExpansion).isEqualTo(1f) }
@@ -95,7 +96,15 @@
     fun legacyPanelExpansion_whenIdle_whenUnlocked() =
         testScope.runTest {
             underTest = kosmos.panelExpansionInteractorImpl
-            setUnlocked(true)
+            val unlockStatus by collectLastValue(deviceUnlockedInteractor.deviceUnlockStatus)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+            runCurrent()
+
+            assertThat(unlockStatus)
+                .isEqualTo(DeviceUnlockStatus(true, DeviceUnlockSource.Fingerprint))
+
             val panelExpansion by collectLastValue(underTest.legacyPanelExpansion)
 
             changeScene(Scenes.Gone) { assertThat(panelExpansion).isEqualTo(0f) }
@@ -147,14 +156,6 @@
             assertThat(underTest.shouldHideStatusBarIconsWhenExpanded()).isFalse()
         }
 
-    private fun TestScope.setUnlocked(isUnlocked: Boolean) {
-        val isDeviceUnlocked by collectLastValue(deviceUnlockedInteractor.isDeviceUnlocked)
-        deviceEntryRepository.setUnlocked(isUnlocked)
-        runCurrent()
-
-        assertThat(isDeviceUnlocked).isEqualTo(isUnlocked)
-    }
-
     private fun TestScope.changeScene(
         toScene: SceneKey,
         assertDuringProgress: ((progress: Float) -> Unit) = {},
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
index d309c6b..e759b50 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/interactor/ShadeBackActionInteractorImplTest.kt
@@ -22,7 +22,6 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.compose.animation.scene.SceneKey
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
@@ -48,7 +47,6 @@
     val kosmos = testKosmos().apply { fakeSceneContainerFlags.enabled = true }
     val testScope = kosmos.testScope
     val sceneInteractor = kosmos.sceneInteractor
-    val deviceEntryRepository = kosmos.fakeDeviceEntryRepository
     val underTest = kosmos.shadeBackActionInteractor
 
     @Before
@@ -78,7 +76,6 @@
     @Test
     fun animateCollapseQs_fullyCollapse_locked() =
         testScope.runTest {
-            deviceEntryRepository.setUnlocked(false)
             setScene(Scenes.QuickSettings)
             underTest.animateCollapseQs(true)
             runCurrent()
@@ -95,7 +92,6 @@
         }
 
     private fun enterDevice() {
-        deviceEntryRepository.setUnlocked(true)
         testScope.runCurrent()
         setScene(Scenes.Gone)
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt
index 52caa78..2ab934c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/domain/startable/ShadeStartableTest.kt
@@ -21,11 +21,15 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.compose.animation.scene.SceneKey
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository
+import com.android.systemui.authentication.shared.model.AuthenticationMethodModel
 import com.android.systemui.common.ui.data.repository.fakeConfigurationRepository
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
 import com.android.systemui.flags.EnableSceneContainer
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.res.R
 import com.android.systemui.scene.domain.interactor.sceneInteractor
@@ -40,6 +44,7 @@
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.TestScope
@@ -48,6 +53,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ShadeStartableTest : SysuiTestCase() {
@@ -95,7 +101,14 @@
 
             underTest.start()
 
-            setUnlocked(true)
+            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
+                AuthenticationMethodModel.Pin
+            )
+            runCurrent()
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
+            runCurrent()
             val transitionState =
                 MutableStateFlow<ObservableTransitionState>(
                     ObservableTransitionState.Idle(Scenes.Gone)
@@ -120,14 +133,6 @@
             }
         }
 
-    private fun TestScope.setUnlocked(isUnlocked: Boolean) {
-        val isDeviceUnlocked by collectLastValue(deviceUnlockedInteractor.isDeviceUnlocked)
-        deviceEntryRepository.setUnlocked(isUnlocked)
-        runCurrent()
-
-        assertThat(isDeviceUnlocked).isEqualTo(isUnlocked)
-    }
-
     private fun TestScope.changeScene(
         toScene: SceneKey,
         transitionState: MutableStateFlow<ObservableTransitionState>,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
index f90a3b1..77109d6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModelTest.kt
@@ -29,6 +29,8 @@
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
 import com.android.systemui.flags.FakeFeatureFlagsClassic
 import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
 import com.android.systemui.qs.footerActionsController
@@ -129,6 +131,7 @@
                 shadeInteractor = kosmos.shadeInteractor,
                 footerActionsViewModelFactory = kosmos.footerActionsViewModelFactory,
                 footerActionsController = kosmos.footerActionsController,
+                sceneInteractor = kosmos.sceneInteractor,
             )
     }
 
@@ -139,7 +142,6 @@
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.Pin
             )
-            kosmos.fakeDeviceEntryRepository.setUnlocked(false)
 
             assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene)
                 .isEqualTo(Scenes.Lockscreen)
@@ -152,7 +154,9 @@
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.Pin
             )
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
 
             assertThat(destinationScenes?.get(Swipe(SwipeDirection.Up))?.toScene)
                 .isEqualTo(Scenes.Gone)
@@ -177,7 +181,6 @@
         testScope.runTest {
             val destinationScenes by collectLastValue(underTest.destinationScenes)
             kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(true)
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.None
             )
@@ -195,7 +198,9 @@
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.Pin
             )
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
             runCurrent()
 
             assertThat(isClickable).isFalse()
@@ -208,40 +213,23 @@
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.Pin
             )
-            kosmos.fakeDeviceEntryRepository.setUnlocked(false)
             runCurrent()
 
             assertThat(isClickable).isTrue()
         }
 
     @Test
-    fun onContentClicked_deviceUnlocked_switchesToGone() =
+    fun onContentClicked_deviceLockedSecurely_switchesToLockscreen() =
         testScope.runTest {
             val currentScene by collectLastValue(sceneInteractor.currentScene)
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.Pin
             )
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
             runCurrent()
 
             underTest.onContentClicked()
 
-            assertThat(currentScene).isEqualTo(Scenes.Gone)
-        }
-
-    @Test
-    fun onContentClicked_deviceLockedSecurely_switchesToBouncer() =
-        testScope.runTest {
-            val currentScene by collectLastValue(sceneInteractor.currentScene)
-            kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
-                AuthenticationMethodModel.Pin
-            )
-            kosmos.fakeDeviceEntryRepository.setUnlocked(false)
-            runCurrent()
-
-            underTest.onContentClicked()
-
-            assertThat(currentScene).isEqualTo(Scenes.Bouncer)
+            assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
index 94539a3..3c28c0e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/NotificationStackAppearanceIntegrationTest.kt
@@ -30,8 +30,10 @@
 import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.fakeSceneDataSource
-import com.android.systemui.statusbar.notification.stack.shared.model.StackBounds
-import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationStackAppearanceViewModel
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape
+import com.android.systemui.statusbar.notification.stack.shared.model.ViewPosition
+import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationScrollViewModel
 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.notificationsPlaceholderViewModel
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
@@ -57,27 +59,44 @@
         }
     private val testScope = kosmos.testScope
     private val placeholderViewModel by lazy { kosmos.notificationsPlaceholderViewModel }
-    private val appearanceViewModel by lazy { kosmos.notificationStackAppearanceViewModel }
+    private val appearanceViewModel by lazy { kosmos.notificationScrollViewModel }
     private val sceneInteractor by lazy { kosmos.sceneInteractor }
     private val fakeSceneDataSource by lazy { kosmos.fakeSceneDataSource }
 
     @Test
     fun updateBounds() =
         testScope.runTest {
-            val clipping by collectLastValue(appearanceViewModel.stackClipping)
+            val radius = MutableStateFlow(32)
+            val viewPosition = MutableStateFlow(ViewPosition(0, 0))
+            val shape by collectLastValue(appearanceViewModel.shadeScrimShape(radius, viewPosition))
 
-            val top = 200f
-            val left = 0f
-            val bottom = 550f
-            val right = 100f
-            placeholderViewModel.onBoundsChanged(
-                left = left,
-                top = top,
-                right = right,
-                bottom = bottom
+            placeholderViewModel.onScrimBoundsChanged(
+                ShadeScrimBounds(left = 0f, top = 200f, right = 100f, bottom = 550f)
             )
-            assertThat(clipping?.bounds)
-                .isEqualTo(StackBounds(left = left, top = top, right = right, bottom = bottom))
+            assertThat(shape)
+                .isEqualTo(
+                    ShadeScrimShape(
+                        bounds =
+                            ShadeScrimBounds(left = 0f, top = 200f, right = 100f, bottom = 550f),
+                        topRadius = 32,
+                        bottomRadius = 0
+                    )
+                )
+
+            viewPosition.value = ViewPosition(200, 15)
+            radius.value = 24
+            placeholderViewModel.onScrimBoundsChanged(
+                ShadeScrimBounds(left = 210f, top = 200f, right = 300f, bottom = 550f)
+            )
+            assertThat(shape)
+                .isEqualTo(
+                    ShadeScrimShape(
+                        bounds =
+                            ShadeScrimBounds(left = 10f, top = 185f, right = 100f, bottom = 535f),
+                        topRadius = 24,
+                        bottomRadius = 0
+                    )
+                )
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorTest.kt
index e3fa89c..50b77dc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorTest.kt
@@ -23,8 +23,8 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.shade.data.repository.shadeRepository
 import com.android.systemui.shade.shared.model.ShadeMode
-import com.android.systemui.statusbar.notification.stack.shared.model.StackBounds
-import com.android.systemui.statusbar.notification.stack.shared.model.StackRounding
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimRounding
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
@@ -42,42 +42,44 @@
     @Test
     fun stackBounds() =
         testScope.runTest {
-            val stackBounds by collectLastValue(underTest.stackBounds)
+            val stackBounds by collectLastValue(underTest.shadeScrimBounds)
 
             val bounds1 =
-                StackBounds(
+                ShadeScrimBounds(
                     top = 100f,
                     bottom = 200f,
                 )
-            underTest.setStackBounds(bounds1)
+            underTest.setShadeScrimBounds(bounds1)
             assertThat(stackBounds).isEqualTo(bounds1)
 
             val bounds2 =
-                StackBounds(
+                ShadeScrimBounds(
                     top = 200f,
                     bottom = 300f,
                 )
-            underTest.setStackBounds(bounds2)
+            underTest.setShadeScrimBounds(bounds2)
             assertThat(stackBounds).isEqualTo(bounds2)
         }
 
     @Test
     fun stackRounding() =
         testScope.runTest {
-            val stackRounding by collectLastValue(underTest.stackRounding)
+            val stackRounding by collectLastValue(underTest.shadeScrimRounding)
 
             kosmos.shadeRepository.setShadeMode(ShadeMode.Single)
-            assertThat(stackRounding).isEqualTo(StackRounding(roundTop = true, roundBottom = false))
+            assertThat(stackRounding)
+                .isEqualTo(ShadeScrimRounding(isTopRounded = true, isBottomRounded = false))
 
             kosmos.shadeRepository.setShadeMode(ShadeMode.Split)
-            assertThat(stackRounding).isEqualTo(StackRounding(roundTop = true, roundBottom = true))
+            assertThat(stackRounding)
+                .isEqualTo(ShadeScrimRounding(isTopRounded = true, isBottomRounded = true))
         }
 
     @Test(expected = IllegalStateException::class)
     fun setStackBounds_withImproperBounds_throwsException() =
         testScope.runTest {
-            underTest.setStackBounds(
-                StackBounds(
+            underTest.setShadeScrimBounds(
+                ShadeScrimBounds(
                     top = 100f,
                     bottom = 99f,
                 )
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelTest.kt
index 9e5f7c9..1f0812d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelTest.kt
@@ -16,17 +16,13 @@
 
 package com.android.systemui.statusbar.notification.stack.ui.viewmodel
 
-import android.platform.test.annotations.DisableFlags
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.common.shared.model.NotificationContainerBounds
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
-import com.android.systemui.statusbar.notification.stack.shared.model.StackBounds
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
@@ -40,23 +36,21 @@
     private val underTest = kosmos.notificationsPlaceholderViewModel
 
     @Test
-    @DisableFlags(Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT)
-    fun onBoundsChanged_setsNotificationContainerBounds() =
+    fun onBoundsChanged() =
         kosmos.testScope.runTest {
-            underTest.onBoundsChanged(left = 5f, top = 5f, right = 5f, bottom = 5f)
-            val containerBounds by
-                collectLastValue(kosmos.keyguardInteractor.notificationContainerBounds)
+            val bounds = ShadeScrimBounds(left = 5f, top = 15f, right = 25f, bottom = 35f)
+            underTest.onScrimBoundsChanged(bounds)
             val stackBounds by
-                collectLastValue(kosmos.notificationStackAppearanceInteractor.stackBounds)
-            assertThat(containerBounds)
-                .isEqualTo(NotificationContainerBounds(top = 5f, bottom = 5f))
-            assertThat(stackBounds)
-                .isEqualTo(StackBounds(left = 5f, top = 5f, right = 5f, bottom = 5f))
+                collectLastValue(kosmos.notificationStackAppearanceInteractor.shadeScrimBounds)
+            assertThat(stackBounds).isEqualTo(bounds)
         }
 
     @Test
-    fun onContentTopChanged_setsContentTop() {
-        underTest.onContentTopChanged(padding = 5f)
-        assertThat(kosmos.notificationStackAppearanceInteractor.contentTop.value).isEqualTo(5f)
-    }
+    fun onStackBoundsChanged() =
+        kosmos.testScope.runTest {
+            underTest.onStackBoundsChanged(top = 5f, bottom = 500f)
+            assertThat(kosmos.notificationStackAppearanceInteractor.stackTop.value).isEqualTo(5f)
+            assertThat(kosmos.notificationStackAppearanceInteractor.stackBottom.value)
+                .isEqualTo(500f)
+        }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index 781a9a8..7e5205b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -36,7 +36,6 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.LockIconViewController;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.biometrics.AuthController;
@@ -93,7 +92,6 @@
     @Mock private NotificationShadeWindowViewController mNotificationShadeWindowViewController;
     @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
     @Mock private ShadeLockscreenInteractor mShadeLockscreenInteractor;
-    @Mock private LockIconViewController mLockIconViewController;
     @Mock private View mAmbientIndicationContainer;
     @Mock private BiometricUnlockController mBiometricUnlockController;
     @Mock private AuthController mAuthController;
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt
index 30564bb..29f286f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/AvalancheControllerTest.kt
@@ -22,6 +22,7 @@
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.log.logcatLogBuffer
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
 import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
@@ -47,12 +48,14 @@
 @EnableFlags(NotificationThrottleHun.FLAG_NAME)
 class AvalancheControllerTest : SysuiTestCase() {
 
-    private val mAvalancheController = AvalancheController()
-
     // For creating mocks
     @get:Rule var rule: MockitoRule = MockitoJUnit.rule()
     @Mock private val runnableMock: Runnable? = null
 
+    // For creating AvalancheController
+    @Mock private lateinit var dumpManager: DumpManager
+    private lateinit var mAvalancheController: AvalancheController
+
     // For creating TestableHeadsUpManager
     @Mock private val mAccessibilityMgr: AccessibilityManagerWrapper? = null
     private val mUiEventLoggerFake = UiEventLoggerFake()
@@ -73,7 +76,10 @@
             )
             .then { i: InvocationOnMock -> i.getArgument(0) }
 
-        // Initialize TestableHeadsUpManager here instead of at declaration, when mocks will be null
+        // Initialize AvalancheController and TestableHeadsUpManager during setUp instead of
+        // declaration, where mocks are null
+        mAvalancheController = AvalancheController(dumpManager)
+
         testableHeadsUpManager =
             TestableHeadsUpManager(
                 mContext,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
index 3dc4495..7c130be 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/BaseHeadsUpManagerTest.java
@@ -45,6 +45,7 @@
 
 import com.android.internal.logging.testing.UiEventLoggerFake;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
@@ -73,7 +74,9 @@
 
     private UiEventLoggerFake mUiEventLoggerFake = new UiEventLoggerFake();
     private final HeadsUpManagerLogger mLogger = spy(new HeadsUpManagerLogger(logcatLogBuffer()));
-    private AvalancheController mAvalancheController = new AvalancheController();
+
+    @Mock private DumpManager dumpManager;
+    private AvalancheController mAvalancheController;
 
     @Mock private AccessibilityManagerWrapper mAccessibilityMgr;
 
@@ -130,6 +133,7 @@
     public void SysuiSetup() throws Exception {
         super.SysuiSetup();
         mSetFlagsRule.disableFlags(NotificationThrottleHun.FLAG_NAME);
+        mAvalancheController = new AvalancheController(dumpManager);
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java
index 61a79d8..a8a75c0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/policy/HeadsUpManagerPhoneTest.java
@@ -32,6 +32,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.UiEventLogger;
+import com.android.systemui.dump.DumpManager;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.res.R;
 import com.android.systemui.shade.domain.interactor.ShadeInteractor;
@@ -76,7 +77,8 @@
     @Mock private UiEventLogger mUiEventLogger;
     @Mock private JavaAdapter mJavaAdapter;
     @Mock private ShadeInteractor mShadeInteractor;
-    private AvalancheController mAvalancheController = new AvalancheController();
+    @Mock private DumpManager dumpManager;
+    private AvalancheController mAvalancheController;
 
     private static final class TestableHeadsUpManagerPhone extends HeadsUpManagerPhone {
         TestableHeadsUpManagerPhone(
@@ -154,6 +156,8 @@
         mDependency.injectMockDependency(NotificationShadeWindowController.class);
         mContext.getOrCreateTestableResources().addOverride(
                 R.integer.ambient_notification_extension_time, 500);
+
+        mAvalancheController = new AvalancheController(dumpManager);
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt
index 6f7f20b..462f36d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModelTest.kt
@@ -35,7 +35,6 @@
 import com.android.systemui.volume.mediaDeviceSessionInteractor
 import com.android.systemui.volume.mediaOutputActionsInteractor
 import com.android.systemui.volume.mediaOutputInteractor
-import com.android.systemui.volume.panel.volumePanelViewModel
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
@@ -62,7 +61,6 @@
                 MediaOutputViewModel(
                     applicationContext,
                     testScope.backgroundScope,
-                    volumePanelViewModel,
                     mediaOutputActionsInteractor,
                     mediaDeviceSessionInteractor,
                     mediaOutputInteractor,
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_password_motion_layout.xml b/packages/SystemUI/res-keyguard/layout/keyguard_password_motion_layout.xml
index 173d57b..3b6b5a0 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_password_motion_layout.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_password_motion_layout.xml
@@ -91,6 +91,7 @@
                 android:layout_height="wrap_content"
                 android:contentDescription="@string/keyguard_accessibility_password"
                 android:gravity="center_horizontal"
+                android:layout_gravity="center"
                 android:imeOptions="flagForceAscii|actionDone"
                 android:inputType="textPassword"
                 android:maxLength="500"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
index 909d4fc..5aac653 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_password_view.xml
@@ -55,6 +55,7 @@
              android:layout_height="wrap_content"
              android:contentDescription="@string/keyguard_accessibility_password"
              android:gravity="center"
+             android:layout_gravity="center"
              android:singleLine="true"
              android:textStyle="normal"
              android:inputType="textPassword"
diff --git a/packages/SystemUI/res-keyguard/values-nl/strings.xml b/packages/SystemUI/res-keyguard/values-nl/strings.xml
index 81e1007..0206403 100644
--- a/packages/SystemUI/res-keyguard/values-nl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nl/strings.xml
@@ -21,10 +21,10 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Geef je pincode op"</string>
-    <string name="keyguard_enter_pin" msgid="8114529922480276834">"Geef de pincode op"</string>
+    <string name="keyguard_enter_pin" msgid="8114529922480276834">"Voer pincode in"</string>
     <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Geef je patroon op"</string>
     <string name="keyguard_enter_pattern" msgid="7616595160901084119">"Teken het patroon"</string>
-    <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Geef je wachtwoord op"</string>
+    <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Voer je wachtwoord in"</string>
     <string name="keyguard_enter_password" msgid="6483623792371009758">"Geef het wachtwoord op"</string>
     <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Ongeldige kaart."</string>
     <string name="keyguard_charged" msgid="5478247181205188995">"Opgeladen"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index 7e5ae10..bc047be 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -24,7 +24,7 @@
     <string name="keyguard_enter_pin" msgid="8114529922480276834">"輸入 PIN 碼"</string>
     <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"畫出解鎖圖案"</string>
     <string name="keyguard_enter_pattern" msgid="7616595160901084119">"畫出解鎖圖案"</string>
-    <string name="keyguard_enter_your_password" msgid="7225626204122735501">"輸入密碼"</string>
+    <string name="keyguard_enter_your_password" msgid="7225626204122735501">"請輸入密碼"</string>
     <string name="keyguard_enter_password" msgid="6483623792371009758">"輸入密碼"</string>
     <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"卡片無效。"</string>
     <string name="keyguard_charged" msgid="5478247181205188995">"充電完成"</string>
diff --git a/packages/SystemUI/res-product/values-ja/strings.xml b/packages/SystemUI/res-product/values-ja/strings.xml
index 1fc8775..9d054c9 100644
--- a/packages/SystemUI/res-product/values-ja/strings.xml
+++ b/packages/SystemUI/res-product/values-ja/strings.xml
@@ -46,9 +46,9 @@
     <string name="thermal_shutdown_message" product="default" msgid="6685194547904051408">"お使いのスマートフォンは現在、正常に動作しています。\nタップして詳細を表示"</string>
     <string name="thermal_shutdown_message" product="device" msgid="3039675532521590478">"お使いのデバイスは現在、正常に動作しています。\nタップして詳細を表示"</string>
     <string name="thermal_shutdown_message" product="tablet" msgid="5285898074484811386">"お使いのタブレットは現在、正常に動作しています。\nタップして詳細を表示"</string>
-    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"スマートフォンが熱くなりすぎたため電源が OFF になりました。現在は正常に動作しています。\n\nスマートフォンは以下の場合に熱くなる場合があります。\n	• リソースを集中的に使用する機能やアプリ(ゲームアプリ、動画アプリ、ナビアプリなど)を使用\n	• サイズの大きいファイルをダウンロードまたはアップロード\n	• 高温の場所で使用"</string>
-    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"デバイスが熱くなりすぎたため電源が OFF になりました。現在は正常に動作しています。\n\nデバイスは以下の場合に熱くなる場合があります。\n	• リソースを集中的に使用する機能やアプリ(ゲームアプリ、動画アプリ、ナビアプリなど)を使用\n	• サイズの大きいファイルをダウンロードまたはアップロード\n	• 高温の場所で使用"</string>
-    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"タブレットが熱くなりすぎたため電源が OFF になりました。現在は正常に動作しています。\n\nタブレットは以下の場合に熱くなる場合があります。\n	• リソースを集中的に使用する機能やアプリ(ゲームアプリ、動画アプリ、ナビアプリなど)を使用\n	• サイズの大きいファイルをダウンロードまたはアップロード\n	• 高温の場所で使用"</string>
+    <string name="thermal_shutdown_dialog_message" product="default" msgid="6145923570358574186">"スマートフォンの温度上昇により電源が OFF になりました。現在は正常に動作しています。\n\nスマートフォンは以下の場合に熱くなる場合があります。\n	• リソースを集中的に使用する機能やアプリ(ゲームアプリ、動画アプリ、ナビアプリなど)を使用\n	• サイズの大きいファイルをダウンロードまたはアップロード\n	• 高温の場所で使用"</string>
+    <string name="thermal_shutdown_dialog_message" product="device" msgid="3647879000909527365">"デバイスの温度上昇により電源が OFF になりました。現在は正常に動作しています。\n\nデバイスは以下の場合に熱くなる場合があります。\n	• リソースを集中的に使用する機能やアプリ(ゲームアプリ、動画アプリ、ナビアプリなど)を使用\n	• サイズの大きいファイルをダウンロードまたはアップロード\n	• 高温の場所で使用"</string>
+    <string name="thermal_shutdown_dialog_message" product="tablet" msgid="8274487811928782165">"タブレットの温度上昇により電源が OFF になりました。現在は正常に動作しています。\n\nタブレットは以下の場合に熱くなる場合があります。\n	• リソースを集中的に使用する機能やアプリ(ゲームアプリ、動画アプリ、ナビアプリなど)を使用\n	• サイズの大きいファイルをダウンロードまたはアップロード\n	• 高温の場所で使用"</string>
     <string name="high_temp_title" product="default" msgid="5365000411304924115">"スマートフォンの温度が上昇中"</string>
     <string name="high_temp_title" product="device" msgid="6622009907401563664">"デバイスの温度が上昇中"</string>
     <string name="high_temp_title" product="tablet" msgid="9039733706606446616">"タブレットの温度が上昇中"</string>
diff --git a/packages/SystemUI/res/anim/slide_in_up.xml b/packages/SystemUI/res/anim/slide_in_up.xml
new file mode 100644
index 0000000..6089a28
--- /dev/null
+++ b/packages/SystemUI/res/anim/slide_in_up.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<translate
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:fromYDelta="100%p"
+    android:toYDelta="0"
+    android:duration="@android:integer/config_shortAnimTime" />
diff --git a/packages/SystemUI/res/anim/slide_out_down.xml b/packages/SystemUI/res/anim/slide_out_down.xml
new file mode 100644
index 0000000..5a7b591
--- /dev/null
+++ b/packages/SystemUI/res/anim/slide_out_down.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<translate
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:fromYDelta="0"
+    android:toYDelta="100%p"
+    android:duration="@android:integer/config_shortAnimTime" />
diff --git a/packages/SystemUI/res/color/menu_item_text.xml b/packages/SystemUI/res/color/menu_item_text.xml
new file mode 100644
index 0000000..0d05650
--- /dev/null
+++ b/packages/SystemUI/res/color/menu_item_text.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+
+    <item android:state_enabled="false"
+          android:color="?androidprv:attr/materialColorOnSurface"
+          android:alpha="0.38" />
+
+    <item android:color="?androidprv:attr/materialColorOnSurface"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_finder_active.xml b/packages/SystemUI/res/drawable/ic_finder_active.xml
index 8ca221a..2423e34 100644
--- a/packages/SystemUI/res/drawable/ic_finder_active.xml
+++ b/packages/SystemUI/res/drawable/ic_finder_active.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
     android:width="24dp"
     android:height="24dp"
     android:viewportWidth="24"
@@ -10,5 +11,6 @@
   <path
       android:pathData="M12.797,4.005C11.949,3.936 11.203,4.597 11.203,5.467V6.659C8.855,7.001 6.998,8.856 6.653,11.203H5.467C4.597,11.203 3.936,11.948 4.005,12.796L4.006,12.802L4.006,12.809C4.38,16.605 7.399,19.625 11.195,20C12.051,20.087 12.803,19.404 12.803,18.547V17.355C15.154,17.012 17.013,15.154 17.355,12.803H18.54C19.406,12.803 20.079,12.058 19.992,11.196C19.618,7.4 16.606,4.388 12.812,4.006L12.804,4.006L12.797,4.005ZM11.203,9.344V8.283C9.741,8.591 8.588,9.741 8.278,11.203H9.344C9.585,10.4 10.179,9.754 10.942,9.437C11.027,9.402 11.114,9.371 11.203,9.344ZM11.998,13.171C11.358,13.175 10.828,12.651 10.827,12.004H10.827C10.827,11.959 10.83,11.915 10.835,11.871C10.885,11.427 11.185,11.056 11.59,10.902C11.694,10.863 11.806,10.838 11.921,10.83C11.948,10.833 11.976,10.834 12.003,10.834C12.65,10.834 13.177,11.356 13.179,12.007C13.177,12.622 12.695,13.13 12.091,13.175C12.06,13.172 12.029,13.17 11.998,13.171ZM17.353,11.203H18.383C18.028,8.289 15.72,5.979 12.804,5.616V6.658C15.153,7 17.004,8.852 17.353,11.203ZM14.663,11.203C14.395,10.311 13.692,9.611 12.804,9.344V8.283C14.265,8.59 15.414,9.736 15.727,11.203H14.663ZM5.615,12.803H6.654C7.001,15.15 8.855,17.002 11.203,17.346V18.391C8.287,18.034 5.972,15.719 5.615,12.803ZM11.203,14.666C10.316,14.394 9.613,13.692 9.345,12.803H8.279C8.591,14.264 9.741,15.412 11.203,15.721V14.666ZM14.661,12.811H15.729C15.418,14.272 14.266,15.422 12.804,15.73V14.662C13.689,14.396 14.391,13.699 14.661,12.811Z"
       android:fillColor="#ffffff"
-      android:fillType="evenOdd"/>
+      android:fillType="evenOdd"
+      tools:ignore="VectorPath" />
 </vector>
diff --git a/packages/SystemUI/res/drawable/ic_shortcutlist_search.xml b/packages/SystemUI/res/drawable/ic_shortcutlist_search.xml
index 1b12e74..0406f0e 100644
--- a/packages/SystemUI/res/drawable/ic_shortcutlist_search.xml
+++ b/packages/SystemUI/res/drawable/ic_shortcutlist_search.xml
@@ -14,12 +14,15 @@
   limitations under the License
   -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
         android:width="24dp"
         android:height="24dp"
         android:viewportWidth="48"
         android:viewportHeight="48"
-        android:tint="?android:attr/textColorSecondary">
+        android:tint="?androidprv:attr/materialColorOnSurfaceVariant">
     <path
         android:fillColor="@android:color/white"
+        android:strokeColor="@android:color/white"
+        android:strokeWidth="2"
         android:pathData="M39.8,41.95 L26.65,28.8Q25.15,30.1 23.15,30.825Q21.15,31.55 18.9,31.55Q13.5,31.55 9.75,27.8Q6,24.05 6,18.75Q6,13.45 9.75,9.7Q13.5,5.95 18.85,5.95Q24.15,5.95 27.875,9.7Q31.6,13.45 31.6,18.75Q31.6,20.9 30.9,22.9Q30.2,24.9 28.8,26.65L42,39.75ZM18.85,28.55Q22.9,28.55 25.75,25.675Q28.6,22.8 28.6,18.75Q28.6,14.7 25.75,11.825Q22.9,8.95 18.85,8.95Q14.75,8.95 11.875,11.825Q9,14.7 9,18.75Q9,22.8 11.875,25.675Q14.75,28.55 18.85,28.55Z"/>
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/SystemUI/res/drawable/screenrecord_options_spinner_popup_background.xml b/packages/SystemUI/res/drawable/screenrecord_options_spinner_popup_background.xml
index 9a02296..321a04a 100644
--- a/packages/SystemUI/res/drawable/screenrecord_options_spinner_popup_background.xml
+++ b/packages/SystemUI/res/drawable/screenrecord_options_spinner_popup_background.xml
@@ -17,5 +17,5 @@
         xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
         android:shape="rectangle">
     <corners android:radius="@dimen/screenrecord_spinner_background_radius"/>
-    <solid android:color="?androidprv:attr/colorAccentSecondary" />
+    <solid android:color="?androidprv:attr/materialColorSurfaceContainer" />
 </shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/shortcut_button_colored.xml b/packages/SystemUI/res/drawable/shortcut_button_colored.xml
index bf90853..2e2d9b9 100644
--- a/packages/SystemUI/res/drawable/shortcut_button_colored.xml
+++ b/packages/SystemUI/res/drawable/shortcut_button_colored.xml
@@ -21,7 +21,7 @@
         android:color="?android:attr/colorControlHighlight">
         <item>
             <shape android:shape="rectangle">
-                <corners android:radius="16dp"/>
+              <corners android:radius="@dimen/ksh_button_corner_radius"/>
                 <solid android:color="?androidprv:attr/materialColorSurfaceBright"/>
             </shape>
         </item>
diff --git a/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml b/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml
index f692ed97..5b88bb9 100644
--- a/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml
+++ b/packages/SystemUI/res/drawable/shortcut_button_focus_colored.xml
@@ -21,7 +21,7 @@
         android:color="?android:attr/colorControlHighlight">
         <item>
             <shape android:shape="rectangle">
-                <corners android:radius="16dp"/>
+              <corners android:radius="@dimen/ksh_button_corner_radius"/>
                 <solid android:color="?androidprv:attr/materialColorPrimary"/>
             </shape>
         </item>
diff --git a/packages/SystemUI/res/drawable/shortcut_dialog_bg.xml b/packages/SystemUI/res/drawable/shortcut_dialog_bg.xml
index 6ce3eae..aa0b268 100644
--- a/packages/SystemUI/res/drawable/shortcut_dialog_bg.xml
+++ b/packages/SystemUI/res/drawable/shortcut_dialog_bg.xml
@@ -17,8 +17,8 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
     <solid android:color="?android:attr/colorBackground"/>
-    <corners android:topLeftRadius="16dp"
-             android:topRightRadius="16dp"
+    <corners android:topLeftRadius="@dimen/ksh_dialog_top_corner_radius"
+             android:topRightRadius="@dimen/ksh_dialog_top_corner_radius"
              android:bottomLeftRadius="0dp"
              android:bottomRightRadius="0dp"/>
-</shape>
\ No newline at end of file
+</shape>
diff --git a/packages/SystemUI/res/drawable/shortcut_search_background.xml b/packages/SystemUI/res/drawable/shortcut_search_background.xml
index 66fc191..d6847f0 100644
--- a/packages/SystemUI/res/drawable/shortcut_search_background.xml
+++ b/packages/SystemUI/res/drawable/shortcut_search_background.xml
@@ -19,8 +19,8 @@
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
     <item>
         <shape android:shape="rectangle">
-            <solid android:color="?androidprv:attr/colorSurface" />
-            <corners android:radius="24dp" />
+            <solid android:color="?androidprv:attr/materialColorSurfaceBright" />
+            <corners android:radius="@dimen/ksh_search_box_corner_radius" />
         </shape>
     </item>
-</layer-list>
\ No newline at end of file
+</layer-list>
diff --git a/packages/SystemUI/res/drawable/shortcut_search_cancel_button.xml b/packages/SystemUI/res/drawable/shortcut_search_cancel_button.xml
index 6c4d4fb..2675906 100644
--- a/packages/SystemUI/res/drawable/shortcut_search_cancel_button.xml
+++ b/packages/SystemUI/res/drawable/shortcut_search_cancel_button.xml
@@ -20,7 +20,7 @@
     <shape android:shape="oval">
       <size android:width="24dp"
         android:height="24dp" />
-      <solid android:color="?androidprv:attr/colorSurface"/>
+      <solid android:color="?androidprv:attr/materialColorSurfaceBright"/>
     </shape>
   </item>
 </ripple>
diff --git a/packages/SystemUI/res/layout-land/biometric_prompt_constraint_layout.xml b/packages/SystemUI/res/layout-land/biometric_prompt_constraint_layout.xml
index 1777bdf..dabfe9d 100644
--- a/packages/SystemUI/res/layout-land/biometric_prompt_constraint_layout.xml
+++ b/packages/SystemUI/res/layout-land/biometric_prompt_constraint_layout.xml
@@ -39,7 +39,6 @@
         android:layout_height="wrap_content"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintHorizontal_bias="0.8"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         tools:srcCompat="@tools:sample/avatars" />
@@ -60,11 +59,12 @@
         android:id="@+id/scrollView"
         android:layout_width="0dp"
         android:layout_height="0dp"
-        android:fillViewport="true"
-        android:padding="24dp"
-        app:layout_constrainedHeight="true"
-        app:layout_constrainedWidth="true"
-        app:layout_constraintBottom_toTopOf="@+id/buttonBarrier"
+        android:paddingBottom="16dp"
+        android:paddingLeft="24dp"
+        android:paddingRight="12dp"
+        android:paddingTop="24dp"
+        android:fadeScrollbars="false"
+        app:layout_constraintBottom_toTopOf="@+id/button_bar"
         app:layout_constraintEnd_toStartOf="@+id/midGuideline"
         app:layout_constraintStart_toStartOf="@id/leftGuideline"
         app:layout_constraintTop_toTopOf="@+id/topGuideline">
@@ -91,7 +91,7 @@
                 android:layout_width="0dp"
                 android:layout_height="wrap_content"
                 android:textAlignment="viewStart"
-                android:paddingLeft="8dp"
+                android:paddingLeft="16dp"
                 app:layout_constraintBottom_toBottomOf="@+id/logo"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toEndOf="@+id/logo"
@@ -119,7 +119,7 @@
                 style="@style/TextAppearance.AuthCredential.Subtitle"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="12dp"
+                android:layout_marginTop="16dp"
                 android:gravity="@integer/biometric_dialog_text_gravity"
                 android:paddingHorizontal="0dp"
                 android:textAlignment="viewStart"
@@ -133,6 +133,7 @@
                 android:id="@+id/customized_view_container"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
+                android:layout_marginTop="24dp"
                 android:gravity="center_vertical"
                 android:orientation="vertical"
                 android:visibility="gone"
@@ -148,6 +149,7 @@
                 style="@style/TextAppearance.AuthCredential.Description"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:layout_marginTop="24dp"
                 android:gravity="@integer/biometric_dialog_text_gravity"
                 android:paddingHorizontal="0dp"
                 android:textAlignment="viewStart"
@@ -179,7 +181,7 @@
         android:fadingEdge="horizontal"
         android:gravity="center_horizontal"
         android:scrollHorizontally="true"
-        app:layout_constraintBottom_toTopOf="@+id/buttonBarrier"
+        app:layout_constraintBottom_toTopOf="@+id/button_bar"
         app:layout_constraintEnd_toEndOf="@+id/biometric_icon"
         app:layout_constraintStart_toStartOf="@+id/biometric_icon"
         app:layout_constraintTop_toBottomOf="@+id/biometric_icon"
@@ -189,7 +191,7 @@
         android:id="@+id/button_bar"
         layout="@layout/biometric_prompt_button_bar"
         android:layout_width="0dp"
-        android:layout_height="0dp"
+        android:layout_height="wrap_content"
         app:layout_constraintBottom_toTopOf="@id/bottomGuideline"
         app:layout_constraintEnd_toEndOf="@id/scrollView"
         app:layout_constraintStart_toStartOf="@id/scrollView"
@@ -204,14 +206,6 @@
         app:barrierDirection="top"
         app:constraint_referenced_ids="scrollView" />
 
-    <androidx.constraintlayout.widget.Barrier
-        android:id="@+id/buttonBarrier"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:barrierAllowsGoneWidgets="false"
-        app:barrierDirection="top"
-        app:constraint_referenced_ids="button_bar" />
-
     <androidx.constraintlayout.widget.Guideline
         android:id="@+id/leftGuideline"
         android:layout_width="wrap_content"
@@ -238,13 +232,13 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
-        app:layout_constraintGuide_end="@dimen/biometric_dialog_border_padding" />
+        app:layout_constraintGuide_end="40dp" />
 
     <androidx.constraintlayout.widget.Guideline
         android:id="@+id/topGuideline"
         android:layout_width="0dp"
         android:layout_height="0dp"
         android:orientation="horizontal"
-        app:layout_constraintGuide_begin="@dimen/biometric_dialog_border_padding" />
+        app:layout_constraintGuide_begin="0dp" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml b/packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml
index 8b886a7..240abab 100644
--- a/packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml
+++ b/packages/SystemUI/res/layout-sw600dp/biometric_prompt_constraint_layout.xml
@@ -29,28 +29,31 @@
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toStartOf="@+id/rightGuideline"
         app:layout_constraintStart_toStartOf="@+id/leftGuideline"
-        app:layout_constraintTop_toTopOf="@+id/topBarrier" />
+        app:layout_constraintTop_toTopOf="@+id/topBarrier"
+        app:layout_constraintWidth_max="640dp" />
 
     <include
-        layout="@layout/biometric_prompt_button_bar"
         android:id="@+id/button_bar"
+        layout="@layout/biometric_prompt_button_bar"
         android:layout_width="0dp"
-        android:layout_height="match_parent"
-        app:layout_constraintBottom_toTopOf="@id/bottomGuideline"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="40dp"
+        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="@id/panel"
-        app:layout_constraintStart_toStartOf="@id/panel"/>
+        app:layout_constraintStart_toStartOf="@id/panel" />
 
     <ScrollView
         android:id="@+id/scrollView"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
+        android:fadeScrollbars="false"
         android:fillViewport="true"
-        android:paddingBottom="36dp"
-        android:paddingHorizontal="24dp"
+        android:paddingBottom="32dp"
+        android:paddingHorizontal="32dp"
         android:paddingTop="24dp"
         app:layout_constrainedHeight="true"
         app:layout_constrainedWidth="true"
-        app:layout_constraintBottom_toTopOf="@+id/biometric_icon"
+        app:layout_constraintBottom_toTopOf="@+id/scrollBarrier"
         app:layout_constraintEnd_toEndOf="@id/panel"
         app:layout_constraintStart_toStartOf="@id/panel"
         app:layout_constraintTop_toTopOf="@+id/topGuideline"
@@ -63,10 +66,10 @@
 
             <ImageView
                 android:id="@+id/logo"
-                android:contentDescription="@string/biometric_dialog_logo"
                 android:layout_width="@dimen/biometric_prompt_logo_size"
                 android:layout_height="@dimen/biometric_prompt_logo_size"
                 android:layout_gravity="center"
+                android:contentDescription="@string/biometric_dialog_logo"
                 android:scaleType="fitXY"
                 android:visibility="visible"
                 app:layout_constraintBottom_toTopOf="@+id/logo_description"
@@ -79,6 +82,7 @@
                 style="@style/TextAppearance.AuthCredential.LogoDescription"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
+                android:paddingTop="16dp"
                 app:layout_constraintBottom_toTopOf="@+id/title"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
@@ -114,6 +118,7 @@
                 android:layout_height="wrap_content"
                 android:gravity="center_vertical"
                 android:orientation="vertical"
+                android:paddingTop="24dp"
                 android:visibility="gone"
                 app:layout_constraintBottom_toBottomOf="parent"
                 app:layout_constraintEnd_toEndOf="parent"
@@ -126,6 +131,8 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:gravity="@integer/biometric_dialog_text_gravity"
+                android:paddingTop="16dp"
+                android:textAlignment="viewStart"
                 app:layout_constraintBottom_toBottomOf="parent"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
@@ -153,7 +160,7 @@
         android:fadingEdge="horizontal"
         android:gravity="center_horizontal"
         android:scrollHorizontally="true"
-        app:layout_constraintBottom_toTopOf="@+id/buttonBarrier"
+        app:layout_constraintBottom_toTopOf="@+id/button_bar"
         app:layout_constraintEnd_toEndOf="@+id/panel"
         app:layout_constraintStart_toStartOf="@+id/panel"
         app:layout_constraintTop_toBottomOf="@+id/biometric_icon"
@@ -172,12 +179,12 @@
 
     <!-- Try Again Button -->
     <androidx.constraintlayout.widget.Barrier
-        android:id="@+id/buttonBarrier"
+        android:id="@+id/scrollBarrier"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         app:barrierAllowsGoneWidgets="false"
         app:barrierDirection="top"
-        app:constraint_referenced_ids="button_bar" />
+        app:constraint_referenced_ids="biometric_icon, button_bar" />
 
     <!-- Guidelines for setting panel border -->
     <androidx.constraintlayout.widget.Guideline
@@ -199,14 +206,14 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
-        app:layout_constraintGuide_end="@dimen/biometric_dialog_border_padding" />
+        app:layout_constraintGuide_end="40dp" />
 
     <androidx.constraintlayout.widget.Guideline
         android:id="@+id/topGuideline"
         android:layout_width="0dp"
         android:layout_height="0dp"
         android:orientation="horizontal"
-        app:layout_constraintGuide_percent="0.25171" />
+        app:layout_constraintGuide_begin="56dp" />
 
     <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper
         android:id="@+id/biometric_icon"
@@ -216,7 +223,7 @@
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintVertical_bias="0.8"
+        app:layout_constraintVertical_bias="1.0"
         tools:srcCompat="@tools:sample/avatars" />
 
     <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper
diff --git a/packages/SystemUI/res/layout/biometric_prompt_button_bar.xml b/packages/SystemUI/res/layout/biometric_prompt_button_bar.xml
index 810c7433..4d2310a 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_button_bar.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_button_bar.xml
@@ -17,12 +17,13 @@
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:theme="@style/Theme.SystemUI.Dialog"
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
     <!-- Negative Button, reserved for app -->
     <Button
         android:id="@+id/button_negative"
-        style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+        style="@style/Widget.Dialog.Button.BorderButton"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
@@ -36,7 +37,7 @@
     <!-- Cancel Button, replaces negative button when biometric is accepted -->
     <Button
         android:id="@+id/button_cancel"
-        style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+        style="@style/Widget.Dialog.Button.BorderButton"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
@@ -49,7 +50,7 @@
     <!-- "Use Credential" Button, replaces if device credential is allowed -->
     <Button
         android:id="@+id/button_use_credential"
-        style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
+        style="@style/Widget.Dialog.Button.BorderButton"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
@@ -61,7 +62,7 @@
     <!-- Positive Button -->
     <Button
         android:id="@+id/button_confirm"
-        style="@*android:style/Widget.DeviceDefault.Button.Colored"
+        style="@style/Widget.Dialog.Button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
@@ -76,7 +77,7 @@
     <!-- Try Again Button -->
     <Button
         android:id="@+id/button_try_again"
-        style="@*android:style/Widget.DeviceDefault.Button.Colored"
+        style="@style/Widget.Dialog.Button"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
diff --git a/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml b/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml
index 74bf318..4aa6092 100644
--- a/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml
+++ b/packages/SystemUI/res/layout/biometric_prompt_constraint_layout.xml
@@ -35,24 +35,26 @@
         android:id="@+id/button_bar"
         layout="@layout/biometric_prompt_button_bar"
         android:layout_width="0dp"
-        android:layout_height="match_parent"
-        app:layout_constraintBottom_toTopOf="@id/bottomGuideline"
+        android:layout_height="wrap_content"
+        android:layout_marginBottom="40dp"
+        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="@id/panel"
         app:layout_constraintStart_toStartOf="@id/panel" />
 
     <ScrollView
         android:id="@+id/scrollView"
-        android:layout_width="match_parent"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:fillViewport="true"
+        android:fadeScrollbars="false"
         android:paddingBottom="36dp"
         android:paddingHorizontal="24dp"
         android:paddingTop="24dp"
         app:layout_constrainedHeight="true"
         app:layout_constrainedWidth="true"
-        app:layout_constraintBottom_toTopOf="@+id/biometric_icon"
-        app:layout_constraintEnd_toEndOf="@id/rightGuideline"
-        app:layout_constraintStart_toStartOf="@id/leftGuideline"
+        app:layout_constraintBottom_toTopOf="@+id/scrollBarrier"
+        app:layout_constraintEnd_toEndOf="@id/panel"
+        app:layout_constraintStart_toStartOf="@id/panel"
         app:layout_constraintTop_toTopOf="@+id/topGuideline"
         app:layout_constraintVertical_bias="1.0">
 
@@ -79,6 +81,7 @@
                 style="@style/TextAppearance.AuthCredential.LogoDescription"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
+                android:paddingTop="8dp"
                 app:layout_constraintBottom_toTopOf="@+id/title"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
@@ -114,8 +117,8 @@
                 android:layout_height="wrap_content"
                 android:gravity="center_vertical"
                 android:orientation="vertical"
-                android:visibility="gone"
                 android:paddingTop="24dp"
+                android:visibility="gone"
                 app:layout_constraintBottom_toBottomOf="parent"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
@@ -127,7 +130,8 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:gravity="@integer/biometric_dialog_text_gravity"
-                android:paddingTop="24dp"
+                android:textAlignment="viewStart"
+                android:paddingTop="16dp"
                 app:layout_constraintBottom_toBottomOf="parent"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
@@ -154,7 +158,7 @@
         android:fadingEdge="horizontal"
         android:gravity="center_horizontal"
         android:scrollHorizontally="true"
-        app:layout_constraintBottom_toTopOf="@+id/buttonBarrier"
+        app:layout_constraintBottom_toTopOf="@+id/button_bar"
         app:layout_constraintEnd_toEndOf="@+id/panel"
         app:layout_constraintStart_toStartOf="@+id/panel"
         app:layout_constraintTop_toBottomOf="@+id/biometric_icon"
@@ -169,12 +173,12 @@
         app:constraint_referenced_ids="scrollView" />
 
     <androidx.constraintlayout.widget.Barrier
-        android:id="@+id/buttonBarrier"
+        android:id="@+id/scrollBarrier"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         app:barrierAllowsGoneWidgets="false"
         app:barrierDirection="top"
-        app:constraint_referenced_ids="button_bar" />
+        app:constraint_referenced_ids="biometric_icon, button_bar" />
 
     <androidx.constraintlayout.widget.Guideline
         android:id="@+id/leftGuideline"
@@ -195,14 +199,14 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
-        app:layout_constraintGuide_end="@dimen/biometric_dialog_border_padding" />
+        app:layout_constraintGuide_end="40dp" />
 
     <androidx.constraintlayout.widget.Guideline
         android:id="@+id/topGuideline"
         android:layout_width="0dp"
         android:layout_height="0dp"
         android:orientation="horizontal"
-        app:layout_constraintGuide_percent="0.25" />
+        app:layout_constraintGuide_begin="119dp" />
 
     <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper
         android:id="@+id/biometric_icon"
@@ -212,7 +216,7 @@
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
-        app:layout_constraintVertical_bias="0.8"
+        app:layout_constraintVertical_bias="1.0"
         tools:srcCompat="@tools:sample/avatars" />
 
     <com.android.systemui.biometrics.BiometricPromptLottieViewWrapper
diff --git a/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml b/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
index ae24313..14b3b55 100644
--- a/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
+++ b/packages/SystemUI/res/layout/clipboard_edit_text_activity.xml
@@ -3,6 +3,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/editor_root"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
diff --git a/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml b/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml
new file mode 100644
index 0000000..a5cdaeb
--- /dev/null
+++ b/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml
@@ -0,0 +1,56 @@
+<!--
+    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.
+-->
+
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/root"
+    style="@style/Widget.SliceView.Panel"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+
+    <androidx.recyclerview.widget.RecyclerView
+        android:id="@+id/device_list"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintBottom_toTopOf="@id/pair_new_device_button" />
+
+    <Button
+        android:id="@+id/pair_new_device_button"
+        style="@style/BluetoothTileDialog.Device"
+        android:paddingEnd="0dp"
+        android:paddingStart="20dp"
+        android:background="@drawable/bluetooth_tile_dialog_bg_off"
+        android:layout_width="0dp"
+        android:layout_height="64dp"
+        android:contentDescription="@string/accessibility_hearing_device_pair_new_device"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/device_list"
+        android:drawableStart="@drawable/ic_add"
+        android:drawablePadding="20dp"
+        android:drawableTint="?android:attr/textColorPrimary"
+        android:text="@string/quick_settings_pair_hearing_devices"
+        android:textSize="14sp"
+        android:textAppearance="@style/TextAppearance.Dialog.Title"
+        android:textDirection="locale"
+        android:textAlignment="viewStart"
+        android:maxLines="1"
+        android:ellipsize="end" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml b/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
index a005100..5ab2327 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcut_app_item.xml
@@ -15,13 +15,14 @@
   ~ limitations under the License
   -->
 <com.android.systemui.statusbar.KeyboardShortcutAppItemLayout
+        xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:orientation="horizontal"
         android:background="@drawable/list_item_background"
         android:focusable="true"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:minHeight="48dp"
+        android:minHeight="@dimen/ksh_app_item_minimum_height"
         android:paddingBottom="8dp">
     <ImageView
             android:id="@+id/keyboard_shortcuts_icon"
@@ -39,7 +40,8 @@
             android:layout_height="wrap_content"
             android:paddingEnd="12dp"
             android:paddingBottom="4dp"
-            android:textColor="?android:attr/textColorPrimary"
+            android:textColor="?androidprv:attr/materialColorOnSurface"
+            android:textAppearance="?android:attr/textAppearanceMedium"
             android:textSize="16sp"
             android:maxLines="5"
             android:singleLine="false"
diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_category_short_separator.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_category_short_separator.xml
index 530e46e..76e5b12 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcuts_category_short_separator.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcuts_category_short_separator.xml
@@ -15,6 +15,6 @@
   limitations under the License
   -->
 <View xmlns:android="http://schemas.android.com/apk/res/android"
-      android:layout_marginTop="8dp"
-      android:layout_marginBottom="0dp"
+      android:layout_marginTop="@dimen/ksh_category_separator_margin"
+      android:layout_marginBottom="@dimen/ksh_category_separator_margin"
       style="@style/ShortcutHorizontalDivider" />
diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml
index 4f100f6..6e7fde6 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcuts_category_title.xml
@@ -16,10 +16,12 @@
   ~ limitations under the License
   -->
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
+          android:textAppearance="?android:attr/textAppearanceMedium"
           android:textSize="14sp"
-          android:fontFamily="sans-serif-medium"
+          android:textColor="?androidprv:attr/materialColorPrimary"
           android:importantForAccessibility="yes"
           android:paddingTop="20dp"
           android:paddingBottom="10dp"/>
diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml
index f6042e4..2cfd644 100644
--- a/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml
+++ b/packages/SystemUI/res/layout/keyboard_shortcuts_search_view.xml
@@ -16,15 +16,21 @@
 
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:background="@drawable/shortcut_dialog_bg"
     android:layout_width="@dimen/ksh_layout_width"
     android:layout_height="wrap_content"
     android:orientation="vertical">
+
+    <com.google.android.material.bottomsheet.BottomSheetDragHandleView
+        android:id="@+id/drag_handle"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"/>
+
     <TextView
         android:id="@+id/shortcut_title"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginTop="40dp"
         android:layout_gravity="center_horizontal"
         android:textAppearance="?android:attr/textAppearanceLarge"
         android:textColor="?android:attr/textColorPrimary"
@@ -39,44 +45,47 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="24dp"
             android:layout_marginBottom="24dp"
-            android:layout_marginStart="49dp"
-            android:layout_marginEnd="49dp"
+            android:layout_marginStart="@dimen/ksh_container_horizontal_margin"
+            android:layout_marginEnd="@dimen/ksh_container_horizontal_margin"
             android:padding="16dp"
             android:background="@drawable/shortcut_search_background"
             android:drawableStart="@drawable/ic_shortcutlist_search"
             android:drawablePadding="15dp"
             android:singleLine="true"
-            android:textColor="?android:attr/textColorPrimary"
+            android:textColor="?androidprv:attr/materialColorOnSurfaceVariant"
             android:inputType="text"
             android:textDirection="locale"
             android:textAlignment="viewStart"
             android:hint="@string/keyboard_shortcut_search_list_hint"
-            android:textColorHint="?android:attr/textColorTertiary" />
+            android:textAppearance="@android:style/TextAppearance.Material"
+            android:textSize="16sp"
+            android:textColorHint="?androidprv:attr/materialColorOutline" />
 
         <ImageButton
             android:id="@+id/keyboard_shortcuts_search_cancel"
             android:layout_gravity="center_vertical|end"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginEnd="49dp"
+            android:layout_marginEnd="@dimen/ksh_container_horizontal_margin"
             android:padding="16dp"
             android:contentDescription="@string/keyboard_shortcut_clear_text"
             android:src="@drawable/ic_shortcutlist_search_button_cancel"
             android:background="@drawable/shortcut_search_cancel_button"
             style="@android:style/Widget.Material.Button.Borderless.Small"
-            android:pointerIcon="arrow" />
+            android:pointerIcon="arrow"
+            android:visibility="gone" />
     </FrameLayout>
 
     <HorizontalScrollView
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginStart="49dp"
+        android:layout_marginStart="@dimen/ksh_container_horizontal_margin"
         android:layout_marginEnd="0dp"
         android:scrollbars="none">
         <LinearLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:gravity="center_vertical"
+            android:layout_gravity="center_vertical"
             android:orientation="horizontal">
             <Button
                 android:id="@+id/shortcut_system"
@@ -113,29 +122,29 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="50dp"
-        android:layout_marginStart="49dp"
-        android:layout_marginEnd="49dp"
+        android:layout_marginStart="@dimen/ksh_container_horizontal_margin"
+        android:layout_marginEnd="@dimen/ksh_container_horizontal_margin"
         android:layout_gravity="center_horizontal"
         android:textAppearance="?android:attr/textAppearanceMedium"
         android:textColor="?android:attr/textColorPrimary"
         android:text="@string/keyboard_shortcut_search_list_no_result"/>
 
-    <ScrollView
+    <androidx.core.widget.NestedScrollView
         android:id="@+id/keyboard_shortcuts_scroll_view"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginTop="16dp"
-        android:layout_marginStart="49dp"
-        android:layout_marginEnd="49dp"
+        android:layout_marginStart="@dimen/ksh_container_horizontal_margin"
+        android:layout_marginEnd="@dimen/ksh_container_horizontal_margin"
         android:overScrollMode="never"
-        android:layout_marginBottom="16dp"
+        android:clipToPadding="false"
         android:scrollbars="none">
         <LinearLayout
             android:id="@+id/keyboard_shortcuts_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="vertical"/>
-    </ScrollView>
+    </androidx.core.widget.NestedScrollView>
     <!-- Required for stretching to full available height when the items in the scroll view
          occupy less space then the full height -->
     <View
diff --git a/packages/SystemUI/res/layout/screen_share_dialog_spinner_item_text.xml b/packages/SystemUI/res/layout/screen_share_dialog_spinner_item_text.xml
index 1e5b249..8c31713 100644
--- a/packages/SystemUI/res/layout/screen_share_dialog_spinner_item_text.xml
+++ b/packages/SystemUI/res/layout/screen_share_dialog_spinner_item_text.xml
@@ -30,7 +30,7 @@
         android:ellipsize="marquee"
         android:singleLine="true"
         android:textAppearance="?android:attr/textAppearanceMedium"
-        android:textColor="?androidprv:attr/textColorOnAccent" />
+        android:textColor="@color/menu_item_text" />
 
     <TextView
         android:id="@android:id/text2"
@@ -39,6 +39,6 @@
         android:ellipsize="marquee"
         android:singleLine="true"
         android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="?androidprv:attr/colorError" />
+        android:textColor="?androidprv:attr/materialColorError" />
 
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/screenshot_shelf.xml b/packages/SystemUI/res/layout/screenshot_shelf.xml
index c988b4a..eeb64bd8 100644
--- a/packages/SystemUI/res/layout/screenshot_shelf.xml
+++ b/packages/SystemUI/res/layout/screenshot_shelf.xml
@@ -51,15 +51,7 @@
         <LinearLayout
             android:id="@+id/screenshot_actions"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content">
-            <include layout="@layout/overlay_action_chip"
-                     android:id="@+id/screenshot_share_chip"/>
-            <include layout="@layout/overlay_action_chip"
-                     android:id="@+id/screenshot_edit_chip"/>
-            <include layout="@layout/overlay_action_chip"
-                     android:id="@+id/screenshot_scroll_chip"
-                     android:visibility="gone" />
-        </LinearLayout>
+            android:layout_height="wrap_content" />
     </HorizontalScrollView>
     <View
         android:id="@+id/screenshot_preview_border"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index b1b4748..2027d16 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Die neem van skermskote word deur jou IT-admin geblokkeer"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Wysig"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Wysig skermkiekie"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Deel"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Deel skermskoot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Vang meer vas"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Maak skermkiekie toe"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skandeer tans gesig"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Stuur"</string>
     <string name="cancel" msgid="1089011503403416730">"Kanselleer"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Applogo"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bevestig"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Probeer weer"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Tik om stawing te kanselleer"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gesig is herken. Druk die ontsluitikoon om voort te gaan."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Gestaaf"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Kanselleer stawing"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Meer opsies"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gebruik PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gebruik patroon"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Gebruik wagwoord"</string>
@@ -281,7 +282,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"Invoer"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"Gehoortoestelle"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Skakel tans aan …"</string>
-    <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Outo-draai"</string>
+    <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Outodraai"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Outodraai skerm"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Ligging"</string>
     <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Sluimerskerm"</string>
@@ -362,11 +363,19 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standaard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Medium"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Hoog"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblokkeer toestelmikrofoon?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblokkeer toestelkamera?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Deblokkeer toestelkamera en mikrofoon?"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Dit deblokkeer toegang vir alle programme en dienste wat toegelaat word om jou mikrofoon te gebruik."</string>
-    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Dit deblokkeer toegang vir alle programme en dienste wat toegelaat word om jou kamera te gebruik."</string>
+    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Dit deblokkeer toegang vir alle apps en dienste wat toegelaat word om jou mikrofoon te gebruik."</string>
+    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Dit deblokkeer toegang vir alle apps en dienste wat toegelaat word om jou kamera te gebruik."</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Dit deblokkeer toegang vir alle programme en dienste wat toegelaat word om jou kamera of mikrofoon te gebruik."</string>
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Mikrofoon is geblokkeer"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Kamera is geblokkeer"</string>
@@ -439,6 +448,10 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Verwyder"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Voeg legstuk by"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Klaar"</string>
+    <!-- no translation found for label_for_button_in_empty_state_cta (7314975555382055823) -->
+    <skip />
+    <!-- no translation found for title_for_empty_state_cta (6161654421223450530) -->
+    <skip />
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Laat enige legstuk op die sluitskerm toe?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Maak instellings oop"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Hervat werkapps?"</string>
@@ -540,13 +553,11 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Hierdie toestel word deur jou ouer bestuur. Jou ouer kan inligting sien en bestuur soos die programme wat jy gebruik, jou ligging en jou skermtyd."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Ontsluit gehou deur TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Toestel is gesluit; te veel stawingpogings"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Toestel is gesluit\nKon nie staaf nie"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Klankinstellings"</string>
-    <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Gee outomaties mediaopskrifte"</string>
+    <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Verskaf outomaties onderskrifte vir media"</string>
     <string name="accessibility_volume_close_odi_captions_tip" msgid="8924753283621160480">"Maak wenk oor onderskrifte toe"</string>
     <string name="volume_odi_captions_content_description" msgid="4172765742046013630">"Onderskrifteoorlegger"</string>
     <string name="volume_odi_captions_hint_enable" msgid="2073091194012843195">"aktiveer"</string>
@@ -765,10 +776,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Gaan by verdeelde skerm in met huidige app aan die regterkant"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Gaan by verdeelde skerm in met huidige app aan die linkerkant"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Skakel oor van verdeelde skerm na volskerm"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skakel oor na app regs of onder terwyl jy verdeelde skerm gebruik"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skakel oor na app links of bo terwyl jy verdeelde skerm gebruik"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Tydens verdeelde skerm: verplaas ’n app van een skerm na ’n ander"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Invoer"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Skakel oor na volgende taal"</string>
@@ -895,12 +904,12 @@
     <string name="instant_apps_title" msgid="8942706782103036910">"<xliff:g id="APP">%1$s</xliff:g> loop tans"</string>
     <string name="instant_apps_message" msgid="6112428971833011754">"Program is oopgemaak sonder dat dit geïnstalleer is."</string>
     <string name="instant_apps_message_with_help" msgid="1816952263531203932">"Program is oopgemaak sonder dat dit geïnstalleer is. Tik om meer te wete te kom."</string>
-    <string name="app_info" msgid="5153758994129963243">"Programinligting"</string>
+    <string name="app_info" msgid="5153758994129963243">"Appinligting"</string>
     <string name="go_to_web" msgid="636673528981366511">"Gaan na blaaier"</string>
     <string name="mobile_data" msgid="4564407557775397216">"Mobiele data"</string>
     <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
-    <string name="wifi_is_off" msgid="5389597396308001471">"Wi-Fi is af"</string>
+    <string name="wifi_is_off" msgid="5389597396308001471">"Wi-fi is af"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth is af"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Moenie Steur Nie is af"</string>
     <string name="dnd_is_on" msgid="7009368176361546279">"Moenie Steur Nie is aan"</string>
@@ -1076,7 +1085,7 @@
     <string name="controls_error_removed" msgid="6675638069846014366">"Nie gekry nie"</string>
     <string name="controls_error_removed_title" msgid="1207794911208047818">"Kontrole is nie beskikbaar nie"</string>
     <string name="controls_error_removed_message" msgid="2885911717034750542">"Kon nie by <xliff:g id="DEVICE">%1$s</xliff:g> ingaan nie. Gaan die <xliff:g id="APPLICATION">%2$s</xliff:g>-program na om seker te maak dat die kontrole steeds beskikbaar is en dat die programinstellings nie verander het nie."</string>
-    <string name="controls_open_app" msgid="483650971094300141">"Maak program oop"</string>
+    <string name="controls_open_app" msgid="483650971094300141">"Maak app oop"</string>
     <string name="controls_error_generic" msgid="352500456918362905">"Kan nie status laai nie"</string>
     <string name="controls_error_failed" msgid="960228639198558525">"Fout, probeer weer"</string>
     <string name="controls_menu_add" msgid="4447246119229920050">"Voeg kontroles by"</string>
@@ -1240,7 +1249,7 @@
     <string name="home_quick_affordance_unavailable_configure_the_app" msgid="604424593994493281">"• Minstens een toestel of toestelpaneel is beskikbaar"</string>
     <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Kies ’n versteknotasapp om die notaneemkortpad te gebruik"</string>
     <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Kies app"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Raak en hou kortpad"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Raak-en-hou-kortpad"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Kanselleer"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Wissel skerms nou"</string>
     <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Ontvou foon"</string>
diff --git a/packages/SystemUI/res/values-af/tiles_states_strings.xml b/packages/SystemUI/res/values-af/tiles_states_strings.xml
index 1427574..8f0532e 100644
--- a/packages/SystemUI/res/values-af/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-af/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Af"</item>
     <item msgid="5137565285664080143">"Aan"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 8daa20e..a3700f2 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ቅጽበታዊ ገፅ እይታዎችን ማንሳት በእርስዎ አይቲ አስተዳዳሪ ታግዷል"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"አርትዕ ያድርጉ"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"ቅጽበታዊ ገፅ ዕይታን አርትዕ ያድርጉ"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"አጋራ"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"ቅጽበታዊ ገፅ እይታን ያጋሩ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ተጨማሪ ይቅረጹ"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ቅጽበታዊ ገፅ ዕይታን አሰናብት"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"የቅኝት ፊት"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ላክ"</string>
     <string name="cancel" msgid="1089011503403416730">"ይቅር"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"የመተግበሪያ ዓርማ"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"አረጋግጥ"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"እንደገና ይሞክሩ"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ማረጋገጥን ለመሰረዝ መታ ያድርጉ"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"መልክ ተለይቶ ታውቋል። ለመቀጠል የመክፈቻ አዶውን ይጫኑ።"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"የተረጋገጠ"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ማረጋገጥን ሰርዝ"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ተጨማሪ አማራጮች"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ፒን ይጠቀሙ"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ሥርዓተ ጥለትን ተጠቀም"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"የይለፍ ቃልን ተጠቀም"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"መደበኛ"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"መካከለኛ"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"ከፍተኛ"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"የመስሚያ መሣሪያዎች"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"የመሣሪያ ማይክሮፎን እገዳ ይነሳ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"የመሣሪያ ካሜራ እገዳ ይነሳ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"የመሣሪያ ካሜራ እና ማይክሮፎን እገዳ ይነሳ?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"አስወግድ"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ምግብር አክል"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"ተከናውኗል"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"ምግብሮችን ያክሉ"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"ጡባዊዎን ሳይከፍቱ የሚወዷቸው የመተግበሪያ ምግብሮች ፈጣን መዳረሻን ያግኙ።"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"በማያ ገጽ ቁልፍ ላይ ማንኛውንም ምግብር ይፈቀድ?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"ቅንብሮችን ክፈት"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"የሥራ መተግበሪያዎች ከቆሙበት ይቀጥሉ?"</string>
@@ -540,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ይህ መሣሪያ በእርስዎ ወላጅ የሚተዳደር ነው። ወላጅዎ የሚጠቀሙባቸውን መተግበሪያዎች፣ አካባቢዎን እና የማያ ገፅ ጊዜዎን የመሳሰሉ መረጃዎችን ማየት እና ማስተዳደር ይችላል።"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"በ TrustAgent እንደተከፈተ ቀርቷል"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"መሣሪያው ተቆልፏል፣ ከልክ በላይ ብዙ የማረጋገጫ ሙከራዎች"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"መሣሪያው ተቆልፏል\nማረጋገጥ አልተሳካም"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>። <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"የድምፅ ቅንብሮች"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"ራስሰር የሥዕል መግለጫ ጽሑፍን ሚዲያ"</string>
@@ -765,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"ለአርኤችኤስ በአሁኑ መተግበሪያ ወደ የተከፈለ ማያ ገጽ ግባ"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"ለኤልኤችኤስ በአሁኑ መተግበሪያ ወደ የተከፈለ ማያ ገጽ ይግቡ"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"ከየተከፈለ ማያ ገጽ ወደ ሙሉ ገጽ ዕይታ ቀይር"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"የተከፈለ ማያ ገጽን ሲጠቀሙ በቀኝ ወይም ከታች ወዳለ መተግበሪያ ይቀይሩ"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"የተከፈለ ማያ ገጽን ሲጠቀሙ በቀኝ ወይም ከላይ ወዳለ መተግበሪያ ይቀይሩ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"በተከፈለ ማያ ገጽ ወቅት፡- መተግበሪያን ከአንዱ ወደ ሌላው ተካ"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ግቤት"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"ወደ ቀጣዩ ቋንቋ ቀይር"</string>
diff --git a/packages/SystemUI/res/values-am/tiles_states_strings.xml b/packages/SystemUI/res/values-am/tiles_states_strings.xml
index ab0b68b..a3c590c 100644
--- a/packages/SystemUI/res/values-am/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-am/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"ጠፍቷል"</item>
     <item msgid="5137565285664080143">"በርቷል"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"አይገኝም"</item>
+    <item msgid="3079622119444911877">"አጥፋ"</item>
+    <item msgid="3028994095749238254">"አብራ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 8cfbf6a..767e909 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"حَظَر مشرف تكنولوجيا المعلومات عملية أخذ لقطات للشاشة."</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"تعديل"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"تعديل لقطة الشاشة"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"مشاركة"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"مشاركة لقطة الشاشة"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"التقاط المزيد من المحتوى"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"إغلاق لقطة الشاشة"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"مسح الوجه"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"إرسال"</string>
     <string name="cancel" msgid="1089011503403416730">"إلغاء"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"شعار التطبيق"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"تأكيد"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"إعادة المحاولة"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"انقر لإلغاء المصادقة."</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"تم التعرّف على الوجه. للمتابعة، اضغط على رمز فتح القفل."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"مصادقة"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"إلغاء المصادقة"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"مزيد من الخيارات"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"استخدام رقم تعريف شخصي"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"استخدام نقش"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"استخدام كلمة المرور"</string>
@@ -264,7 +265,7 @@
     <string name="quick_settings_dnd_label" msgid="7728690179108024338">"عدم الإزعاج"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"بلوتوث"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"لا يتوفر أي أجهزة مقترنة"</string>
-    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"انقر لربط جهاز أو إلغاء ربطه."</string>
+    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"انقر لربط جهاز أو إلغاء ربطه"</string>
     <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"إقران جهاز جديد"</string>
     <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"عرض الكل"</string>
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"استخدام البلوتوث"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"عادي"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"متوسط"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"مرتفع"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"هل تريد إزالة حظر ميكروفون الجهاز؟"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"هل تريد إزالة حظر كاميرا الجهاز؟"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"هل تريد إزالة حظر الكاميرا والميكروفون؟"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"إزالة"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"إضافة تطبيق مصغّر"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"تم"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"إضافة تطبيقات مصغّرة"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"يمكنك الوصول سريعًا إلى تطبيقاتك المصغّرة المفضّلة بدون فتح قفل جهازك اللوحي."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"هل تريد السماح بعرض أي تطبيق مصغّر على شاشة القفل؟"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"فتح الإعدادات"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"أتريد إعادة تفعيل تطبيقات العمل؟"</string>
@@ -451,7 +462,7 @@
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"البدء من جديد"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"نعم، متابعة"</string>
     <string name="guest_notification_app_name" msgid="2110425506754205509">"وضع الضيف"</string>
-    <string name="guest_notification_session_active" msgid="5567273684713471450">"أنت تستخدِم وضع الضيف."</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"أنت تستخدِم وضع الضيف"</string>
     <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"ستؤدي إضافة مُستخدِم جديد إلى الخروج من وضع الضيف وحذف كل التطبيقات والبيانات من جلسة الضيف الحالية."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"تم الوصول إلى أقصى عدد للمستخدمين"</string>
     <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{يمكن إنشاء مستخدم واحد فقط.}zero{يمكنك إضافة ما يصل إلى # مستخدم}two{يمكنك إضافة ما يصل إلى مستخدمَين}few{يمكنك إضافة ما يصل إلى # مستخدمِين}many{يمكنك إضافة ما يصل إلى # مستخدمًا}other{يمكنك إضافة ما يصل إلى # مستخدم}}"</string>
@@ -494,7 +505,7 @@
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"محو جميع الإشعارات الصامتة"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"تم إيقاف الإشعارات مؤقتًا وفقًا لإعداد \"عدم الإزعاج\""</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"البدء الآن"</string>
-    <string name="empty_shade_text" msgid="8935967157319717412">"ما مِن إشعارات."</string>
+    <string name="empty_shade_text" msgid="8935967157319717412">"ما مِن إشعارات"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"ما مِن إشعارات جديدة"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"افتَح قفل الشاشة لعرض الإشعارات الأقدم."</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"يتولّى أحد الوالدين إدارة هذا الجهاز."</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"يتولّى أحد الوالدين إدارة هذا الجهاز. يمكن للوالدين عرض وإدارة معلوماتك، مثلاً التطبيقات التي تستخدمها وموقعك الجغرافي ووقت النظر إلى الشاشة."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"شبكة افتراضية خاصة"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"‏فتح القفل باستمرار بواسطة TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"تم قفل الجهاز بسبب إجراء العديد من محاولات المصادقة"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"تم قفل الجهاز\nتعذّرت المصادقة"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"إعدادات الصوت"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"شرح تلقائي للوسائط"</string>
@@ -587,9 +596,9 @@
     <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"اهتزاز"</string>
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"كتم الصوت"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"البثّ"</string>
-    <string name="stream_notification_unavailable" msgid="4313854556205836435">"يتعذّر التغيير بسبب كتم صوت الرنين."</string>
+    <string name="stream_notification_unavailable" msgid="4313854556205836435">"غير متاح بسبب كتم صوت الرنين"</string>
     <string name="stream_alarm_unavailable" msgid="4059817189292197839">"مستوى الصوت غير متاح بسبب تفعيل وضع \"عدم الإزعاج\""</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"مستوى الصوت غير متاح بسبب تفعيل وضع \"عدم الإزعاج\""</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"مستوى الصوت غير متاح لأنّ وضع \"عدم الإزعاج\" مفعّل"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"‏%1$s. انقر لإلغاء التجاهل."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"‏%1$s. انقر للتعيين على الاهتزاز. قد يتم تجاهل خدمات \"سهولة الاستخدام\"."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"‏%1$s. انقر للتجاهل. قد يتم تجاهل خدمات \"سهولة الاستخدام\"."</string>
@@ -597,8 +606,8 @@
     <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"‏%1$s. انقر لكتم الصوت."</string>
     <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"التحكُّم في مستوى الضجيج"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"الصوت المكاني"</string>
-    <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"إيقاف"</string>
-    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"مفعّل"</string>
+    <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"غير مفعّل"</string>
+    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"تفعيل"</string>
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"تتبُّع حركة الرأس"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"انقر لتغيير وضع الرنين."</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"كتم الصوت"</string>
@@ -623,7 +632,7 @@
     <string name="wallet_title" msgid="5369767670735827105">"محفظة"</string>
     <string name="wallet_empty_state_label" msgid="7776761245237530394">"يمكنك إعداد طريقة دفع لإجراء عمليات شراء بسرعة وأمان أكبر باستخدام هاتفك."</string>
     <string name="wallet_app_button_label" msgid="7123784239111190992">"عرض الكل"</string>
-    <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"انقر لفتح قفل الجهاز."</string>
+    <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"انقر لفتح قفل الجهاز"</string>
     <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"جارٍ تحديث تطبيق المحفظة"</string>
     <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"فتح القفل للاستخدام"</string>
     <string name="wallet_error_generic" msgid="257704570182963611">"حدثت مشكلة أثناء الحصول على البطاقات، يُرجى إعادة المحاولة لاحقًا."</string>
@@ -669,7 +678,7 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"‏&lt;b&gt;الحالة:&lt;/b&gt; تم خفض الترتيب"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل."</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل وتظهر على شكل فقاعة."</string>
-    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل، وتقاطع ميزة \"عدم الإزعاج\"."</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل، وتُقاطع ميزة \"عدم الإزعاج\""</string>
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"تظهر في أعلى إشعارات المحادثات وكصورة ملف شخصي على شاشة القفل وتظهر على شكل فقاعة لمقاطعة ميزة \"عدم الإزعاج\"."</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"الأولوية"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"لا يدعم تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> ميزات المحادثات."</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"تفعيل وضع \"تقسيم الشاشة\" مع عرض التطبيق الحالي على يسار الشاشة"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"تفعيل وضع \"تقسيم الشاشة\" مع عرض التطبيق الحالي على يمين الشاشة"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"التبديل من وضع \"تقسيم الشاشة\" إلى وضع \"ملء الشاشة\""</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"التبديل إلى التطبيق على اليسار أو الأسفل أثناء استخدام \"تقسيم الشاشة\""</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"التبديل إلى التطبيق على اليمين أو الأعلى أثناء استخدام \"تقسيم الشاشة\""</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"استبدال تطبيق بآخر في وضع \"تقسيم الشاشة\""</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"إدخال"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"التبديل إلى اللغة التالية"</string>
@@ -1117,8 +1124,8 @@
     <string name="build_number_copy_toast" msgid="877720921605503046">"تم نسخ رقم الإصدار إلى الحافظة."</string>
     <string name="basic_status" msgid="2315371112182658176">"محادثة مفتوحة"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"التطبيقات المصغّرة للمحادثات"</string>
-    <string name="select_conversation_text" msgid="3376048251434956013">"انقر على محادثة لإضافتها إلى \"الشاشة الرئيسية\"."</string>
-    <string name="no_conversations_text" msgid="5354115541282395015">"ستظهر هنا المحادثات الحديثة."</string>
+    <string name="select_conversation_text" msgid="3376048251434956013">"انقر على محادثة لإضافتها إلى \"الشاشة الرئيسية\""</string>
+    <string name="no_conversations_text" msgid="5354115541282395015">"ستظهر هنا المحادثات الحديثة"</string>
     <string name="priority_conversations" msgid="3967482288896653039">"المحادثات ذات الأولوية"</string>
     <string name="recent_conversations" msgid="8531874684782574622">"المحادثات الحديثة"</string>
     <string name="days_timestamp" msgid="5821854736213214331">"قبل <xliff:g id="DURATION">%1$s</xliff:g> يوم"</string>
@@ -1153,7 +1160,7 @@
     <string name="person_available" msgid="2318599327472755472">"متاح"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"حدثت مشكلة أثناء قراءة مقياس مستوى شحن البطارية."</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"انقر للحصول على مزيد من المعلومات."</string>
-    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"لم يتم ضبط منبّه."</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"لم يتم ضبط منبّه"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"إدخال الرمز لفتح القفل"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"مستشعر بصمات الإصبع"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"المصادقة"</string>
@@ -1240,7 +1247,7 @@
     <string name="home_quick_affordance_unavailable_configure_the_app" msgid="604424593994493281">"• توفُّر جهاز واحد أو لوحة جهاز واحدة على الأقل"</string>
     <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"اختَر تطبيقًا تلقائيًا لتدوين الملاحظات لاستخدام اختصار تدوين الملاحظات."</string>
     <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"اختيار تطبيق"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"انقر مع الاستمرار على الاختصار."</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"انقر مع الاستمرار على الاختصار"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"إلغاء"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"تبديل الشاشتَين الآن"</string>
     <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"فتح الهاتف"</string>
diff --git a/packages/SystemUI/res/values-ar/tiles_states_strings.xml b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
index 364737d..307a26e 100644
--- a/packages/SystemUI/res/values-ar/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"الخيار غير مفعَّل"</item>
     <item msgid="5137565285664080143">"الخيار مفعَّل"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index b621ce88..5a083ab 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"স্ক্ৰীনশ্বট লোৱাটো আপোনাৰ আইটি প্ৰশাসকে অৱৰোধ কৰিছে"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"সম্পাদনা কৰক"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"স্ক্ৰীনশ্বট সম্পাদনা কৰক"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"শ্বেয়াৰ কৰক"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"স্ক্ৰীনশ্বট শ্বেয়াৰ কৰক"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"অধিক কেপচাৰ কৰক"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"স্ক্ৰীনশ্বট অগ্ৰাহ্য কৰক"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"চেহেৰা স্কেন কৰি থকা হৈছে"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"পঠিয়াওক"</string>
     <string name="cancel" msgid="1089011503403416730">"বাতিল কৰক"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"এপৰ ল’গ’"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"নিশ্চিত কৰক"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"আকৌ চেষ্টা কৰক"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ বাতিল কৰিবলৈ টিপক"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"মুখাৱয়ব চিনাক্ত কৰা হৈছে। অব্যাহত ৰাখিবলৈ আনলক কৰক চিহ্নটোত টিপক।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰা হ’ল"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"বিশ্বাসযোগ্যতা প্ৰমাণীকৰণ বাতিল কৰক"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"অধিক বিকল্প"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"পিন ব্যৱহাৰ কৰক"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"আৰ্হি ব্যৱহাৰ কৰক"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"পাছৱৰ্ড ব্যৱহাৰ কৰক"</string>
@@ -264,7 +265,7 @@
     <string name="quick_settings_dnd_label" msgid="7728690179108024338">"অসুবিধা নিদিব"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"ব্লুটুথ"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"কোনো যোৰা লগোৱা ডিভাইচ উপলব্ধ নহয়।"</string>
-    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"এটা ডিভাইচৰ সংযোগ কৰিবলৈ অথবা ডিভাইচটোৰ সৈতে সংযোগ বিচ্ছিন্ন কৰিবলৈ টিপক"</string>
+    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"ডিভাইচ সংযোগ কৰিবলৈ অথবা সংযোগ বিচ্ছিন্ন কৰিবলৈ টিপক"</string>
     <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"নতুন ডিভাইচ পেয়াৰ কৰক"</string>
     <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"আটাইবোৰ চাওক"</string>
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"ব্লুটুথ ব্যৱহাৰ কৰক"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"মানক"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"মধ্যমীয়া"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"উচ্চ"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"শুনাৰ ডিভাইচ"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ডিভাইচৰ মাইক্ৰ\'ফ\'ন অৱৰোধৰ পৰা আঁতৰাবনে?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ডিভাইচৰ কেমেৰা অৱৰোধৰ পৰা আঁতৰাবনে?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ডিভাইচৰ কেমেৰা আৰু মাইক্ৰ\'ফ\'ন অৱৰোধৰ পৰা আঁতৰাবনে?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"আঁতৰাওক"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ৱিজেট যোগ দিয়ক"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"কৰা হ’ল"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"ৱিজেট যোগ দিয়ক"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"আপোনাৰ টেবলেটটো আনলক নকৰাকৈ আপোনাৰ প্ৰিয় এপৰ ৱিজেটসমূহলৈ ক্ষিপ্ৰভাৱে এক্সেছ পাওক।"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"লক স্ক্ৰীনত যিকোনো ৱিজেটৰ অনুমতি দিবনে?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"ছেটিং খোলক"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"কাম সম্পৰ্কীয় এপ্ আনপজ কৰিবনে?"</string>
@@ -540,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"এই ডিভাইচটো আপোনাৰ অভিভাৱকে পৰিচালনা কৰে। আপোনাৰ অভিভাৱকে আপুনি ব্যৱহাৰ কৰা এপ্‌, আপোনাৰ অৱস্থান আৰু আপুনি ডিভাইচত অতিবাহিত কৰা সময়ৰ দৰে তথ্য চাব আৰু পৰিচালনা কৰিব পাৰে।"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"ভিপিএন"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgentএ আনলক কৰি ৰাখিছে"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"ডিভাইচ লক কৰা হৈছে, বিশ্বাসযোগ্যতা প্ৰমাণীকৰণৰ অতি বেছিসংখ্যক প্ৰয়াস"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"ডিভাইচ লক কৰা হৈছে\nবিশ্বাসযোগ্যতা প্ৰমাণীকৰণ কৰিব পৰা নগ’ল"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"ধ্বনিৰ ছেটিং"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"স্বয়ংক্ৰিয় কেপশ্বন মিডিয়া"</string>
@@ -765,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"বৰ্তমানৰ এপৰ জৰিয়তে বিভাজিত স্ক্ৰীনৰ সোঁফালৰ স্ক্ৰীনখনত সোমাওক"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"বৰ্তমানৰ এপৰ জৰিয়তে বিভাজিত স্ক্ৰীনৰ বাওঁফালৰ স্ক্ৰীনখনত সোমাওক"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"বিভাজিত স্ক্ৰীনৰ পৰা পূৰ্ণ স্ক্ৰীনলৈ সলনি কৰক"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰাৰ সময়ত সোঁফালে অথবা তলত থকা এপলৈ সলনি কৰক"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰাৰ সময়ত বাওঁফালে অথবা ওপৰত থকা এপলৈ সলনি কৰক"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"বিভাজিত স্ক্ৰীনৰ ব্যৱহাৰ কৰাৰ সময়ত: কোনো এপ্ এখন স্ক্ৰীনৰ পৰা আনখনলৈ নিয়ক"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ইনপুট"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"পৰৱৰ্তী ভাষাটোলৈ সলনি কৰক"</string>
@@ -901,7 +907,7 @@
     <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"ৱাই-ফাই অফ অৱস্থাত আছে"</string>
-    <string name="bt_is_off" msgid="7436344904889461591">"ব্লুটুথ অফ অৱস্থাত আছে"</string>
+    <string name="bt_is_off" msgid="7436344904889461591">"ব্লুটুথ অফ আছে"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"অসুবিধা নিদিব অফ অৱস্থাত আছে"</string>
     <string name="dnd_is_on" msgid="7009368176361546279">"অসুবিধা নিদিব অন অৱস্থাত আছে"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"অসুবিধা নিদিব-ক এটা স্বয়ংক্ৰিয় নিয়ম (<xliff:g id="ID_1">%s</xliff:g>)এ অন কৰিলে।"</string>
diff --git a/packages/SystemUI/res/values-as/tiles_states_strings.xml b/packages/SystemUI/res/values-as/tiles_states_strings.xml
index 767b34d..e978fe2 100644
--- a/packages/SystemUI/res/values-as/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-as/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"অফ আছে"</item>
     <item msgid="5137565285664080143">"অন আছে"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"উপলব্ধ নহয়"</item>
+    <item msgid="3079622119444911877">"অফ আছে"</item>
+    <item msgid="3028994095749238254">"অন আছে"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 0fbab20..7faec8a 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Skrinşot çəkilməsi İT admininiz tərəfindən bloklanıb"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Redaktə edin"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Skrinşota düzəliş edin"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Paylaşın"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Skrinşotu paylaşın"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Genişləndirin"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ekran şəklini ötürün"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Üzün skan edilməsi"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Göndərin"</string>
     <string name="cancel" msgid="1089011503403416730">"Ləğv edin"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Tətbiq loqosu"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Təsdiq"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Yenidən cəhd edin"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Doğrulanmanı ləğv etmək üçün toxunun"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Üz tanınıb. \"Kiliddən çıxar\" ikonasına basıb davam edin."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Doğrulandı"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"İdentifikasiyanı ləğv edin"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Digər seçimlər"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN istifadə edin"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Model istifadə edin"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Parol istifadə edin"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standart"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Orta"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Yüksək"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Cihaz mikrofonu blokdan çıxarılsın?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Cihaz kamerası blokdan çıxarılsın?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Cihaz kamerası və mikrofonu blokdan çıxarılsın?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Silin"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Vidcet əlavə edin"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Hazırdır"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Vidcetlər əlavə edin"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Planşeti kiliddən çıxarmadan sevimli tətbiq vidcetlərinizə sürətli giriş əldə edin."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Kilid ekranında istənilən vidcetə icazə verilsin?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Ayarları açın"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"İş tətbiqi üzrə pauza bitsin?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Bu cihaz valideyniniz tərəfindən idarə olunur. Valideyniniz işlətdiyiniz tətbiqlər, məkanınız və ekran vaxtınız kimi bilgiləri görə və idarə edə bilər."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN (Virtual Şəxsi Şəbəkələr)"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent ilə açıq saxlayın"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Cihaz kilidlənib, həddindən çox identifikasiya cəhdi"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Cihaz kilidləndi\nDoğrulama uğursuz oldu"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Səs ayarları"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Avtomatik başlıq mediası"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Cari tətbiq sağda olmaqla bölünmüş ekrana daxil olun"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Cari tətbiq solda olmaqla bölünmüş ekrana daxil olun"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Bölünmüş ekrandan tam ekrana keçin"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bölünmüş ekran istifadə edərkən sağda və ya aşağıda tətbiqə keçin"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bölünmüş ekran istifadə edərkən solda və ya yuxarıda tətbiqə keçin"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Bölünmüş ekran rejimində: tətbiqi birindən digərinə dəyişin"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Daxiletmə"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Növbəti dilə keçin"</string>
diff --git a/packages/SystemUI/res/values-az/tiles_states_strings.xml b/packages/SystemUI/res/values-az/tiles_states_strings.xml
index 3457a71..f390369 100644
--- a/packages/SystemUI/res/values-az/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-az/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Deaktiv"</item>
     <item msgid="5137565285664080143">"Aktiv"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 18d010c..cd5dc26 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"IT administrator blokira pravljenje snimaka ekrana"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Izmeni"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Izmenite snimak ekrana"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Delite"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Delite snimak ekrana"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Snimite još"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Odbacite snimak ekrana"</string>
@@ -106,8 +105,8 @@
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrađujemo video snimka ekrana"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Obaveštenje o sesiji snimanja ekrana je aktivno"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Želite da započnete snimanje?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Android ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju dok snimate. Zato budite pažljivi sa lozinkama, informacijama o plaćanju, porukama, slikama i audio i videima."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Kada snimate aplikaciju, Android ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Zato budite pažljivi sa lozinkama, informacijama o plaćanju, porukama, slikama i audio i videima."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Android ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju dok snimate. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, i audio i video sadržaj."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Kada snimate aplikaciju, Android ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, i audio i video sadržaj."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Započni snimanje"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Snimaj zvuk"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Zvuk uređaja"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string>
     <string name="cancel" msgid="1089011503403416730">"Otkaži"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logotip aplikacije"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdi"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Probaj ponovo"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Dodirnite da biste otkazali potvrdu identiteta"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu otključavanja za nastavak."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Identitet je potvrđen"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Otkažite potvrdu identiteta"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Još opcija"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristite PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristite šablon"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Koristite lozinku"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standardno"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Srednje"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Visoko"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Slušni aparati"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite da odblokirate mikrofon uređaja?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite da odblokirate kameru uređaja?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite da odblokirate kameru i mikrofon uređaja?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Ukloni"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodaj vidžet"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Gotovo"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Dodaj vidžete"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Brzo pristupajte omiljenim vidžetima za aplikacije bez otključavanja tableta."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Želite da dozvolite sve vidžete na zaključanom ekranu?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Otvori podešavanja"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Uključiti poslovne aplikacije?"</string>
@@ -466,17 +476,17 @@
     <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Jedna aplikacija"</string>
     <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Delite ili snimite aplikaciju"</string>
     <string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Želite da počnete snimanje ili prebacivanje pomoću aplikacije <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
-    <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kada delite, snimate ili prebacujete, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju. Zato budite pažljivi sa lozinkama, informacijama o plaćanju, porukama, slikama i audio i videima."</string>
-    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Kada delite, snimate ili prebacujete aplikaciju, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Zato budite pažljivi sa lozinkama, informacijama o plaćanju, porukama, slikama i audio i videima."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kada delite, snimate ili prebacujete, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, i audio i video sadržaj."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Kada delite, snimate ili prebacujete aplikaciju, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, i audio i video sadržaj."</string>
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Pokreni"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućila ovu opciju"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Želite da započnete prebacivanje?"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Kada prebacujete, Android ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju. Zato budite pažljivi sa lozinkama, informacijama o plaćanju, porukama, slikama i audio i videima."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Kada prebacujete aplikaciju, Android ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Zato budite pažljivi sa lozinkama, informacijama o plaćanju, porukama, slikama i audio i videima."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Kada prebacujete, Android ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, i audio i video sadržaj."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Kada prebacujete aplikaciju, Android ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, i audio i video sadržaj."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Započni prebacivanje"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Želite da počnete da delite?"</string>
-    <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Kada delite, snimate ili prebacujete, Android ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju. Zato budite pažljivi sa lozinkama, informacijama o plaćanju, porukama, slikama i audio i videima."</string>
-    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Kada delite, snimate ili prebacujete aplikaciju, Android ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Zato budite pažljivi sa lozinkama, informacijama o plaćanju, porukama, slikama i audio i videima."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Kada delite, snimate ili prebacujete, Android ima pristup kompletnom sadržaju koji je vidljiv na ekranu ili se pušta na uređaju. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, i audio i video sadržaj."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Kada delite, snimate ili prebacujete aplikaciju, Android ima pristup kompletnom sadržaju koji je vidljiv ili se pušta u toj aplikaciji. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, i audio i video sadržaj."</string>
     <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Pokreni"</string>
     <string name="media_projection_task_switcher_text" msgid="590885489897412359">"Deljenje se zaustavlja kada menjate aplikacije"</string>
     <string name="media_projection_task_switcher_action_switch" msgid="8682258717291921123">"Deli ovu aplikaciju"</string>
@@ -593,7 +603,7 @@
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Dodirnite da biste isključili zvuk. Zvuk usluga pristupačnosti će možda biti isključen."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Dodirnite da biste podesili na vibraciju."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Dodirnite da biste isključili zvuk."</string>
-    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kontrola šuma"</string>
+    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kontrola buke"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Prostorni zvuk"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Isključeno"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fiksno"</string>
@@ -763,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Pokreni podeljeni ekran za aktuelnu aplikaciju na desnoj strani"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Pokreni podeljeni ekran za aktuelnu aplikaciju na levoj strani"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Pređi sa podeljenog ekrana na ceo ekran"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Pređite u aplikaciju zdesna ili ispod dok koristite podeljeni ekran"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pređite u aplikaciju sleva ili iznad dok koristite podeljeni ekran"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"U režimu podeljenog ekrana: zamena jedne aplikacije drugom"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Unos"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Pređi na sledeći jezik"</string>
@@ -1152,7 +1160,7 @@
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Problem sa očitavanjem merača baterije"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Dodirnite za više informacija"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Nije podešen"</string>
-    <string name="accessibility_bouncer" msgid="5896923685673320070">"unesite zaključavanje ekrana"</string>
+    <string name="accessibility_bouncer" msgid="5896923685673320070">"unesite otključavanje ekrana"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Senzor za otisak prsta"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"potvrdite identitet"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"unesite uređaj"</string>
@@ -1174,7 +1182,7 @@
     <string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"Traže se mreže…"</string>
     <string name="wifi_failed_connect_message" msgid="4161863112079000071">"Povezivanje sa mrežom nije uspelo"</string>
     <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"WiFi trenutno ne može da se automatski poveže"</string>
-    <string name="see_all_networks" msgid="3773666844913168122">"Pogledajte sve"</string>
+    <string name="see_all_networks" msgid="3773666844913168122">"Prikaži sve"</string>
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Da biste promenili mrežu, prekinite eternet vezu"</string>
     <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Radi boljeg doživljaja uređaja, aplikacije i usluge i dalje mogu da traže WiFi mreže u bilo kom trenutku, čak i kada je WiFi isključen. To možete da promenite u podešavanjima WiFi skeniranja. "<annotation id="link">"Promenite"</annotation></string>
     <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Isključi režim rada u avionu"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
index 75fb325..df0b786 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"Isključeno"</item>
     <item msgid="5137565285664080143">"Uključeno"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"Nedostupno"</item>
+    <item msgid="3079622119444911877">"Isključeno"</item>
+    <item msgid="3028994095749238254">"Uključeno"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 217a6fe..a76c38b 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Стварэнне здымкаў экрана заблакіравана IT-адміністратарам"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Змяніць"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Змяніць здымак экрана"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Абагуліць"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Абагуліць здымак экрана"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Захапіць больш"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Адхіліць здымак экрана"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканіраванне твару"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Адправіць"</string>
     <string name="cancel" msgid="1089011503403416730">"Скасаваць"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Лагатып праграмы"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Пацвердзіць"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Паўтарыць спробу"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Націсніце, каб скасаваць аўтэнтыфікацыю"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Твар распазнаны. Для працягу націсніце значок разблакіроўкі."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Распазнана"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Скасаваць аўтэнтыфікацыю"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Іншыя варыянты"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Увесці PIN-код"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Выкарыстаць узор разблакіроўкі"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Выкарыстаць пароль"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Стандартная"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Сярэдняя"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Высокая"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Разблакіраваць мікрафон прылады?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Разблакіраваць камеру прылады?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Разблакіраваць камеру і мікрафон прылады?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Выдаліць"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Дадаць віджэт"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Гатова"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Дадаць віджэты"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Доступ да віджэтаў любімых праграм без разблакіроўкі планшэта."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Дазволіць размяшчаць на экране блакіроўкі любыя віджэты?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Адкрыць налады"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Уключыць працоўныя праграмы?"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Перайсці ў рэжым падзеленага экрана з бягучай праграмай справа"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Перайсці ў рэжым падзеленага экрана з бягучай праграмай злева"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Пераключыцца з рэжыму падзеленага экрана на поўнаэкранны рэжым"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Пераключыцца на праграму справа або ўнізе на падзеленым экране"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Пераключыцца на праграму злева або ўверсе на падзеленым экране"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"У рэжыме падзеленага экрана замяніць адну праграму на іншую"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Увод"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Пераключыцца на наступную мову"</string>
diff --git a/packages/SystemUI/res/values-be/tiles_states_strings.xml b/packages/SystemUI/res/values-be/tiles_states_strings.xml
index 74fc7c6..32619ef 100644
--- a/packages/SystemUI/res/values-be/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-be/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Выключана"</item>
     <item msgid="5137565285664080143">"Уключана"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 62c95b2..f8793b3 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Правенето на екранни снимки е блокирано от системния ви администратор"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Редактиране"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Редактиране на екранната снимка"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Споделяне"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Споделяне на екранната снимка"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Заснемане на още"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Отхвърляне на екранната снимка"</string>
@@ -110,10 +109,10 @@
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Докато записвате дадено приложение, Android има достъп до всичко, което се показва или възпроизвежда в него. Затова бъдете внимателни с неща като пароли, подробности за начини на плащане, съобщения, снимки, аудио и видео."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Стартиране на записването"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Записване на звук"</string>
-    <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Аудио от устройството"</string>
+    <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Звук от устройството"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Звук от устройството ви, като например музика, обаждания и мелодии"</string>
     <string name="screenrecord_mic_label" msgid="2111264835791332350">"Микрофон"</string>
-    <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Аудио от устройството и микрофона"</string>
+    <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Звук от устройството и микрофона"</string>
     <string name="screenrecord_continue" msgid="4055347133700593164">"Стартиране"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Екранът се записва"</string>
     <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Екранът и аудиото се записват"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Извършва се сканиране на лице"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Изпращане"</string>
     <string name="cancel" msgid="1089011503403416730">"Отказ"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Лого на приложението"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Потвърждаване"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Нов опит"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Докоснете, за да анулирате удостоверяването"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицето бе разпознато. Продължете чрез иконата за отключване."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Удостоверено"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Анулиране на удостоверяването"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Още опции"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Използване на ПИН"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Използване на фигура"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Използване на парола"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Стандартен"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Среден"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Висок"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Да се отблокира ли микрофонът на устройството?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Да се отблокира ли камерата на устройството?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Да се отблокират ли камерата и микрофонът на устройството?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Премахване"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Добавяне на приспособление"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Готово"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Добавяне на приспособления"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Получете бърз достъп до любимите си приспособления за приложения, без да отключвате таблета си."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Да се разреши ли което и да е приспособление на заключения екран?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Отваряне на настройките"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Отмяна на паузата за служ. прил.?"</string>
@@ -587,7 +598,7 @@
     <string name="media_device_cast" msgid="4786241789687569892">"Предаване"</string>
     <string name="stream_notification_unavailable" msgid="4313854556205836435">"Не е налице, защото звъненето е спряно"</string>
     <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Не е налице, защото режимът „Не безпокойте“ е вкл."</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"Не е налице, защото режимът „Не безпокойте“ е вкл."</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"Не е налице, защото „Не безпокойте“ е вкл."</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Докоснете, за да включите отново звука."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Докоснете, за да зададете вибриране. Възможно е звукът на услугите за достъпност да бъде заглушен."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Докоснете, за да заглушите звука. Възможно е звукът на услугите за достъпност да бъде заглушен."</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Преминаване към разделен екран с текущото приложение отдясно"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Преминаване към разделен екран с текущото приложение отляво"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Превключване от разделен към цял екран"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Превключване към приложението вдясно/отдолу в режима на разделен екран"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Превключване към приложението вляво/отгоре в режима на разделен екран"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"При разделен екран: замяна на дадено приложение с друго"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Въвеждане"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Превключване към следващия език"</string>
diff --git a/packages/SystemUI/res/values-bg/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
index ddd0c3f..381b0f0 100644
--- a/packages/SystemUI/res/values-bg/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Изключено"</item>
     <item msgid="5137565285664080143">"Включено"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index abfbfcc..f6de0e3 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"আপনার আইটি অ্যাডমিন স্ক্রিনশট নেওয়ার সুবিধা ব্লক করেছেন"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"এডিট করুন"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"স্ক্রিনশট এডিট করুন"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"শেয়ার করুন"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"স্ক্রিনশট শেয়ার করুন"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"আরও বেশি ক্যাপচার করুন"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"স্ক্রিনশট বাতিল করুন"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ফেস স্ক্যান করা হচ্ছে"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"পাঠান"</string>
     <string name="cancel" msgid="1089011503403416730">"বাতিল করুন"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"অ্যাপের লোগো"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"কনফার্ম করুন"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"আবার চেষ্টা করুন"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"যাচাইকরণ বাতিল করতে ট্যাপ করুন"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ফেস শনাক্ত করা হয়েছে। চালিয়ে যেতে আনলক আইকন প্রেস করুন।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"প্রমাণীকৃত"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"যাচাইকরণ বাতিল করুন"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"আরও বিকল্প"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"পিন ব্যবহার করুন"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"প্যাটার্ন ব্যবহার করুন"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"পাসওয়ার্ড ব্যবহার করুন"</string>
@@ -362,11 +363,19 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"স্ট্যান্ডার্ড"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"মিডিয়াম"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"হাই"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ডিভাইসের মাইক্রোফোন আনব্লক করতে চান?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ডিভাইসের ক্যামেরা আনব্লক করতে চান?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ডিভাইসের ক্যামেরা এবং মাইক্রোফোন আনব্লক করতে চান?"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"এটার জন্য মাইক্রোফোনের অ্যাক্সেস সেই সব অ্যাপ এবং পরিষেবার জন্য আনব্লক হয়ে যাবে, যাতে আপনার মাইক্রোফোন ব্যবহার করার অনুমতি দেওয়া হয়েছে।"</string>
-    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"এটার জন্য ক্যামেরার অ্যাক্সেস সেই সব অ্যাপ এবং পরিষেবার জন্য আনব্লক হয়ে যাবে, যাতে আপনার ক্যামেরা ব্যবহারের অনুমতি দেওয়া হয়েছে।"</string>
+    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"এর ফলে মাইক্রোফোনের অ্যাক্সেস সেই সব অ্যাপ এবং পরিষেবার জন্য আনব্লক হয়ে যাবে, যাতে আপনার মাইক্রোফোন ব্যবহার করার অনুমতি দেওয়া আছে।"</string>
+    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"এর ফলে ক্যামেরার অ্যাক্সেস সেই সব অ্যাপ এবং পরিষেবার জন্য আনব্লক হয়ে যাবে, যাতে আপনার ক্যামেরা ব্যবহারের অনুমতি দেওয়া আছে।"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"এটার জন্য ক্যামেরা অথবা মাইক্রোফোনের অ্যাক্সেস সেই সব অ্যাপ এবং পরিষেবার জন্য আনব্লক হয়ে যাবে, যাতে আপনার ক্যামেরা অথবা মাইক্রোফোন ব্যবহারের অনুমতি দেওয়া হয়েছে।"</string>
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"মাইক্রোফোন ব্লক করা আছে"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"ক্যামেরা ব্লক করা আছে"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"সরান"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"উইজেট যোগ করুন"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"হয়ে গেছে"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"উইজেট যোগ করুন"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"নিজের ট্যাবলেট আনলক বা করেই আপনার প্রিয় অ্যাপ উইজেটে দ্রুত অ্যাক্সেস পান।"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"লক স্ক্রিনে যেকোনও উইজেটকে অনুমতি দেবেন?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"সেটিংস খুলুন"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"অফিসের অ্যাপ আনপজ করতে চান?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"আপনার অভিভাবক এই ডিভাইস ম্যানেজ করেন। আপনার অভিভাবক আপনার ব্যবহার করা অ্যাপ, লোকেশন ও স্ক্রিন টাইমের মতো তথ্যগুলি দেখতে এবং ম্যানেজ করতে পারেন।"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent দিয়ে আনলক করে রাখা হয়েছে"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"ডিভাইস লক করা আছে, যাচাইকরণের জন্য অনেক বেশিবার চেষ্টা করা হয়েছে"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"ডিভাইস লক করা আছে\nযাচাইকরণ করা যায়নি"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"সাউন্ড সেটিংস"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"অটোমেটিক মিডিয়া ক্যাপশন দেখুন"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"ডানদিকে থাকা বর্তমান অ্যাপ ব্যবহার করে \'স্প্লিট স্ক্রিন\' যোগ করুন"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"বাঁদিকে থাকা বর্তমান অ্যাপ ব্যবহার করে \'স্প্লিট স্ক্রিন\' যোগ করুন"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"\'স্প্লিট স্ক্রিন\' থেকে ফুল স্ক্রিনে পাল্টান"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"স্প্লিট স্ক্রিন ব্যবহার করার সময় ডানদিকের বা নিচের অ্যাপে পাল্টে নিন"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"স্প্লিট স্ক্রিন ব্যবহার করার সময় বাঁদিকের বা উপরের অ্যাপে পাল্টে নিন"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"\'স্প্লিট স্ক্রিন\' থাকাকালীন: একটি অ্যাপ থেকে অন্যটিতে পাল্টান"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ইনপুট"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"পরবর্তী ভাষায় পাল্টান"</string>
diff --git a/packages/SystemUI/res/values-bn/tiles_states_strings.xml b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
index ad32560..2eebd97 100644
--- a/packages/SystemUI/res/values-bn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"বন্ধ আছে"</item>
     <item msgid="5137565285664080143">"চালু আছে"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 75a2f94..9347757 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Snimanje ekrana je blokirao IT administrator"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Uredite"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Uredite snimak ekrana"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Dijeli"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Dijeljenje snimka ekrana"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Snimi više"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Odbacite snimak ekrana"</string>
@@ -109,9 +108,9 @@
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Dok snimate, Android ima pristup svemu što je vidljivo na ekranu ili što se reproducira na uređaju. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Dok snimate aplikaciju, Android ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, zvukovi i videozapisi."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Pokreni snimanje"</string>
-    <string name="screenrecord_audio_label" msgid="6183558856175159629">"Snimi zvučni zapis"</string>
+    <string name="screenrecord_audio_label" msgid="6183558856175159629">"Snimanje zvuka"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Zvuk na uređaju"</string>
-    <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Zvuk s vašeg uređaja, naprimjer muzika, pozivi i melodije zvona"</string>
+    <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Zvuk s vašeg uređaja, npr. muzika, pozivi i melodije zvona"</string>
     <string name="screenrecord_mic_label" msgid="2111264835791332350">"Mikrofon"</string>
     <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Zvuk na uređaju i mikrofon"</string>
     <string name="screenrecord_continue" msgid="4055347133700593164">"Pokreni"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string>
     <string name="cancel" msgid="1089011503403416730">"Otkaži"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logotip aplikacije"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdite"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Pokušaj ponovo"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Dodirnite da otkažete autentifikaciju"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice prepoznato. Pritisnite ikonu za otklj. da nastavite."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificirano"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Otkažite autentifikaciju"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Više opcija"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristi PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristi uzorak"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Koristi lozinku"</string>
@@ -264,7 +265,7 @@
     <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne ometaj"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nema dostupnih uparenih uređaja"</string>
-    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Dodirnite da povežete uređaj ili prekinete njegovu povezanost"</string>
+    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Dodirnite da povežete ili prekinete povezanost uređaja"</string>
     <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Upari novi uređaj"</string>
     <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Prikaži sve"</string>
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Koristi Bluetooth"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standardno"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Srednje"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Visoko"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblokirati mikrofon uređaja?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblokirati kameru uređaja?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Deblokirati kameru i mikrofon uređaja?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Uklanjanje"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodajte vidžet"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Gotovo"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Dodaj widgete"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Brzo pristupajte widgetima omiljenih aplikacija bez otključavanja tableta."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Dozvoliti bilo koji vidžet na zaključanom ekranu?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Otvori postavke"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Pokrenuti poslovne aplikacije?"</string>
@@ -540,7 +551,7 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Ovim uređajem upravlja tvoj roditelj. Roditelj može vidjeti i upravljati informacijama kao što su aplikacije koje koristiš, lokacija i vrijeme korištenja uređaja."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Pouzdani agent sprečava zaključavanje"</string>
-    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Uređaj je bio zaključan zbog previše pokušaja autentifikacije"</string>
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Uređaj je zaključan zbog previše pokušaja autentifikacije"</string>
     <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Uređaj je zaključan\nAutentifikacija nije uspjela"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Postavke zvuka"</string>
@@ -610,7 +621,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"isključivanje parametra %s"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"uključivanje parametra %s"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"Reproduciranje: <xliff:g id="LABEL">%s</xliff:g>"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Zvuk će se reprod. na:"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Reprodukcija zvuka na"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"Podešavač za korisnički interfejs sistema"</string>
     <string name="status_bar" msgid="4357390266055077437">"Statusna traka"</string>
     <string name="demo_mode" msgid="263484519766901593">"Demo način rada Sistemskog UI-ja"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Otvaranje podijeljenog ekrana s trenutnom aplikacijom na desnoj strani"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Otvaranje podijeljenog ekrana s trenutnom aplikacijom na lijevoj strani"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Prebacivanje s podijeljenog ekrana na prikaz preko cijelog ekrana"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Pređite u aplikaciju desno ili ispod dok koristite podijeljeni ekran"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pređite u aplikaciju lijevo ili iznad dok koristite podijeljeni ekran"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Za vrijeme podijeljenog ekrana: zamjena jedne aplikacije drugom"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Unos"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Prebacivanje na sljedeći jezik"</string>
diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
index 75fb325..e09cab5 100644
--- a/packages/SystemUI/res/values-bs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Isključeno"</item>
     <item msgid="5137565285664080143">"Uključeno"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index d31fb06..40532ca 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"El teu administrador de TI ha bloquejat les captures de pantalla"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Edita"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Edita la captura de pantalla"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Comparteix"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Comparteix la captura de pantalla"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Captura més"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ignora la captura de pantalla"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"S\'està escanejant la cara"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envia"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancel·la"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logotip de l\'aplicació"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirma"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Torna-ho a provar"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Toca per cancel·lar l\'autenticació"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"S\'ha reconegut la cara. Prem la icona per continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticat"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel·la l\'autenticació"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Més opcions"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utilitza el PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utilitza el patró"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Utilitza la contrasenya"</string>
@@ -362,12 +363,20 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Estàndard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Mitjà"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Alt"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vols desbloquejar el micròfon del dispositiu?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vols desbloquejar la càmera del dispositiu?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vols desbloquejar la càmera i el micròfon del dispositiu?"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Aquesta opció desbloqueja l\'accés de tots els serveis i aplicacions que tenen permís per utilitzar el micròfon."</string>
-    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Aquesta opció desbloqueja l\'accés de tots els serveis i aplicacions que tenen permís per utilitzar la càmera."</string>
-    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Aquesta opció desbloqueja l\'accés de tots els serveis i aplicacions que tenen permís per utilitzar la càmera o el micròfon."</string>
+    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Si ho fas, tots els serveis i les aplicacions que tenen permís podran utilitzar el micròfon."</string>
+    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Si ho fas, tots els serveis i les aplicacions que tenen permís podran utilitzar la càmera."</string>
+    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Si ho fas, tots els serveis i les aplicacions que tenen permís podran utilitzar la càmera o el micròfon."</string>
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"El micròfon està bloquejat"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"La càmera està bloquejada"</string>
     <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"El micròfon i la càmera estan bloquejats"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Suprimeix"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Afegeix un widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Fet"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Afegeix widgets"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Accedeix ràpidament als teus widgets d\'aplicacions preferits sense desbloquejar la tauleta."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Vols permetre qualsevol widget a la pantalla de bloqueig?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Obre la configuració"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Reactivar les apps de treball?"</string>
@@ -467,7 +478,7 @@
     <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Comparteix o grava una aplicació"</string>
     <string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Vols començar a gravar o emetre contingut amb <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Quan comparteixes, graves o emets contingut, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> té accés a qualsevol cosa que es vegi a la pantalla o que es reprodueixi al dispositiu. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos i l\'àudio i el vídeo."</string>
-    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Quan comparteixes, graves o emets contingut, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> té accés a qualsevol cosa que es vegi a la pantalla o que es reprodueixi a l\'aplicació. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos i l\'àudio i el vídeo."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Quan comparteixes, graves o emets una aplicació, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> té accés a qualsevol cosa que es mostri o que es reprodueixi en aquella aplicació. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos i l\'àudio i el vídeo."</string>
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Inicia"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ha desactivat aquesta opció"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Vols iniciar una emissió?"</string>
@@ -476,7 +487,7 @@
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Inicia una emissió"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Vols començar a compartir?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Quan comparteixes, graves o emets contingut, Android té accés a qualsevol cosa que es vegi a la pantalla o que es reprodueixi al dispositiu. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos i l\'àudio i el vídeo."</string>
-    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Quan comparteixes, graves o emets contingut, Android té accés a qualsevol cosa que es vegi a la pantalla o que es reprodueixi a l\'aplicació. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos i l\'àudio i el vídeo."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Quan comparteixes, graves o emets una aplicació, Android té accés a qualsevol cosa que es mostri o que es reprodueixi en aquella aplicació. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos i l\'àudio i el vídeo."</string>
     <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Inicia"</string>
     <string name="media_projection_task_switcher_text" msgid="590885489897412359">"La compartició es posa en pausa quan canvies d\'aplicació"</string>
     <string name="media_projection_task_switcher_action_switch" msgid="8682258717291921123">"Comparteix aquesta aplicació"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"El teu pare o mare gestionen aquest dispositiu, i poden veure i gestionar informació com ara les aplicacions que utilitzes, la teva ubicació i el teu temps de connexió."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Desbloquejat per TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"El dispositiu s\'ha bloquejat; massa intents d\'autenticació"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"El dispositiu s\'ha bloquejat\nHa fallat l\'autenticació"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Configuració del so"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Subtitula el contingut multimèdia automàticament"</string>
@@ -576,7 +585,7 @@
     <string name="screen_pinning_exit" msgid="4553787518387346893">"S\'ha deixat de fixar l\'aplicació"</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"Trucada"</string>
     <string name="stream_system" msgid="7663148785370565134">"Sistema"</string>
-    <string name="stream_ring" msgid="7550670036738697526">"To de trucada"</string>
+    <string name="stream_ring" msgid="7550670036738697526">"So"</string>
     <string name="stream_music" msgid="2188224742361847580">"Multimèdia"</string>
     <string name="stream_alarm" msgid="16058075093011694">"Alarma"</string>
     <string name="stream_notification" msgid="7930294049046243939">"Notificació"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Entra al mode de pantalla dividida amb l\'aplicació actual a la dreta"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Entra al mode de pantalla dividida amb l\'aplicació actual a l\'esquerra"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Canvia de pantalla dividida a pantalla completa"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Canvia a l\'aplicació de la dreta o de sota amb la pantalla dividida"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Canvia a l\'aplicació de l\'esquerra o de dalt amb la pantalla dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Durant el mode de pantalla dividida: substitueix una app per una altra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Canvia a l\'idioma següent"</string>
diff --git a/packages/SystemUI/res/values-ca/tiles_states_strings.xml b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
index c926e9e..6a36b6f 100644
--- a/packages/SystemUI/res/values-ca/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Desactivat"</item>
     <item msgid="5137565285664080143">"Activat"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 995d994..16c2914 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Pořizování snímků obrazovky je blokováno administrátorem IT"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Upravit"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Upravit snímek obrazovky"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Sdílet"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Sdílet snímek obrazovky"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Zvětšit záběr snímku"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Zavřít snímek obrazovky"</string>
@@ -107,7 +106,7 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Trvalé oznámení o relaci nahrávání"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Začít nahrávat?"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Během nahrávání má Android přístup k veškerému obsahu, který je viditelný na obrazovce nebo se přehrává v zařízení. Buďte proto opatrní s věcmi, jako jsou hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Během nahrávání aplikace má Android přístup k veškerému obsahu, který je v dané aplikaci zobrazen nebo přehráván. Buďte proto opatrní s věcmi, jako jsou hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Během nahrávání aplikace má Android přístup k veškerému obsahu, který je v dané aplikaci zobrazen nebo přehráván. Buďte proto opatrní s informacemi, jako jsou hesla, platební údaje, zprávy, fotky, zvukové záznamy nebo videa."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Začít nahrávat"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Nahrávat zvuk"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Zvuk zařízení"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skenování obličeje"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Odeslat"</string>
     <string name="cancel" msgid="1089011503403416730">"Zrušit"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logo aplikace"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdit"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Zkusit znovu"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Klepnutím zrušíte ověření"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Obličej rozpoznán. Klepněte na ikonu odemknutí."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ověřeno"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Zrušit ověření"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Další možnosti"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Použít kód PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Použít gesto"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Použít heslo"</string>
@@ -264,7 +265,7 @@
     <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Nerušit"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nejsou dostupná žádná spárovaná zařízení"</string>
-    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Klepnutím připojíte nebo odpojíte zařízení"</string>
+    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Klepnutím zařízení připojíte nebo odpojíte"</string>
     <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Spárovat nové zařízení"</string>
     <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Zobrazit vše"</string>
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Použít Bluetooth"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standardní"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Střední"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Vysoká"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokovat mikrofon zařízení?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokovat fotoaparát zařízení?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Odblokovat fotoaparát a mikrofon zařízení?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Odstranit"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Přidat widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Hotovo"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Přidat widgety"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Získejte rychlý přístup ke svým oblíbeným widgetům aplikací bez odemykání tabletu."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Povolit jakýkoli widget na obrazovce uzamčení?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Otevřít nastavení"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Zrušit pozastavení pracovních aplikací?"</string>
@@ -472,11 +483,11 @@
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> tuto možnost zakázala"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Začít odesílat?"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Během odesílání má Android přístup ke všemu, co je viditelné na obrazovce nebo se přehrává v zařízení. Buďte proto opatrní s věcmi, jako jsou hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Během odesílání aplikace má Android přístup k veškerému obsahu, který je v dané aplikaci zobrazen nebo přehráván. Buďte proto opatrní s věcmi, jako jsou hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Během odesílání aplikace má Android přístup k veškerému obsahu, který je v dané aplikaci zobrazen nebo přehráván. Buďte proto opatrní s informacemi, jako jsou hesla, platební údaje, zprávy, fotky, zvukové záznamy a videa."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Začít odesílat"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Začít sdílet?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Během sdílení, nahrávání nebo odesílání má Android přístup k veškerému obsahu, který je viditelný na obrazovce nebo se přehrává v zařízení. Buďte proto opatrní s věcmi, jako jsou hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
-    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Během sdílení, nahrávání nebo odesílání aplikace má Android přístup k veškerému obsahu, který je v dané aplikaci zobrazen nebo přehráván. Buďte proto opatrní s věcmi, jako jsou hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Během sdílení, nahrávání nebo odesílání aplikace má Android přístup k veškerému obsahu, který je v dané aplikaci zobrazen nebo přehráván. Buďte proto opatrní s informacemi, jako jsou hesla, platební údaje, zprávy, fotky, zvukové záznamy a videa."</string>
     <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Začít"</string>
     <string name="media_projection_task_switcher_text" msgid="590885489897412359">"Když přepnete aplikace, sdílení se pozastaví"</string>
     <string name="media_projection_task_switcher_action_switch" msgid="8682258717291921123">"Sdílet aplikaci"</string>
@@ -587,7 +598,7 @@
     <string name="media_device_cast" msgid="4786241789687569892">"Odesílání"</string>
     <string name="stream_notification_unavailable" msgid="4313854556205836435">"Nedostupné, protože vyzvánění je ztlumené"</string>
     <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Nedostupné, protože je zapnutý režim Nerušit"</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"Nedostupné, protože je zapnutý režim Nerušit"</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"Nedostupné – je zapnutý režim Nerušit"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Klepnutím zapnete zvuk."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Klepnutím aktivujete režim vibrací. Služby přístupnosti mohou být ztlumeny."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Klepnutím vypnete zvuk. Služby přístupnosti mohou být ztlumeny."</string>
@@ -596,7 +607,7 @@
     <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Omezení hluku"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Prostorový zvuk"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Vypnuto"</string>
-    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Pevné"</string>
+    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Pevný"</string>
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Sledování hlavy"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Klepnutím změníte režim vyzvánění"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"vypnout zvuk"</string>
@@ -610,7 +621,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"ztlumíte %s"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"zapnete zvuk %s"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"Přehrávání <xliff:g id="LABEL">%s</xliff:g> na"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Zvuk se přehraje na"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Zvuk se přehraje přes"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"Nástroj na ladění uživatelského rozhraní systému"</string>
     <string name="status_bar" msgid="4357390266055077437">"Stavový řádek"</string>
     <string name="demo_mode" msgid="263484519766901593">"Ukázkový režim uživatelského rozhraní systému"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Přepnout na rozdělenou obrazovku s aktuálními aplikacemi napravo"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Přepnout na rozdělenou obrazovku s aktuálními aplikacemi nalevo"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Přepnout z rozdělené obrazovky na celou obrazovku"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Přechod na aplikaci vpravo nebo dole v režimu rozdělené obrazovky"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Přechod na aplikaci vlevo nebo nahoře v režimu rozdělené obrazovky"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"V režimu rozdělené obrazovky: nahradit jednu aplikaci druhou"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vstup"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Přepnout na další jazyk"</string>
@@ -1164,7 +1173,7 @@
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Připojeno"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Dočasně připojeno"</string>
     <string name="mobile_data_poor_connection" msgid="819617772268371434">"Nekvalitní připojení"</string>
-    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Mobilní data se nebudou připojovat automaticky"</string>
+    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Bez automatického připojení přes mobilní data"</string>
     <string name="mobile_data_no_connection" msgid="1713872434869947377">"Žádné připojení"</string>
     <string name="non_carrier_network_unavailable" msgid="770049357024492372">"Žádné další sítě nejsou k dispozici"</string>
     <string name="all_network_unavailable" msgid="4112774339909373349">"Nejsou k dispozici žádné sítě"</string>
diff --git a/packages/SystemUI/res/values-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
index 5345569..02a0f5f 100644
--- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Vypnuto"</item>
     <item msgid="5137565285664080143">"Zapnuto"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 32f8336..4754dbb 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Din it-administrator har blokeret screenshot-funktionen"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Rediger"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Rediger screenshot"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Del"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Del screenshottet"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Medtag mere"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Luk screenshot"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanner ansigt"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
     <string name="cancel" msgid="1089011503403416730">"Annuller"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Applogo"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bekræft"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Prøv igen"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Tryk for at annullere godkendelsen"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansigt genkendt. Tryk på oplåsningsikonet for at fortsætte."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Godkendt"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annuller godkendelsen"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Flere valgmuligheder"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Brug pinkode"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Brug mønster"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Brug adgangskode"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Middel"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Høj"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vil du fjerne blokeringen af enhedens mikrofon?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vil du fjerne blokeringen af enhedens kamera?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vil du fjerne blokeringen af enhedens kamera og mikrofon?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Fjern"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Tilføj widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Udfør"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Tilføj widgets"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Få hurtig adgang til dine foretrukne appwidgets uden at låse din tablet op."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Vil du tillade alle widgets på låseskærmen?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Åbn Indstillinger"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Vil du genoptage arbejdsapps?"</string>
@@ -574,14 +585,14 @@
     <string name="screen_pinning_exit" msgid="4553787518387346893">"Appen er frigjort"</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"Ring op"</string>
     <string name="stream_system" msgid="7663148785370565134">"System"</string>
-    <string name="stream_ring" msgid="7550670036738697526">"Ring"</string>
+    <string name="stream_ring" msgid="7550670036738697526">"Ringetone"</string>
     <string name="stream_music" msgid="2188224742361847580">"Medie"</string>
     <string name="stream_alarm" msgid="16058075093011694">"Alarm"</string>
     <string name="stream_notification" msgid="7930294049046243939">"Notifikation"</string>
     <string name="stream_bluetooth_sco" msgid="6234562365528664331">"Bluetooth"</string>
     <string name="stream_dtmf" msgid="7322536356554673067">"Tonesignalfrekvens (DTMF)"</string>
     <string name="stream_accessibility" msgid="3873610336741987152">"Hjælpefunktioner"</string>
-    <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ring"</string>
+    <string name="volume_ringer_status_normal" msgid="1339039682222461143">"Ringetone"</string>
     <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibration"</string>
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Slå lyden fra"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"Cast"</string>
@@ -597,7 +608,7 @@
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Rumlig lyd"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Fra"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fast"</string>
-    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Reg. af hovedbevægelser"</string>
+    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Register. af hoved­bevægelser"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Tryk for at ændre ringetilstand"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"slå lyden fra"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"slå lyden til"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Start opdelt skærm med aktuel app til højre"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Start opdelt skærm med aktuel app til venstre"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Skift fra opdelt skærm til fuld skærm"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skift til en app til højre eller nedenfor, når du bruger opdelt skærm"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skift til en app til venstre eller ovenfor, når du bruger opdelt skærm"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ved opdelt skærm: Udskift én app med en anden"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Skift til næste sprog"</string>
diff --git a/packages/SystemUI/res/values-da/tiles_states_strings.xml b/packages/SystemUI/res/values-da/tiles_states_strings.xml
index 5a53149..598fcfe 100644
--- a/packages/SystemUI/res/values-da/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-da/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Fra"</item>
     <item msgid="5137565285664080143">"Til"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 6768608..2fd26bc 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Dein IT-Administrator hat das Erstellen von Screenshots blockiert"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Bearbeiten"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Screenshot bearbeiten"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Teilen"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Screenshot teilen"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Mehr aufnehmen"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Screenshot schließen"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Gesicht wird gescannt"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Senden"</string>
     <string name="cancel" msgid="1089011503403416730">"Abbrechen"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"App-Logo"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bestätigen"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Noch einmal versuchen"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Zum Abbrechen der Authentifizierung tippen"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gesicht erkannt. Tippe zum Fortfahren auf das Symbol „Entsperren“."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifiziert"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Authentifizierung abbrechen"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Weitere Optionen"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN verwenden"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Muster verwenden"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Passwort verwenden"</string>
@@ -328,7 +329,7 @@
     <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Geschäftliche Apps"</string>
     <string name="quick_settings_work_mode_paused_state" msgid="6681788236383735976">"Pausiert"</string>
     <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Nachtlicht"</string>
-    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"An bei Sonnenuntergang"</string>
+    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"An: Sonnenuntergang"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Bis Sonnenaufgang"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"An um <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Bis <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Mittel"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Hoch"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Blockierung des Gerätemikrofons aufheben?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Blockierung der Gerätekamera aufheben?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Blockierung von Gerätekamera und Gerätemikrofon aufheben?"</string>
@@ -439,6 +448,10 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Entfernen"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Widget hinzufügen"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Fertig"</string>
+    <!-- no translation found for label_for_button_in_empty_state_cta (7314975555382055823) -->
+    <skip />
+    <!-- no translation found for title_for_empty_state_cta (6161654421223450530) -->
+    <skip />
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Beliebige Widgets auf Sperrbildschirm zulassen?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Einstellungen öffnen"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Geschäftliche Apps nicht mehr pausieren?"</string>
@@ -540,10 +553,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Dieses Gerät wird von deinen Eltern verwaltet. Sie können unter anderem Informationen über deine genutzten Apps, deinen Standort und deine Bildschirmzeit einsehen und verwalten."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Durch TrustAgent entsperrt"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Das Gerät wurde aufgrund zu vieler Authentifizierungsversuche gesperrt"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Gerät gesperrt\nAuthentifizierung fehlgeschlagen"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Toneinstellungen"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Medien autom. untertiteln"</string>
@@ -574,7 +585,7 @@
     <string name="screen_pinning_negative" msgid="6882816864569211666">"Nein danke"</string>
     <string name="screen_pinning_start" msgid="7483998671383371313">"Bildschirm wurde fixiert"</string>
     <string name="screen_pinning_exit" msgid="4553787518387346893">"App vom Bildschirm losgelöst"</string>
-    <string name="stream_voice_call" msgid="7468348170702375660">"Anruf"</string>
+    <string name="stream_voice_call" msgid="7468348170702375660">"Anrufen"</string>
     <string name="stream_system" msgid="7663148785370565134">"System"</string>
     <string name="stream_ring" msgid="7550670036738697526">"Klingelton"</string>
     <string name="stream_music" msgid="2188224742361847580">"Medien"</string>
@@ -589,17 +600,17 @@
     <string name="media_device_cast" msgid="4786241789687569892">"Stream"</string>
     <string name="stream_notification_unavailable" msgid="4313854556205836435">"Nicht verfügbar, da Klingelton stumm"</string>
     <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Nicht verfügbar, weil „Bitte nicht stören“ an ist"</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"Nicht verfügbar, weil „Bitte nicht stören“ an ist"</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"Nicht verfügbar, weil „Bitte nicht stören“ an"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Zum Aufheben der Stummschaltung tippen."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tippen, um Vibrieren festzulegen. Bedienungshilfen werden unter Umständen stummgeschaltet."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Zum Stummschalten tippen. Bedienungshilfen werden unter Umständen stummgeschaltet."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Zum Aktivieren der Vibration tippen."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Zum Stummschalten tippen."</string>
-    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Geräuschunterdrückung"</string>
+    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Geräusch­unterdrückung"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Spatial Audio"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Aus"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Statisch"</string>
-    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Erfassung von Kopfbewegungen"</string>
+    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Erfassung von Kopfbewe­gungen"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Zum Ändern des Klingeltonmodus tippen"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"Stummschalten"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"Aufheben der Stummschaltung"</string>
@@ -765,10 +776,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Splitscreen aktivieren, aktuelle App rechts"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Splitscreen aktivieren, aktuelle App links"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Vom Splitscreen zum Vollbild wechseln"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Im Splitscreen-Modus rechts oder unten zu einer App wechseln"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Im Splitscreen-Modus links oder oben zu einer App wechseln"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Im Splitscreen: eine App durch eine andere ersetzen"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Eingabe"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Zur nächsten Sprache wechseln"</string>
diff --git a/packages/SystemUI/res/values-de/tiles_states_strings.xml b/packages/SystemUI/res/values-de/tiles_states_strings.xml
index e5f8655..4b4eed5 100644
--- a/packages/SystemUI/res/values-de/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-de/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Aus"</item>
     <item msgid="5137565285664080143">"An"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index c7d4825..0c3f0d5 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Η λήψη στιγμιότυπων οθόνης έχει αποκλειστεί από τον διαχειριστή IT."</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Επεξεργασία"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Επεξεργασία στιγμιότυπου οθόνης"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Κοινή χρήση"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Κοινοποίηση στιγμιότυπου οθόνης"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Περισσότερα"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Παράβλεψη στιγμιότυπου οθόνης"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Σάρωση προσώπου"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Αποστολή"</string>
     <string name="cancel" msgid="1089011503403416730">"Ακύρωση"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Λογότυπο εφαρμογής"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Επιβεβαίωση"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Δοκιμάστε ξανά"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Πατήστε για ακύρωση του ελέγχου ταυτότητας"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Το πρόσωπο αναγνωρ. Πατήστε το εικον. ξεκλειδ. για συνέχεια."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Ολοκληρώθηκε ο έλεγχος ταυτότητας"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Ακύρωση ελέγχου ταυτότητας"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Περισσότερες επιλογές"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Χρήση PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Χρήση μοτίβου"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Χρήση κωδικού πρόσβασης"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Τυπική"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Μέτρια"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Υψηλή"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Κατάργηση αποκλεισμού μικροφώνου συσκευής;"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Κατάργηση αποκλεισμού κάμερας συσκευής;"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Κατάργηση αποκλεισμού κάμερας και μικροφώνου συσκευής;"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Κατάργηση"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Προσθήκη γραφικού στοιχείου"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Τέλος"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Προσθήκη γραφικών στοιχείων"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Αποκτήστε γρήγορα πρόσβαση στα αγαπημένα σας γραφικά στοιχεία εφαρμογών χωρίς να ξεκλειδώσετε το tablet σας."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Να επιτρέπονται όλα τα γραφικά στοιχεία στην οθόνη κλειδώματος;"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Άνοιγμα ρυθμίσεων"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Αναίρ. παύσης εφαρμ. εργασιών;"</string>
@@ -574,7 +585,7 @@
     <string name="screen_pinning_exit" msgid="4553787518387346893">"Η εφαρμογή ξεκαρφιτσώθηκε."</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"Κλήση"</string>
     <string name="stream_system" msgid="7663148785370565134">"Σύστημα"</string>
-    <string name="stream_ring" msgid="7550670036738697526">"Κλήση"</string>
+    <string name="stream_ring" msgid="7550670036738697526">"Ήχος κλήσης"</string>
     <string name="stream_music" msgid="2188224742361847580">"Μέσα"</string>
     <string name="stream_alarm" msgid="16058075093011694">"Ξυπνητήρι"</string>
     <string name="stream_notification" msgid="7930294049046243939">"Ειδοποίηση"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Ενεργοποίηση διαχωρισμού οθόνης με την τρέχουσα εφαρμογή στα δεξιά"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Ενεργοποίηση διαχωρισμού οθόνης με την τρέχουσα εφαρμογή στα αριστερά"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Εναλλαγή από διαχωρισμό οθόνης σε πλήρη οθόνη"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Εναλλαγή στην εφαρμογή δεξιά ή κάτω κατά τη χρήση διαχωρισμού οθόνης"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Εναλλαγή σε εφαρμογή αριστερά ή επάνω κατά τη χρήση διαχωρισμού οθόνης"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Κατά τον διαχωρισμό οθόνης: αντικατάσταση μιας εφαρμογής με άλλη"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Είσοδος"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Εναλλαγή στην επόμενη γλώσσα"</string>
@@ -1176,7 +1185,7 @@
     <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Δεν θα γίνεται προς το παρόν αυτόματη σύνδεση Wi-Fi."</string>
     <string name="see_all_networks" msgid="3773666844913168122">"Εμφάνιση όλων"</string>
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Για εναλλαγή δικτύων, αποσυνδέστε το ethernet"</string>
-    <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Για βελτίωση της εμπειρίας στη συσκευή, οι εφαρμογές και οι υπηρεσίες μπορούν ακόμα να εκτελούν σάρωση για δίκτυα Wi‑Fi ανά πάσα στιγμή, ακόμα και όταν το Wi‑Fi είναι απενεργοποιημένο. Μπορείτε να αλλάξετε αυτήν τη ρύθμιση στις ρυθμίσεις της Σάρωσης Wi‑Fi. "<annotation id="link">"Αλλαγή"</annotation></string>
+    <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Για βελτίωση της εμπειρίας στη συσκευή, οι εφαρμογές και οι υπηρεσίες μπορούν ακόμα να εκτελούν σάρωση για δίκτυα Wi‑Fi ανά πάσα στιγμή, ακόμα και όταν το Wi‑Fi είναι απενεργοποιημένο. Μπορείτε να αλλάξετε αυτή τη ρύθμιση στις ρυθμίσεις της Σάρωσης Wi‑Fi. "<annotation id="link">"Αλλαγή"</annotation></string>
     <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Απενεργοποίηση λειτουργίας πτήσης"</string>
     <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"Η εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g> θέλει να προσθέσει το παρακάτω πλακίδιο στις Γρήγορες ρυθμίσεις"</string>
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Προσθήκη πλακιδίου"</string>
diff --git a/packages/SystemUI/res/values-el/tiles_states_strings.xml b/packages/SystemUI/res/values-el/tiles_states_strings.xml
index a697711..e4c6854 100644
--- a/packages/SystemUI/res/values-el/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-el/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Ανενεργό"</item>
     <item msgid="5137565285664080143">"Ενεργό"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index ed9e816..a8848a5 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Taking screenshots is blocked by your IT admin"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Share"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capture more"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dismiss screenshot"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancel"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"App logo"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Tap to cancel authentication"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel authentication"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More options"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Use password"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Medium"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"High"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Done"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Add widgets"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Get quick access to your favourite app widgets without unlocking your tablet."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Allow any widget on the lock screen?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Open settings"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Unpause work apps?"</string>
@@ -472,7 +483,7 @@
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Start casting?"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"When you’re casting, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"When you’re casting an app, Android has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"When you’re casting an app, Android has access to anything shown or played on that app. Be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Start casting"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Start sharing?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"When you’re sharing, recording or casting, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Enter split screen with current app to RHS"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Enter split screen with current app to LHS"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Switch from split screen to full screen"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Switch to next language"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
index d97c4c9..304abe1 100644
--- a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Off"</item>
     <item msgid="5137565285664080143">"On"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 99b3e31..4b69255 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -151,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancel"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"App logo"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Tap to cancel authentication"</string>
@@ -165,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognized. Press the unlock icon to continue."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel Authentication"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More Options"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Use password"</string>
@@ -361,6 +363,10 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Medium"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"High"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Hearing devices"</string>
+    <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"Hearing devices"</string>
+    <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"Pair new device"</string>
+    <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
@@ -438,6 +444,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Done"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Add widgets"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Get quick access to your favorite app widgets without unlocking your tablet."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Allow any widget on lock screen?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Open settings"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Unpause work apps?"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
index d97c4c9..39dd7c8 100644
--- a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"Off"</item>
     <item msgid="5137565285664080143">"On"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"Unavailable"</item>
+    <item msgid="3079622119444911877">"Off"</item>
+    <item msgid="3028994095749238254">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index ed9e816..a8848a5 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Taking screenshots is blocked by your IT admin"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Share"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capture more"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dismiss screenshot"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancel"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"App logo"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Tap to cancel authentication"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel authentication"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More options"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Use password"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Medium"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"High"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Done"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Add widgets"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Get quick access to your favourite app widgets without unlocking your tablet."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Allow any widget on the lock screen?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Open settings"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Unpause work apps?"</string>
@@ -472,7 +483,7 @@
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Start casting?"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"When you’re casting, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"When you’re casting an app, Android has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"When you’re casting an app, Android has access to anything shown or played on that app. Be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Start casting"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Start sharing?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"When you’re sharing, recording or casting, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Enter split screen with current app to RHS"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Enter split screen with current app to LHS"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Switch from split screen to full screen"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Switch to next language"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
index d97c4c9..304abe1 100644
--- a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Off"</item>
     <item msgid="5137565285664080143">"On"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index ed9e816..a8848a5 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Taking screenshots is blocked by your IT admin"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit screenshot"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Share"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Share screenshot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capture more"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dismiss screenshot"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanning face"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancel"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"App logo"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirm"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Try again"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Tap to cancel authentication"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Face recognised. Press the unlock icon to continue."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authenticated"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancel authentication"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"More options"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Use PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Use pattern"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Use password"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Medium"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"High"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Unblock device camera and microphone?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Remove"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Add widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Done"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Add widgets"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Get quick access to your favourite app widgets without unlocking your tablet."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Allow any widget on the lock screen?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Open settings"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Unpause work apps?"</string>
@@ -472,7 +483,7 @@
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Start casting?"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"When you’re casting, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"When you’re casting an app, Android has access to anything shown or played on that app. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"When you’re casting an app, Android has access to anything shown or played on that app. Be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Start casting"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Start sharing?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"When you’re sharing, recording or casting, Android has access to anything visible on your screen or played on your device. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Enter split screen with current app to RHS"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Enter split screen with current app to LHS"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Switch from split screen to full screen"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Switch to next language"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
index d97c4c9..304abe1 100644
--- a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Off"</item>
     <item msgid="5137565285664080143">"On"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index fc7f605..3ed9fc5 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -151,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‎‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎Scanning face‎‏‎‎‏‎"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎Send‎‏‎‎‏‎"</string>
     <string name="cancel" msgid="1089011503403416730">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‏‎‎‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‏‎‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎Cancel‎‏‎‎‏‎"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‎App logo‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‎‏‎‎‎‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‏‏‏‏‏‎Confirm‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‏‎‏‎‎‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‎‎‎‏‏‎‎‎Try again‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‎Tap to cancel authentication‎‏‎‎‏‎"</string>
@@ -165,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‎‏‎‏‏‎Face recognized. Press the unlock icon to continue.‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‏‎‎‎‏‎‏‎‎‏‎‎‎Authenticated‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‎‎‎‎‎‎‏‎‎‎‏‎‎‏‏‎‏‎Cancel Authentication‎‏‎‎‏‎"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‏‎‎‏‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎More Options‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‎‏‎‏‎Use PIN‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‎Use pattern‎‏‎‎‏‎"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‎‏‏‎Use password‎‏‎‎‏‎"</string>
@@ -361,6 +363,10 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎‏‏‎‎‎‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‏‎‏‏‎‏‎‏‏‎‏‏‏‎‏‎‏‏‎‎‎‏‎‎‎‎Standard‎‏‎‎‏‎"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‏‎‏‏‎‎‎‏‎‎‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‏‎‎‏‎‏‏‎‏‏‎‏‏‎‎‏‏‎‎Medium‎‏‎‎‏‎"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎High‎‏‎‎‏‎"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‏‎‎‏‎‏‎‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‏‎Hearing devices‎‏‎‎‏‎"</string>
+    <string name="quick_settings_hearing_devices_dialog_title" msgid="9004774017688484981">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‎‎‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‎‎‏‏‏‎‏‎‏‎Hearing devices‎‏‎‎‏‎"</string>
+    <string name="quick_settings_pair_hearing_devices" msgid="5987105102207447322">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‏‎‏‎‎‏‎‎‏‎‎‎‎‎‎‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‎Pair new device‎‏‎‎‏‎"</string>
+    <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‎‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‏‎‎Click to pair new device‎‏‎‎‏‎"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎Unblock device microphone?‎‏‎‎‏‎"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎Unblock device camera?‎‏‎‎‏‎"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‎‏‎‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‎‏‏‎‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‏‏‏‎Unblock device camera and microphone?‎‏‎‎‏‎"</string>
@@ -438,6 +444,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‏‏‎‏‎‎‏‏‏‏‏‎‏‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎Remove‎‏‎‎‏‎"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‎‏‏‎‎‏‏‎‎‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‏‎Add widget‎‏‎‎‏‎"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‎‏‎‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎Done‎‏‎‎‏‎"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‏‏‏‏‎‎‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‏‎Add widgets‎‏‎‎‏‎"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‎‎‎‎‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‎‎‎‏‎‎Get quick access to your favorite app widgets without unlocking your tablet.‎‏‎‎‏‎"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‏‏‎‏‎‏‏‏‎‏‎‏‎‏‎‎‎‏‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎Allow any widget on lock screen?‎‏‎‎‏‎"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‏‎‏‏‎‎‏‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎Open settings‎‏‎‎‏‎"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‎‎‎‏‎Unpause work apps?‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
index 2facf58..35ab88b 100644
--- a/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‏‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‎‏‎‎‏‏‎‎‎‏‎Off‎‏‎‎‏‎"</item>
     <item msgid="5137565285664080143">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‏‏‎‎‎‏‎‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‎‎‏‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‏‏‏‏‎On‎‏‎‎‏‎"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎Unavailable‎‏‎‎‏‎"</item>
+    <item msgid="3079622119444911877">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‎‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‏‎Off‎‏‎‎‏‎"</item>
+    <item msgid="3028994095749238254">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‏‎‏‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‏‏‎‎On‎‏‎‎‏‎"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 129987e..3755fb6 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Tu administrador de TI bloquea las capturas de pantalla"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de pantalla"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Compartir"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Compartir captura"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturar más"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Descartar captura de pantalla"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Escaneando rostro"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logotipo de la app"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Volver a intentarlo"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Presiona para cancelar la autenticación"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rostro reconocido. Presiona el desbloqueo para continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticación"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Más opciones"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar patrón"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Usar contraseña"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Estándar"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Medio"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Alto"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"¿Quieres desbloquear el micrófono del dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"¿Quieres desbloquear la cámara del dispositivo?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"¿Quieres desbloquear la cámara y el micrófono del dispositivo?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Quitar"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Agregar widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Listo"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Agregar widgets"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Accede rápidamente a los widgets de tus apps favoritas sin desbloquear la tablet."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"¿Quieres permitir cualquier widget en la pantalla de bloqueo?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Abrir configuración"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"¿Reanudar apps de trabajo?"</string>
@@ -450,7 +461,7 @@
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"¿Quieres retomar la sesión?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Volver a empezar"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Sí, continuar"</string>
-    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo de Invitado"</string>
+    <string name="guest_notification_app_name" msgid="2110425506754205509">"Modo de invitado"</string>
     <string name="guest_notification_session_active" msgid="5567273684713471450">"Estás en el modo de invitado"</string>
     <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Si agregas un usuario nuevo, se desactivará el modo de invitado y se borrarán todas las apps y los datos de la sesión de invitado actual."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Alcanzaste el límite de usuarios"</string>
@@ -470,10 +481,10 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Cuando compartas, grabes o transmitas una app, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> podrá acceder a todo el contenido que se muestre o que reproduzcas en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Iniciar"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> inhabilitó esta opción"</string>
-    <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"¿Quieres comenzar a transmitir contenido?"</string>
+    <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"¿Empezar a transmitir contenido?"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Cuando transmitas contenido, Android podrá acceder a todo lo que sea visible en la pantalla o que reproduzcas en el dispositivo. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Cuando transmitas una app, Android podrá acceder a todo el contenido que se muestre o que reproduzcas en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
-    <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Comenzar a transmitir contenido"</string>
+    <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Empezar"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"¿Quieres empezar a compartir?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Cuando compartas, grabes o transmitas contenido, Android podrá acceder a todo lo que sea visible en la pantalla o que reproduzcas en el dispositivo. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Cuando compartas, grabes o transmitas una app, Android podrá acceder a todo el contenido que se muestre o que reproduzcas en ella. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
@@ -621,7 +632,7 @@
     <string name="wallet_title" msgid="5369767670735827105">"Billetera"</string>
     <string name="wallet_empty_state_label" msgid="7776761245237530394">"Prepárate para realizar compras rápidas y seguras con tu teléfono"</string>
     <string name="wallet_app_button_label" msgid="7123784239111190992">"Mostrar todo"</string>
-    <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Presiona para abrir"</string>
+    <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Toca para abrir"</string>
     <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Actualizando"</string>
     <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Desbloquear para usar"</string>
     <string name="wallet_error_generic" msgid="257704570182963611">"Ocurrió un problema al obtener las tarjetas; vuelve a intentarlo más tarde"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Activar pantalla dividida con la app actual en el lado derecho (RHS)"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Activar pantalla dividida con la app actual en el lado izquierdo (LHS)"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Cambiar de pantalla dividida a pantalla completa"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Ubica la app a la derecha o abajo cuando usas la pantalla dividida"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Ubica la app a la izquierda o arriba cuando usas la pantalla dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Durante pantalla dividida: Reemplaza una app con otra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Cambiar al próximo idioma"</string>
@@ -1164,7 +1173,7 @@
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Conexión establecida"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Conectado temporalmente"</string>
     <string name="mobile_data_poor_connection" msgid="819617772268371434">"Conexión deficiente"</string>
-    <string name="mobile_data_off_summary" msgid="3663995422004150567">"No se conectarán automáticamente los datos móviles"</string>
+    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Los datos móviles no se conectarán automáticamente"</string>
     <string name="mobile_data_no_connection" msgid="1713872434869947377">"Sin conexión"</string>
     <string name="non_carrier_network_unavailable" msgid="770049357024492372">"No hay otras redes disponibles"</string>
     <string name="all_network_unavailable" msgid="4112774339909373349">"No hay redes disponibles"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
index 6446bdf..71efef9 100644
--- a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Desactivado"</item>
     <item msgid="5137565285664080143">"Activado"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index c01a44f..01afa29 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Tu administrador de TI ha bloqueado las capturas de pantalla"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de pantalla"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Compartir"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Compartir captura de pantalla"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturar más"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Cerrar captura de pantalla"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Escaneando cara"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logotipo de la aplicación"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Reintentar"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Toca para cancelar la autenticación"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Cara reconocida. Pulsa el icono de desbloquear para continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Se ha autenticado"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticación"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Más opciones"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar patrón"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Usar contraseña"</string>
@@ -265,7 +266,7 @@
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"No hay dispositivos vinculados disponibles"</string>
     <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Toca para conectar o desconectar un dispositivo"</string>
-    <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Emparejar un nuevo dispositivo"</string>
+    <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Emparejar nuevo dispositivo"</string>
     <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Ver todos"</string>
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Usar Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Conectado"</string>
@@ -286,7 +287,7 @@
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicación"</string>
     <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Salvapantallas"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acceso a cámara"</string>
-    <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acceso al micro"</string>
+    <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acceso a micro"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponible"</string>
     <string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Bloqueado"</string>
     <string name="quick_settings_media_device_label" msgid="8034019242363789941">"Dispositivo multimedia"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Estándar"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Medio"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Alto"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"¿Desbloquear el micrófono del dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"¿Desbloquear la cámara del dispositivo?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"¿Desbloquear la cámara y el micrófono del dispositivo?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Quitar"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Añadir widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Hecho"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Añadir widgets"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Accede rápidamente a los widgets de tus aplicaciones favoritas sin desbloquear la tablet."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"¿Permitir cualquier widget en la pantalla de bloqueo?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Abrir ajustes"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"¿Reactivar apps de trabajo?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Tu padre o madre gestionan este dispositivo y pueden ver y controlar cierta información, como las aplicaciones que utilizas, tu ubicación y tu tiempo de pantalla."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Desbloqueado por TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Dispositivo bloqueado; demasiados intentos de autenticación"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Dispositivo bloqueado\nError de autenticación"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Ajustes de sonido"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Subtitular automáticamente"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Iniciar pantalla dividida con esta aplicación en el lado derecho"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Iniciar pantalla dividida con esta aplicación en el lado izquierdo"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Cambiar de pantalla dividida a pantalla completa"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Cambiar a la app de la derecha o de abajo en pantalla dividida"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Cambiar a la app de la izquierda o de arriba en pantalla dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Con pantalla dividida: reemplazar una aplicación por otra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Cambiar a siguiente idioma"</string>
diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml
index 4cc0c67..bd90056 100644
--- a/packages/SystemUI/res/values-es/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Desactivado"</item>
     <item msgid="5137565285664080143">"Activado"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index ff07693..52cbb0f 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -151,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Näo skannimine"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Saada"</string>
     <string name="cancel" msgid="1089011503403416730">"Tühista"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Rakenduse logo"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Kinnita"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Proovi uuesti"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Puudutage autentimise tühistamiseks"</string>
@@ -165,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Nägu tuvastati. Jätkamiseks vajutage avamise ikooni."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenditud"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Tühista autentimine"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Rohkem valikuid"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Kasuta PIN-koodi"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Kasuta mustrit"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Kasuta parooli"</string>
@@ -361,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Tavaline"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Keskmine"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Kõrge"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kas tühistada seadme mikrofoni blokeerimine?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kas tühistada seadme kaamera blokeerimine?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Kas tühistada seadme kaamera ja mikrofoni blokeerimine?"</string>
@@ -438,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Eemalda"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Lisa vidin"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Valmis"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Vidinate lisamine"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Pääsege kiiresti juurde rakenduse lemmikvidinatele ilma tahvelarvutit avamata."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Kas lubada lukustuskuval kõik vidinad?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Ava seaded"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Kas lõpetada töörakenduste peatamine?"</string>
@@ -539,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Seda seadet haldab sinu vanem. Sinu vanem näeb ja saab hallata teavet, näiteks kasutatavaid rakendusi, sinu asukohta ja ekraaniaega."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Avatuna hoiab TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Seade lukustati, liiga palju autentimiskatseid"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Seade on lukustatud\nAutentimine ebaõnnestus"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Heliseaded"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automaatsed subtiitrid"</string>
@@ -611,7 +621,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"vaigistab %s"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"tühistab %s vaigistuse"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"Esitamine jätkub seadmes <xliff:g id="LABEL">%s</xliff:g>"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Heli esitamine jätkub"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Heli esitatakse seadmes"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"Süsteemi kasutajaliidese tuuner"</string>
     <string name="status_bar" msgid="4357390266055077437">"Olekuriba"</string>
     <string name="demo_mode" msgid="263484519766901593">"Süsteemi kasutajaliidese demorežiim"</string>
@@ -1176,7 +1186,7 @@
     <string name="see_all_networks" msgid="3773666844913168122">"Kuva kõik"</string>
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Võrkude vahetamiseks katkestage Etherneti-ühendus"</string>
     <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Seadme kasutuskogemuse parandamiseks võivad rakendused ja teenused siiski alati otsida WiFi-võrke isegi siis, kui WiFi on väljas. Seda saab muuta WiFi-skannimise seadetes. "<annotation id="link">"Muuda"</annotation></string>
-    <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Lennureżiimi väljalülitamine"</string>
+    <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Lülita lennukireżiim välja"</string>
     <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> soovib kiirseadetesse lisada järgmise paani"</string>
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Lisa paan"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"Ära lisa paani"</string>
@@ -1237,7 +1247,7 @@
     <string name="home_quick_affordance_unavailable_configure_the_app" msgid="604424593994493281">"• Vähemalt üks seade või seadmepaneel on saadaval"</string>
     <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Valige märkmete tegemise vaikerakendus, et kasutada märkmete tegemise otseteed"</string>
     <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Valige rakendus"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pikalt puudutamise otsetee"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Puudutage otseteed pikalt"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Tühista"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Vaheta ekraane kohe"</string>
     <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Telefoni lahtivoltimine"</string>
diff --git a/packages/SystemUI/res/values-et/tiles_states_strings.xml b/packages/SystemUI/res/values-et/tiles_states_strings.xml
index f16d552..55bff30 100644
--- a/packages/SystemUI/res/values-et/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-et/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Väljas"</item>
     <item msgid="5137565285664080143">"Sees"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index caed3b5..b0056f6 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"IKT saileko administratzaileak blokeatu egin dizu pantaila-argazkiak ateratzeko aukera"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Editatu"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Editatu pantaila-argazkia"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Partekatu"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Partekatu pantaila-argazkia"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Kapturatu eduki gehiago"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Baztertu pantaila-argazkia"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Aurpegia eskaneatzen"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Bidali"</string>
     <string name="cancel" msgid="1089011503403416730">"Utzi"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Aplikazioaren logotipoa"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Berretsi"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Saiatu berriro"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Sakatu hau autentifikazioa bertan behera uzteko"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ezagutu da aurpegia. Aurrera egiteko, sakatu desblokeatzeko ikonoa."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikatuta"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Utzi bertan behera autentifikazioa"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Aukera gehiago"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Erabili PINa"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Erabili eredua"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Erabili pasahitza"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Arrunta"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Tartekoa"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Altua"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Gailuaren mikrofonoa desblokeatu nahi duzu?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Gailuaren kamera desblokeatu nahi duzu?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Gailuaren kamera eta mikrofonoa desblokeatu nahi dituzu?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Kendu"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Gehitu widget bat"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Eginda"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Gehitu widgetak"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Atzitu gogoko aplikazioen widgetak bizkor, tableta desblokeatu gabe."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Pantaila blokeatuan edozein widget erakusteko baimena eman nahi duzu?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Ireki ezarpenak"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Laneko aplikazioak berraktibatu?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Zure gurasoak kudeatzen du gailua. Zure gurasoak gailuko informazioa ikusi eta kudea dezake; besteak beste, zer aplikazio erabiltzen dituzun, zure kokapena zein den eta pantaila aurrean zenbat eta noiz egoten zaren."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPNa"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent bidez desblokeatuta"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Blokeatu egin da gailua. Autentifikatze-saiakera gehiegi egin dira."</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Gailua blokeatuta dago\nEzin izan da autentifikatu"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Soinuaren ezarpenak"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Ezarri azpitituluak automatikoki"</string>
@@ -595,7 +604,7 @@
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Sakatu audioa desaktibatzeko. Baliteke erabilerraztasun-eginbideen audioa desaktibatzea."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Sakatu hau dardara ezartzeko."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Sakatu hau audioa desaktibatzeko."</string>
-    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Zarata-murrizketa"</string>
+    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Zarata-kontrola"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Audio espaziala"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Desaktibatuta"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Finkoa"</string>
@@ -612,7 +621,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"desaktibatu honen audioa: %s"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"aktibatu honen audioa: %s"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> hemen erreproduzitzen:"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audioa erreproduzitzen jarraituko du"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audioak abian jarraituko du hemen:"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"Sistemaren erabiltzaile-interfazearen konfiguratzailea"</string>
     <string name="status_bar" msgid="4357390266055077437">"Egoera-barra"</string>
     <string name="demo_mode" msgid="263484519766901593">"Sistemaren erabiltzaile-interfazearen demo modua"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Sartu pantaila zatituaren eskuineko aldean oraingo aplikazioarekin"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Sartu pantaila zatituaren ezkerreko aldean oraingo aplikazioarekin"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Aldatu pantaila zatitutik pantaila osora"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Aldatu eskuineko edo beheko aplikaziora pantaila zatitua erabiltzean"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Aldatu ezkerreko edo goiko aplikaziora pantaila zatitua erabiltzean"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Pantaila zatituan zaudela, ordeztu aplikazio bat beste batekin"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Sarrera"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Aldatu hurrengo hizkuntzara"</string>
@@ -1153,7 +1160,7 @@
     <string name="person_available" msgid="2318599327472755472">"Konektatuta"</string>
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Arazo bat izan da bateria-neurgailua irakurtzean"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Informazio gehiago lortzeko, sakatu hau"</string>
-    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Ez da ezarri alarmarik"</string>
+    <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Alarmarik ez"</string>
     <string name="accessibility_bouncer" msgid="5896923685673320070">"erabili pantailaren blokeoa"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Hatz-marken sentsorea"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"autentifikatu"</string>
@@ -1166,7 +1173,7 @@
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Konektatuta"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Aldi baterako konektatuta"</string>
     <string name="mobile_data_poor_connection" msgid="819617772268371434">"Konexio ahula"</string>
-    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Ez da automatikoki aktibatuko datu-konexioa"</string>
+    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Datu-konexioa ez da automatikoki aktibatuko"</string>
     <string name="mobile_data_no_connection" msgid="1713872434869947377">"Konexiorik gabe"</string>
     <string name="non_carrier_network_unavailable" msgid="770049357024492372">"Ez dago beste sare erabilgarririk"</string>
     <string name="all_network_unavailable" msgid="4112774339909373349">"Ez dago sare erabilgarririk"</string>
diff --git a/packages/SystemUI/res/values-eu/tiles_states_strings.xml b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
index 0f6570c..7f38d44 100644
--- a/packages/SystemUI/res/values-eu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Desaktibatuta"</item>
     <item msgid="5137565285664080143">"Aktibatuta"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 03566d6..de97db35 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"سرپرست فناوری اطلاعات گرفتن نماگرفت را مسدود کرده است"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"ویرایش"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"ویرایش نماگرفت"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"هم‌رسانی"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"هم‌رسانی نماگرفت"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ضبط محتوای بیشتر"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"رد کردن نماگرفت"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"درحال اسکن کردن چهره"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ارسال"</string>
     <string name="cancel" msgid="1089011503403416730">"لغو"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"نشان‌واره برنامه"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"تأیید"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"امتحان مجدد"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"برای لغو راستی‌آزمایی ضربه بزنید"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"چهره شناسایی شد. برای ادامه، نماد قفل‌گشایی را فشار دهید."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"راستی‌آزمایی‌شده"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"لغو اصالت‌سنجی"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"گزینه‌های بیشتر"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"استفاده از پین"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"استفاده از الگو"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"استفاده از گذرواژه"</string>
@@ -274,7 +275,7 @@
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_activate" msgid="3724301751036877403">"فعال کردن"</string>
     <string name="turn_on_bluetooth_auto_tomorrow" msgid="414836329962473906">"فردا دوباره به‌طور خودکار روشن شود"</string>
     <string name="turn_on_bluetooth_auto_info_disabled" msgid="8267380591344023327">"ویژگی‌هایی مثل «هم‌رسانی سریع»، «پیدا کردن دستگاهم»، و مکان دستگاه از بلوتوث استفاده می‌کنند"</string>
-    <string name="turn_on_bluetooth_auto_info_enabled" msgid="4802071533678400330">"بلوتوث فردا ۵ ق.ظ. روشن خواهد شد"</string>
+    <string name="turn_on_bluetooth_auto_info_enabled" msgid="4802071533678400330">"بلوتوث فردا ۵ ق.ظ روشن خواهد شد"</string>
     <string name="quick_settings_bluetooth_secondary_label_battery_level" msgid="4182034939479344093">"شارژ باتری <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%s</xliff:g>"</string>
     <string name="quick_settings_bluetooth_secondary_label_audio" msgid="780333390310051161">"صوت"</string>
     <string name="quick_settings_bluetooth_secondary_label_headset" msgid="2332093067553000852">"هدست"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"استاندارد"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"متوسط"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"بالا"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"میکروفون دستگاه لغو انسداد شود؟"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"دوربین دستگاه لغو انسداد شود؟"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"دوربین و میکروفون دستگاه لغو انسداد شود؟"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"برداشتن"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"افزودن ابزارک"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"تمام"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"افزودن ابزارک‌ها"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"بدون باز کردن قفل رایانه لوحی، به ابزارک برنامه‌های دلخواهتان فوراً دسترسی پیدا کنید."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"هر نوع ابزارکی در صفحه قفل مجاز شود؟"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"باز کردن تنظیمات"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"مکث برنامه‌های کاری لغو شود؟"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"این دستگاه را ولی‌تان مدیریت می‌کند. ولی‌تان می‌تواند اطلاعاتی مثل برنامه‌هایی که استفاده می‌کنید، مکانتان، و مدت تماشای صفحه‌تان را ببیند و مدیریت کند."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"‏با TrustAgent قفل را باز نگه‌دارید"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"دستگاه قفل شد، تعداد تلاش‌ها برای اصالت‌سنجی بسیار زیاد بود"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"دستگاه قفل شد\nاصالت‌سنجی ناموفق بود"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. ‏<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"تنظیمات صدا"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"رسانه زیرنویس خودکار"</string>
@@ -612,7 +621,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"‏بی‌صدا کردن %s"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"‏باصدا کردن %s"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"درحال پخش <xliff:g id="LABEL">%s</xliff:g> در"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"صدا پخش می‌شود در"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"صدا در این دستگاه پخش می‌شود:"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"تنظیم‌کننده واسط کاربری سیستم"</string>
     <string name="status_bar" msgid="4357390266055077437">"نوار وضعیت"</string>
     <string name="demo_mode" msgid="263484519766901593">"حالت نمایشی واسط کاربری سیستم"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"وارد شدن به صفحهٔ دونیمه با برنامه فعلی در سمت راست"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"وارد شدن به صفحهٔ دونیمه با برنامه فعلی در سمت چپ"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"جابه‌جایی از صفحهٔ دونیمه به تمام صفحه"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"رفتن به برنامه سمت راست یا پایین درحین استفاده از صفحهٔ دونیمه"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"رفتن به برنامه سمت چپ یا بالا درحین استفاده از صفحهٔ دونیمه"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"درحین صفحهٔ دونیمه: برنامه‌ای را با دیگری جابه‌جا می‌کند"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ورودی"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"رفتن به زبان بعدی"</string>
diff --git a/packages/SystemUI/res/values-fa/tiles_states_strings.xml b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
index 6d6954e..9a6b1af 100644
--- a/packages/SystemUI/res/values-fa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"خاموش"</item>
     <item msgid="5137565285664080143">"روشن"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index ee36315..55413a0 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"IT-järjestelmänvalvoja on estänyt kuvakaappauksien ottamisen."</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Muuta"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Muokkaa kuvakaappausta"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Jaa"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Jaa kuvakaappaus"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Kuvaa enemmän"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Hylkää kuvakaappaus"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Kasvojen skannaus"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Lähetä"</string>
     <string name="cancel" msgid="1089011503403416730">"Peru"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Sovelluksen logo"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Vahvista"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Yritä uudelleen"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Peru todennus napauttamalla"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Kasvot tunnistettu. Jatka lukituksen avauskuvakkeella."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Todennettu"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Peruuta todennus"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Lisää vaihtoehtoja"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Käytä PIN-koodia"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Käytä kuviota"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Käytä salasanaa"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Tavallinen"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Keskitaso"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Suuri"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kumotaanko laitteen mikrofonin esto?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kumotaanko laitteen kameran esto?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Kumotaanko laitteen kameran ja mikrofonin esto?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Poista"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Lisää widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Valmis"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Lisää widgetejä"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Pääset nopeasti tuttuihin sovelluswidgeteihin avaamatta tabletin lukitusta."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Sallitaanko kaikki widgetit lukitusnäytöllä?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Avaa asetukset"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Laita työsovellukset päälle?"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Siirry jaettuun näyttöön (sovellus oikeanpuoleiseen näyttöön)"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Siirry jaettuun näyttöön (sovellus vasemmanpuoleiseen näyttöön)"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Vaihda jaetusta näytöstä koko näyttöön"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Vaihda sovellukseen oikealla tai alapuolella jaetun näytön avulla"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Vaihda sovellukseen vasemmalla tai yläpuolella jaetun näytön avulla"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Jaetun näytön aikana: korvaa sovellus toisella"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Syöttötapa"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Vaihda seuraavaan kieleen"</string>
diff --git a/packages/SystemUI/res/values-fi/tiles_states_strings.xml b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
index 545abc9..f1e3e61 100644
--- a/packages/SystemUI/res/values-fi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Pois päältä"</item>
     <item msgid="5137565285664080143">"Päällä"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 5c534cb..272e00e 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"La prise de captures d\'écran est bloquée par votre administrateur informatique"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Modifier"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Modifier la capture d\'écran"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Partager"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Partagez la capture d\'écran"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturer plus"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Fermer la capture d\'écran"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Numérisation du visage"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envoyer"</string>
     <string name="cancel" msgid="1089011503403416730">"Annuler"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logo de l\'application"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmer"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Réessayer"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Touchez ici pour annuler l\'authentification"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Visage reconnu. Appuyez sur Déverrouiller pour continuer."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annuler l\'authentification"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Plus d\'options"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utiliser un NIP"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utiliser un schéma"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Utiliser un mot de passe"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Moyen"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Élevé"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le microphone de l\'appareil?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer l\'appareil photo de l\'appareil?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Débloquer l\'appareil photo et le microphone?"</string>
@@ -439,6 +448,10 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Retirer"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Ajouter un widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Terminé"</string>
+    <!-- no translation found for label_for_button_in_empty_state_cta (7314975555382055823) -->
+    <skip />
+    <!-- no translation found for title_for_empty_state_cta (6161654421223450530) -->
+    <skip />
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Autoriser n\'importe quel widget sur l\'écran de verrouillage?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Ouvrir les paramètres"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Réactiver les applis pros?"</string>
@@ -763,10 +776,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Passer à l\'écran divisé avec l\'application actuelle à droite"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Passer à l\'écran divisé avec l\'application actuelle à gauche"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Passer de l\'écran divisé au plein écran"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passer à l\'application à droite ou en dessous avec l\'Écran divisé"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passer à l\'application à gauche ou au-dessus avec l\'Écran divisé"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"En mode d\'écran divisé : remplacer une application par une autre"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrée"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Passer à la langue suivante"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
index d89484d..dfea45a 100644
--- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Désactivée"</item>
     <item msgid="5137565285664080143">"Activée"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 35c8e7e..41f9249 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"La capture d\'écran est bloquée par votre administrateur informatique"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Modifier"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Modifier la capture d\'écran"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Partager"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Partager la capture d\'écran"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturer plus"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Fermer la capture d\'écran"</string>
@@ -111,7 +110,7 @@
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Lancer l\'enregistrement"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Enregistrer l\'audio"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audio de l\'appareil"</string>
-    <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Son provenant de l\'appareil (musique, appels et sonneries, etc.)"</string>
+    <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Son provenant de l\'appareil (musique, appels, sonneries, etc.)"</string>
     <string name="screenrecord_mic_label" msgid="2111264835791332350">"Micro"</string>
     <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Audio de l\'appareil et micro"</string>
     <string name="screenrecord_continue" msgid="4055347133700593164">"Commencer"</string>
@@ -146,12 +145,13 @@
     <string name="accessibility_phone_button" msgid="4256353121703100427">"Téléphoner"</string>
     <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Assistance vocale"</string>
     <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
-    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Lecteur de code QR"</string>
+    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"Lecteur code QR"</string>
     <string name="accessibility_unlock_button" msgid="3613812140816244310">"Déverrouillé"</string>
     <string name="accessibility_lock_icon" msgid="661492842417875775">"Appareil verrouillé"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Analyse du visage en cours"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Envoyer"</string>
     <string name="cancel" msgid="1089011503403416730">"Annuler"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logo de l\'appli"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmer"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Réessayer"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Appuyer pour annuler l\'authentification"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Visage reconnu. Appuyez sur l\'icône de déverrouillage pour continuer."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Authentifié"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annuler l\'authentification"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Plus d\'options"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utiliser un code PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Utiliser un schéma"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Utiliser un mot de passe"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Moyen"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Élevé"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le micro de l\'appareil ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer la caméra de l\'appareil ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Débloquer l\'appareil photo et le micro de l\'appareil ?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Supprimer"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Ajouter un widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"OK"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Ajouter des widgets"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Accéder rapidement aux widgets de vos applis préférées sans déverrouiller votre tablette."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Autoriser n\'importe quel widget sur l\'écran de verrouillage ?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Ouvrir les paramètres"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Réactiver les applis pro ?"</string>
@@ -463,7 +474,7 @@
     <string name="media_projection_sys_service_dialog_title" msgid="3751133258891897878">"Commencer à enregistrer ou à caster ?"</string>
     <string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"Le service qui fournit cette fonction aura accès à toutes les infos visibles sur votre écran ou lues depuis votre appareil pendant un enregistrement ou une diffusion de contenu. Il peut s\'agir de mots de passe, détails de mode de paiement, photos, messages ou encore contenus audio lus."</string>
     <string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"Tout l\'écran"</string>
-    <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Une seule appli"</string>
+    <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Uniquement l\'appli"</string>
     <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Partager ou enregistrer une appli"</string>
     <string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Commencer à enregistrer ou à caster avec <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ?"</string>
     <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Lorsque vous partagez, enregistrez ou castez, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> a accès à tout ce qui est visible sur votre écran ou lu sur votre appareil. Faites donc attention aux éléments tels que les mots de passe, détails de mode de paiement, messages, photos et contenus audio et vidéo."</string>
@@ -597,7 +608,7 @@
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Son spatial"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Désactivé"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Activé"</string>
-    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Suivi des mouvements de la tête"</string>
+    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Suivi de la tête"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Appuyez pour changer le mode de la sonnerie"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"couper le son"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"réactiver le son"</string>
@@ -610,7 +621,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"couper le son de %s"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"réactiver le son de %s"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"Diffusion de <xliff:g id="LABEL">%s</xliff:g> sur"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"L\'audio se mettra en marche"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Lecture audio sur"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string>
     <string name="status_bar" msgid="4357390266055077437">"Barre d\'état"</string>
     <string name="demo_mode" msgid="263484519766901593">"Mode démo de l\'UI du système"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Passer en écran partagé avec l\'appli actuelle affichée à droite"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Passer en écran partagé avec l\'appli actuelle affichée à gauche"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Passer de l\'écran partagé au plein écran"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passez à l\'appli à droite ou en dessous avec l\'écran partagé"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passez à l\'appli à gauche ou au-dessus avec l\'écran partagé"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"En mode écran partagé : Remplacer une appli par une autre"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Saisie"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Passer à la langue suivante"</string>
diff --git a/packages/SystemUI/res/values-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
index a560ff0..34ccb75 100644
--- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
@@ -58,7 +58,7 @@
   </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Indisponible"</item>
-    <item msgid="5044688398303285224">"Désactivé"</item>
+    <item msgid="5044688398303285224">"Désactivée"</item>
     <item msgid="8527389108867454098">"Activée"</item>
   </string-array>
   <string-array name="tile_states_rotation">
@@ -79,7 +79,7 @@
   <string-array name="tile_states_location">
     <item msgid="3316542218706374405">"Indisponible"</item>
     <item msgid="4813655083852587017">"Désactivé"</item>
-    <item msgid="6744077414775180687">"Activé"</item>
+    <item msgid="6744077414775180687">"Activée"</item>
   </string-array>
   <string-array name="tile_states_hotspot">
     <item msgid="3145597331197351214">"Indisponible"</item>
@@ -113,7 +113,7 @@
   </string-array>
   <string-array name="tile_states_cast">
     <item msgid="6032026038702435350">"Indisponible"</item>
-    <item msgid="1488620600954313499">"Désactivé"</item>
+    <item msgid="1488620600954313499">"Désactivée"</item>
     <item msgid="588467578853244035">"Activé"</item>
   </string-array>
   <string-array name="tile_states_night">
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Désactivé"</item>
     <item msgid="5137565285664080143">"Activé"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index c0694e6..189f048 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -151,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Analizando cara"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logotipo da aplicación"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar de novo"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Toca para cancelar a autenticación"</string>
@@ -165,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Recoñeceuse a cara. Preme a icona de desbloquear."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar a autenticación"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Máis opcións"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrón"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Usar contrasinal"</string>
@@ -361,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Nivel estándar"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Nivel medio"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Nivel alto"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Queres desbloquear o micrófono do dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Queres desbloquear a cámara do dispositivo?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Queres desbloquear a cámara e o micrófono do dispositivo?"</string>
@@ -438,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Quitar"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Engadir widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Feito"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Engadir widgets"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Accede rapidamente aos widgets das túas aplicacións favoritas sen desbloquear a tableta."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Queres permitir calquera widget na pantalla de bloqueo?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Abrir configuración"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Reactivar apps do traballo?"</string>
@@ -573,7 +585,7 @@
     <string name="screen_pinning_exit" msgid="4553787518387346893">"Deixouse de fixar a aplicación"</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"Chamada"</string>
     <string name="stream_system" msgid="7663148785370565134">"Sistema"</string>
-    <string name="stream_ring" msgid="7550670036738697526">"Ton"</string>
+    <string name="stream_ring" msgid="7550670036738697526">"Son"</string>
     <string name="stream_music" msgid="2188224742361847580">"Multimedia"</string>
     <string name="stream_alarm" msgid="16058075093011694">"Alarma"</string>
     <string name="stream_notification" msgid="7930294049046243939">"Notificación"</string>
@@ -584,9 +596,9 @@
     <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string>
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Silenciar"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"Emitir"</string>
-    <string name="stream_notification_unavailable" msgid="4313854556205836435">"Non dispoñible (o son está silenciado)"</string>
-    <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Non dispoñible porque está activado Non molestar"</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"Non dispoñible porque está activado Non molestar"</string>
+    <string name="stream_notification_unavailable" msgid="4313854556205836435">"Non dispoñible: o son está silenciado"</string>
+    <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Non dispoñible: Non molestar está activado"</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"Non dispoñible: Non molestar está activado"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toca para activar o son."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Toca para establecer a vibración. Pódense silenciar os servizos de accesibilidade."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toca para silenciar. Pódense silenciar os servizos de accesibilidade."</string>
@@ -609,7 +621,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"silenciar %s"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"activar o son de %s"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"Reproducindo <xliff:g id="LABEL">%s</xliff:g> en"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Audio reproducido en"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Reproducirase en"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"Configurador da IU do sistema"</string>
     <string name="status_bar" msgid="4357390266055077437">"Barra de estado"</string>
     <string name="demo_mode" msgid="263484519766901593">"Modo de demostración da IU do sistema"</string>
diff --git a/packages/SystemUI/res/values-gl/tiles_states_strings.xml b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
index 1cde1ab..de8ee63 100644
--- a/packages/SystemUI/res/values-gl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Desactivado"</item>
     <item msgid="5137565285664080143">"Activado"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 9913d04..54312e1 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"તમારા IT ઍડમિન દ્વારા સ્ક્રીનશૉટ લેવાની સુવિધા બ્લૉક કરવામાં આવી છે"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"ફેરફાર કરો"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"સ્ક્રીનશૉટમાં ફેરફાર કરો"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"શેર કરો"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"સ્ક્રીનશૉટ શેર કરો"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"વધુ કૅપ્ચર કરો"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"સ્ક્રીનશૉટ છોડી દો"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ચહેરો સ્કૅન કરવો"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"મોકલો"</string>
     <string name="cancel" msgid="1089011503403416730">"રદ કરો"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"ઍપનો લોગો"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"કન્ફર્મ કરો"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ફરી પ્રયાસ કરો"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"પ્રમાણીકરણ રદ કરવા માટે ટૅપ કરો"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ચહેરો ઓળખ્યો. આગળ વધવા \'અનલૉક કરો\' આઇકન દબાવો."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"પ્રમાણિત"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"પ્રમાણીકરણ રદ કરો"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"વધુ વિકલ્પો"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"પિનનો ઉપયોગ કરો"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"પૅટર્નનો ઉપયોગ કરો"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"પાસવર્ડનો ઉપયોગ કરો"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"સ્ટૅન્ડર્ડ"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"મધ્યમ"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"વધુ"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ડિવાઇસના માઇક્રોફોનને અનબ્લૉક કરીએ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ડિવાઇસના કૅમેરાને અનબ્લૉક કરીએ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ડિવાઇસના કૅમેરા અને માઇક્રોફોનને અનબ્લૉક કરીએ?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"કાઢી નાખો"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"વિજેટ ઉમેરો"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"થઈ ગયું"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"વિજેટ ઉમેરો"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"તમારું ટૅબ્લેટ અનલૉક કર્યા વિના તમારા મનપસંદ ઍપ વિજેટનો ઝડપી ઍક્સેસ મેળવો."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"લૉક સ્ક્રીન પર કોઈપણ વિજેટને મંજૂરી આપીએ?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"સેટિંગ ખોલો"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"ઑફિસની થોભાવેલી ઍપ ચાલુ કરીએ?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"આ ડિવાઇસ તમારા માતાપિતા દ્વારા મેનેજ કરવામાં આવે છે. તમે જેનો ઉપયોગ કરો છો તે ઍપ, તમારું સ્થાન અને તમારા સ્ક્રીન સમય જેવી માહિતીને તમારા માતાપિતા જોઈ અને મેનેજ કરી શકે છે."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent દ્વારા અનલૉક રાખેલું"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"પ્રમાણીકરણના ઘણા પ્રયાસો કરવામાં આવ્યા, તેથી ડિવાઇસ લૉક કરવામાં આવ્યું"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"ડિવાઇસ લૉક કર્યું\nપ્રમાણીકરણ નિષ્ફળ થયું છે"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"સાઉન્ડ સેટિંગ"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"મીડિયામાં કૅપ્શન ઑટોમૅટિક રીતે ઉમેરો"</string>
@@ -597,9 +606,9 @@
     <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. મ્યૂટ કરવા માટે ટૅપ કરો."</string>
     <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"અવાજનું નિયંત્રણ"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"સ્પેશલ ઑડિયો"</string>
-    <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"બંધ કરો"</string>
+    <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"બંધ"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ફિક્સ્ડ"</string>
-    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"હેડ ટ્રૅકિંગ"</string>
+    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"હૅડ ટ્રૅકિંગ"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"રિંગર મોડ બદલવા માટે ટૅપ કરો"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"મ્યૂટ કરો"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"અનમ્યૂટ કરો"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"જમણી બાજુ પર હાલની ઍપ સાથે વિભાજિત સ્ક્રીનમાં દાખલ થાઓ"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"ડાબી બાજુ પર હાલની ઍપ સાથે વિભાજિત સ્ક્રીનમાં દાખલ થાઓ"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"વિભાજિત સ્ક્રીનથી પૂર્ણ સ્ક્રીન પર સ્વિચ કરો"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"વિભાજિત સ્ક્રીનનો ઉપયોગ કરતી વખતે જમણી બાજુ કે નીચેની ઍપ પર સ્વિચ કરો"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"વિભાજિત સ્ક્રીનનો ઉપયોગ કરતી વખતે ડાબી બાજુની કે ઉપરની ઍપ પર સ્વિચ કરો"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"વિભાજિત સ્ક્રીન દરમિયાન: એક ઍપને બીજી ઍપમાં બદલો"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ઇનપુટ"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"આગલી ભાષા પર સ્વિચ કરો"</string>
diff --git a/packages/SystemUI/res/values-gu/tiles_states_strings.xml b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
index 65b6133..c6a86e5 100644
--- a/packages/SystemUI/res/values-gu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"બંધ"</item>
     <item msgid="5137565285664080143">"ચાલુ"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 03018c0..ee3e40b 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"आईटी एडमिन ने स्क्रीनशॉट लेने पर रोक लगाई है"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"बदलाव करें"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"स्क्रीनशॉट में बदलाव करें"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"शेयर करें"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"स्क्रीनशॉट शेयर करें"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ज़्यादा कॉन्टेंट कैप्चर करें"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"स्क्रीनशॉट को खारिज करें"</string>
@@ -105,7 +104,7 @@
     <string name="screenrecord_title" msgid="4257171601439507792">"स्क्रीन रिकॉर्डर"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"स्क्रीन रिकॉर्डिंग को प्रोसेस किया जा रहा है"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"स्क्रीन रिकॉर्ड सेशन के लिए जारी सूचना"</string>
-    <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"क्या स्क्रीन रिकॉर्ड करनी है?"</string>
+    <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"क्या रिकॉर्डिंग शुरू करनी है?"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"रिकॉर्ड करते समय, Android के पास स्क्रीन पर दिख रहे कॉन्टेंट या डिवाइस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, और डिवाइस पर चल रहे ऑडियो और वीडियो को लेकर सावधानी बरतें."</string>
     <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"किसी ऐप्लिकेशन को रिकॉर्ड करते समय, Android के पास उस ऐप्लिकेशन पर दिख रहे कॉन्टेंट या उस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, और डिवाइस पर चल रहे ऑडियो और वीडियो को लेकर सावधानी बरतें."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"रिकॉर्ड करें"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"डिवाइस अनलॉक करने के लिए चेहरा स्कैन किया जाता है"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"भेजें"</string>
     <string name="cancel" msgid="1089011503403416730">"रद्द करें"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"ऐप्लिकेशन का लोगो"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"पुष्टि करें"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"फिर से कोशिश करें"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"पुष्टि की प्रक्रिया रद्द करने के लिए टैप करें"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरे की पहचान हो गई. जारी रखने के लिए अनलॉक आइकॉन को टैप करें."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"पुष्टि हो गई"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"पुष्टि करने की प्रोसेस को रद्द करें"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ज़्यादा विकल्प"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"पिन इस्तेमाल करें"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"पैटर्न इस्तेमाल करें"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"पासवर्ड इस्तेमाल करें"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"स्टैंडर्ड"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"सामान्य"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"ज़्यादा"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"क्या आपको डिवाइस का माइक्रोफ़ोन अनब्लॉक करना है?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"क्या आपको डिवाइस का कैमरा अनब्लॉक करना है?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"क्या आप डिवाइस का कैमरा और माइक्रोफ़ोन अनब्लॉक करना चाहते हैं?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"हटाएं"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"विजेट जोड़ें"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"हो गया"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"विजेट जोड़ें"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"अपने टैबलेट को अनलॉक किए बिना, अपने पसंदीदा ऐप्लिकेशन विजेट को तुरंत ऐक्सेस करें."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"लॉक स्क्रीन पर किसी भी विजेट को अनुमति देनी है?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"सेटिंग खोलें"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"वर्क ऐप्लिकेशन चालू करने हैं?"</string>
@@ -464,15 +475,15 @@
     <string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"रिकॉर्ड या कास्ट करते समय, इस सुविधा को उपलब्ध कराने वाली सेवा के पास आपकी स्क्रीन पर दिख रही जानकारी या डिवाइस पर चल रहे हर मीडिया का ऐक्सेस होता है. जैसे, पासवर्ड, पेमेंट के तरीके की जानकारी, फ़ोटो, मैसेज, और डिवाइस पर चल रहा ऑडियो."</string>
     <string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"पूरी स्क्रीन"</string>
     <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"सिर्फ़ एक ऐप्लिकेशन"</string>
-    <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"रिकॉर्ड या शेयर करने के लिए ऐप्लिकेशन चुनें"</string>
+    <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"ऐप्लिकेशन शेयर करें या उसकी रिकॉर्डिंग करें"</string>
     <string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"क्या <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> का इस्तेमाल करके रिकॉर्ड या कास्ट करना है?"</string>
     <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"शेयर, रिकॉर्ड या कास्ट करते समय, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> के पास स्क्रीन पर दिख रहे कॉन्टेंट या डिवाइस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, और डिवाइस पर चल रहे ऑडियो और वीडियो को लेकर सावधानी बरतें."</string>
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"किसी ऐप्लिकेशन को शेयर, रिकॉर्ड या कास्ट करते समय, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> के पास उस ऐप्लिकेशन पर दिख रहे कॉन्टेंट या उस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, और डिवाइस पर चल रहे ऑडियो और वीडियो को लेकर सावधानी बरतें."</string>
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"शुरू करें"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ने इस विकल्प को बंद कर दिया है"</string>
-    <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"क्या मीडिया कास्ट करना है?"</string>
+    <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"क्या कास्टिंग शुरू करनी है?"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"कास्ट करते समय, Android के पास स्क्रीन पर दिख रहे कॉन्टेंट या डिवाइस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, और डिवाइस पर चल रहे ऑडियो और वीडियो को लेकर सावधानी बरतें."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"किसी ऐप्लिकेशन को कास्ट करते समय, Android के पास उस ऐप्लिकेशन पर दिख रहे कॉन्टेंट या उस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, और डिवाइस पर चल रहे ऑडियो और वीडियो को लेकर सावधानी बरतें."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"जब किसी ऐप्लिकेशन को कास्ट किया जाता है, तब उस पर दिख रहे कॉन्टेंट या चल रहे हर मीडिया का ऐक्सेस Android के पास होता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, और डिवाइस पर चल रहे ऑडियो और वीडियो को लेकर आपको सावधानी बरतनी चाहिए."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"कास्ट करें"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"क्या मीडिया शेयर करना है?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"शेयर, रिकॉर्ड या कास्ट करते समय, Android के पास स्क्रीन पर दिख रहे कॉन्टेंट या डिवाइस पर चल रहे हर मीडिया का ऐक्सेस होता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, और डिवाइस पर चल रहे ऑडियो और वीडियो को लेकर सावधानी बरतें."</string>
@@ -574,7 +585,7 @@
     <string name="screen_pinning_exit" msgid="4553787518387346893">"ऐप्लिकेशन अनपिन किया गया"</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"कॉल करें"</string>
     <string name="stream_system" msgid="7663148785370565134">"सिस्‍टम"</string>
-    <string name="stream_ring" msgid="7550670036738697526">"घंटी बजाएं"</string>
+    <string name="stream_ring" msgid="7550670036738697526">"रिंग"</string>
     <string name="stream_music" msgid="2188224742361847580">"मीडिया"</string>
     <string name="stream_alarm" msgid="16058075093011694">"अलार्म"</string>
     <string name="stream_notification" msgid="7930294049046243939">"सूचना"</string>
@@ -585,9 +596,9 @@
     <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"वाइब्रेशन"</string>
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"आवाज़ बंद है"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"कास्ट करें"</string>
-    <string name="stream_notification_unavailable" msgid="4313854556205836435">"रिंग म्यूट होने से आवाज़ नहीं सुनाई दी"</string>
+    <string name="stream_notification_unavailable" msgid="4313854556205836435">"आवाज़ नहीं आएगी, क्योंकि रिंग म्यूट है"</string>
     <string name="stream_alarm_unavailable" msgid="4059817189292197839">"सुविधा बंद है, क्योंकि \'परेशान न करें\' मोड चालू है"</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"सुविधा बंद है, क्योंकि \'परेशान न करें\' मोड चालू है"</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"आवाज़ बंद है, क्योंकि \'परेशान न करें\' मोड चालू है"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. अनम्यूट करने के लिए टैप करें."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. कंपन पर सेट करने के लिए टैप करें. सुलभता सेवाएं म्यूट हो सकती हैं."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. म्यूट करने के लिए टैप करें. सुलभता सेवाएं म्यूट हो सकती हैं."</string>
@@ -595,9 +606,9 @@
     <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. म्यूट करने के लिए टैप करें."</string>
     <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"शोर को कंट्रोल करने की सुविधा"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"स्पेशल ऑडियो"</string>
-    <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"बंद करें"</string>
-    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"चालू करें"</string>
-    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"सिर हिलना ट्रैक करें"</string>
+    <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"बंद है"</string>
+    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"चालू है"</string>
+    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"हेड ट्रैकिंग चालू है"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"रिंगर मोड बदलने के लिए टैप करें"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"म्यूट करें"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"अनम्यूट करें"</string>
@@ -610,7 +621,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s को म्यूट करें"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s को अनम्यूट करें"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> को चलाया जा रहा है"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"ऑडियो इसमें चलेगा"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"ऑडियो इस पर चलेगा"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"सिस्टम यूज़र इंटरफ़ेस (यूआई) ट्यूनर"</string>
     <string name="status_bar" msgid="4357390266055077437">"स्टेटस बार"</string>
     <string name="demo_mode" msgid="263484519766901593">"सिस्टम यूज़र इंटरफ़ेस (यूआई) डेमो मोड"</string>
@@ -621,7 +632,7 @@
     <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
     <string name="wallet_empty_state_label" msgid="7776761245237530394">"फ़ोन के ज़रिए तेज़ी से और सुरक्षित तरीके से खरीदारी करने के लिए सेट अप करें"</string>
     <string name="wallet_app_button_label" msgid="7123784239111190992">"सभी दिखाएं"</string>
-    <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"अनलॉक करने के लिए टैप करें"</string>
+    <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"खोलने के लिए टैप करें"</string>
     <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"अपडेट हो रहा है"</string>
     <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"इस्तेमाल करने के लिए, डिवाइस अनलॉक करें"</string>
     <string name="wallet_error_generic" msgid="257704570182963611">"आपके कार्ड की जानकारी पाने में कोई समस्या हुई है. कृपया बाद में कोशिश करें"</string>
@@ -629,7 +640,7 @@
     <string name="qr_code_scanner_title" msgid="1938155688725760702">"क्यूआर कोड स्कैनर"</string>
     <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"अपडेट हो रहा है"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"वर्क प्रोफ़ाइल"</string>
-    <string name="status_bar_airplane" msgid="4848702508684541009">"हवाई जहाज़ मोड"</string>
+    <string name="status_bar_airplane" msgid="4848702508684541009">"फ़्लाइट मोड"</string>
     <string name="zen_alarm_warning" msgid="7844303238486849503">"आपको <xliff:g id="WHEN">%1$s</xliff:g> पर अपना अगला अलार्म नहीं सुनाई देगा"</string>
     <string name="alarm_template" msgid="2234991538018805736">"<xliff:g id="WHEN">%1$s</xliff:g> बजे"</string>
     <string name="alarm_template_far" msgid="3561752195856839456">"<xliff:g id="WHEN">%1$s</xliff:g> पर"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"स्प्लिट स्क्रीन का इस्तेमाल करके, मौजूदा ऐप्लिकेशन को दाईं ओर ले जाएं"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"स्प्लिट स्क्रीन का इस्तेमाल करके, मौजूदा ऐप्लिकेशन को बाईं ओर ले जाएं"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"स्प्लिट स्क्रीन से फ़ुल स्क्रीन मोड पर स्विच करने के लिए"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रीन इस्तेमाल करते समय दाईं ओर या नीचे के ऐप पर स्विच करें"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रीन इस्तेमाल करते समय बाईं ओर या ऊपर के ऐप पर स्विच करें"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रीन के दौरान: एक ऐप्लिकेशन को दूसरे ऐप्लिकेशन से बदलें"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"इनपुट"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"अगली भाषा पर स्विच करने के लिए"</string>
@@ -1177,7 +1186,7 @@
     <string name="see_all_networks" msgid="3773666844913168122">"सभी देखें"</string>
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"नेटवर्क बदलने के लिए, पहले ईथरनेट को डिसकनेक्ट करें"</string>
     <string name="wifi_scan_notify_message" msgid="3753839537448621794">"डिवाइस इस्तेमाल करने के अनुभव काे बेहतर बनाने के लिए, ऐप्लिकेशन और सेवाओं की मदद से, किसी भी समय वाई-फ़ाई नेटवर्क स्कैन किए जा सकते हैं. ऐसा वाई-फ़ाई बंद होने पर भी किया जा सकता है. वाई-फ़ाई स्कैनिंग की सेटिंग में जाकर, इसे बदला जा सकता है. "<annotation id="link">"बदलें"</annotation></string>
-    <string name="turn_off_airplane_mode" msgid="8425587763226548579">"हवाई जहाज़ मोड बंद करें"</string>
+    <string name="turn_off_airplane_mode" msgid="8425587763226548579">"फ़्लाइट मोड बंद करें"</string>
     <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> इस टाइल को \'फटाफट सेटिंग\' में जोड़ने के लिए अनुमति चाहता है"</string>
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"टाइल जोड़ें"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"टाइल न जोड़ें"</string>
diff --git a/packages/SystemUI/res/values-hi/tiles_states_strings.xml b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
index b49d3b9..0cb06c0 100644
--- a/packages/SystemUI/res/values-hi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"बंद है"</item>
     <item msgid="5137565285664080143">"चालू है"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index dde688c..a1d885a 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Izradu snimki zaslona blokirao je IT administrator"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Uredi"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Uređivanje snimke zaslona"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Podijelite"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Podijeli snimku zaslona"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Snimi više"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Odbacivanje snimke zaslona"</string>
@@ -106,8 +105,8 @@
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Obrada snimanja zaslona"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Tekuća obavijest za sesiju snimanja zaslona"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Želite li pokrenuti snimanje?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Dok snimate, Android ima pristup svemu što je vidljivo na vašem zaslonu ili se reproducira na vašem uređaju. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Dok snimate aplikaciju, Android ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Dok snimate, Android ima pristup svemu što je vidljivo na zaslonu ili se reproducira na uređaju. Stoga pazite na zaporke, podatke o plaćanju, poruke, fotografije te audio i videozapise."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Dok snimate aplikaciju, Android ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na zaporke, podatke o plaćanju, poruke, fotografije te audio i videozapise."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Pokreni snimanje"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Snimanje zvuka"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Zvuk na uređaju"</string>
@@ -142,7 +141,7 @@
     <string name="accessibility_accessibility_button" msgid="4089042473497107709">"Pristupačnost"</string>
     <string name="accessibility_rotate_button" msgid="1238584767612362586">"Zakretanje zaslona"</string>
     <string name="accessibility_recent" msgid="901641734769533575">"Pregled"</string>
-    <string name="accessibility_camera_button" msgid="2938898391716647247">"Fotoaparat"</string>
+    <string name="accessibility_camera_button" msgid="2938898391716647247">"Kamera"</string>
     <string name="accessibility_phone_button" msgid="4256353121703100427">"Telefon"</string>
     <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"Glasovna pomoć"</string>
     <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skeniranje lica"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošalji"</string>
     <string name="cancel" msgid="1089011503403416730">"Odustani"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logotip aplikacije"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdi"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Pokušaj ponovo"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Dodirnite da biste otkazali autentifikaciju"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Lice je prepoznato. Pritisnite ikonu otključavanja da biste nastavili."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikacija izvršena"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Otkaži autentifikaciju"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Više opcija"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Koristite PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Koristite uzorak"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Koristite zaporku"</string>
@@ -264,10 +265,10 @@
     <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Ne uznemiravaj"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Upareni uređaji nisu dostupni"</string>
-    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Dodirnite da biste povezali uređaj ili prekinuli vezu uređaja"</string>
-    <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Upari novi uređaj"</string>
+    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Dodirnite da biste povezali uređaj ili prekinuli vezu s njim"</string>
+    <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Uparite novi uređaj"</string>
     <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Pogledajte sve"</string>
-    <string name="turn_on_bluetooth" msgid="5681370462180289071">"Uključi"</string>
+    <string name="turn_on_bluetooth" msgid="5681370462180289071">"Koristi Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Povezano"</string>
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Spremljeno"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"prekini vezu"</string>
@@ -285,7 +286,7 @@
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Automatsko zakretanje zaslona"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Lokacija"</string>
     <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Čuvar zaslona"</string>
-    <string name="quick_settings_camera_label" msgid="5612076679385269339">"Pristup fotoaparatu"</string>
+    <string name="quick_settings_camera_label" msgid="5612076679385269339">"Pristup kameri"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Pristup mikrofonu"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Dostupno"</string>
     <string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Blokirano"</string>
@@ -293,7 +294,7 @@
     <string name="quick_settings_user_title" msgid="8673045967216204537">"Korisnik"</string>
     <string name="quick_settings_wifi_label" msgid="2879507532983487244">"Wi-Fi"</string>
     <string name="quick_settings_internet_label" msgid="6603068555872455463">"Internet"</string>
-    <string name="quick_settings_networks_available" msgid="1875138606855420438">"Mreže su dostupne"</string>
+    <string name="quick_settings_networks_available" msgid="1875138606855420438">"Dostupne su mreže"</string>
     <string name="quick_settings_networks_unavailable" msgid="1167847013337940082">"Mreže nisu dostupne"</string>
     <string name="quick_settings_wifi_detail_empty_text" msgid="483130889414601732">"Nije dostupna nijedna Wi-Fi mreža"</string>
     <string name="quick_settings_wifi_secondary_label_transient" msgid="7501659015509357887">"Uključivanje…"</string>
@@ -347,7 +348,7 @@
     <string name="quick_settings_screen_record_start" msgid="1574725369331638985">"Početak"</string>
     <string name="quick_settings_screen_record_stop" msgid="8087348522976412119">"Zaustavi"</string>
     <string name="qs_record_issue_label" msgid="8166290137285529059">"Zabilježi poteškoću"</string>
-    <string name="qs_record_issue_start" msgid="2979831312582567056">"Početak"</string>
+    <string name="qs_record_issue_start" msgid="2979831312582567056">"Pokreni"</string>
     <string name="qs_record_issue_stop" msgid="3531747965741982657">"Zaustavi"</string>
     <string name="qs_record_issue_dropdown_header" msgid="5995983175678658329">"Na koji dio doživljaja na uređaju to utjecalo?"</string>
     <string name="qs_record_issue_dropdown_prompt" msgid="2526949919167046219">"Odaberite vrstu problema"</string>
@@ -362,12 +363,20 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standardni"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Srednji"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Visoki"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite li deblokirati mikrofon uređaja?"</string>
-    <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite li deblokirati fotoaparat uređaja?"</string>
-    <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite li deblokirati fotoaparat i mikrofon uređaja?"</string>
+    <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite li deblokirati kameru uređaja?"</string>
+    <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite li deblokirati kameru i mikrofon uređaja?"</string>
     <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Time se deblokira pristup za sve aplikacije i usluge kojima je dopuštena upotreba vašeg mikrofona."</string>
-    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Time se deblokira pristup za sve aplikacije i usluge kojima je dopuštena upotreba vašeg fotoaparata."</string>
-    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Time se deblokira pristup za sve aplikacije i usluge kojima je dopuštena upotreba vašeg fotoaparata ili mikrofona."</string>
+    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Time se deblokira pristup za sve aplikacije i usluge kojima je dopuštena upotreba vaše kamere."</string>
+    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Time se deblokira pristup za sve aplikacije i usluge kojima je dopuštena upotreba vaše kamere ili mikrofona."</string>
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Mikrofon je blokiran"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Kamera je blokirana"</string>
     <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"Mikrofon i kamera su blokirani"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Ukloni"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodaj widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Gotovo"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Dodaj widgete"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Brzo pristupajte widgetima omiljenih aplikacija bez otključavanja tableta."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Želite li dopustiti bilo koji widget na zaključanom zaslonu?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Otvori postavke"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Pokrenuti poslovne aplikacije?"</string>
@@ -466,17 +477,17 @@
     <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Jedna aplikacija"</string>
     <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Dijeljenje ili snimanje aplikacije"</string>
     <string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Želite li započeti snimanje ili emitiranje pomoću aplikacije <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
-    <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kad dijelite, snimate ili emitirate, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što je vidljivo na vašem zaslonu ili se reproducira na vašem uređaju. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
-    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Kad dijelite, snimate ili emitirate aplikaciju, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kad dijelite, snimate ili emitirate, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što je vidljivo na zaslonu ili se reproducira na uređaju. Stoga pazite na zaporke, podatke o plaćanju, poruke, fotografije te audio i videozapise."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Kad dijelite, snimate ili emitirate aplikaciju, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na zaporke, podatke o plaćanju, poruke, fotografije te audio i videozapise."</string>
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Pokreni"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> onemogućila je ovu opciju"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Želite li pokrenuti emitiranje?"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Kad emitirate, Android ima pristup svemu što je vidljivo na vašem zaslonu ili se reproducira na vašem uređaju. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Kad emitirate aplikaciju, Android ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Kad emitirate, Android ima pristup svemu što je vidljivo na zaslonu ili se reproducira na uređaju. Stoga pazite na zaporke, podatke o plaćanju, poruke, fotografije te audio i videozapise."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Kad emitirate aplikaciju, Android ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na zaporke, podatke o plaćanju, poruke, fotografije te audio i videozapise."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Pokreni emitiranje"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Želite li pokrenuti dijeljenje?"</string>
-    <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Kad dijelite, snimate ili emitirate, Android ima pristup svemu što je vidljivo na vašem zaslonu ili se reproducira na vašem uređaju. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
-    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Kad dijelite, snimate ili emitirate aplikaciju, Android ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Kad dijelite, snimate ili emitirate, Android ima pristup svemu što je vidljivo na zaslonu ili se reproducira na uređaju. Stoga pazite na zaporke, podatke o plaćanju, poruke, fotografije te audio i videozapise."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Kad dijelite, snimate ili emitirate aplikaciju, Android ima pristup svemu što se prikazuje ili reproducira u toj aplikaciji. Stoga pazite na zaporke, podatke o plaćanju, poruke, fotografije te audio i videozapise."</string>
     <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Pokreni"</string>
     <string name="media_projection_task_switcher_text" msgid="590885489897412359">"Dijeljenje pauza tijekom prebacivanja aplikacija"</string>
     <string name="media_projection_task_switcher_action_switch" msgid="8682258717291921123">"Umjesto toga podijelite ovu aplikaciju"</string>
@@ -596,7 +607,7 @@
     <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Kontrola buke"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Prostorni zvuk"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Isključeno"</string>
-    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Otklonjeno"</string>
+    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fiksno"</string>
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Praćenje glave"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Dodirnite da biste promijenili način softvera zvona"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"isključivanje zvuka"</string>
@@ -658,7 +669,7 @@
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatski"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Bez zvuka ili vibracije"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Bez zvuka ili vibracije i prikazuje se pri dnu odjeljka razgovora"</string>
-    <string name="notification_channel_summary_default" msgid="777294388712200605">"Možda će zvoniti ili vibrirati, ovisno o postavkama uređaja"</string>
+    <string name="notification_channel_summary_default" msgid="777294388712200605">"Može zvoniti ili vibrirati ovisno o postavkama uređaja"</string>
     <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Možda će zvoniti ili vibrirati, ovisno o postavkama uređaja. Razgovori iz aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> prikazuju se u oblačiću prema zadanim postavkama."</string>
     <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Neka sustav odredi treba li obavijest najaviti zvukom ili vibracijom"</string>
     <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"&lt;b&gt;Status:&lt;/b&gt; promaknuta u zadanu"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Otvori podijeljeni zaslon s trenutačnom aplikacijom s desne strane"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Otvori podijeljeni zaslon s trenutačnom aplikacijom s lijeve strane"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Prijeđi s podijeljenog zaslona na cijeli zaslon"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prijeđite na aplikaciju zdesna ili ispod uz podijeljeni zaslon"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Prijeđite na aplikaciju slijeva ili iznad uz podijeljeni zaslon"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Tijekom podijeljenog zaslona: zamijeni aplikaciju drugom"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Unos"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Prijeđi na sljedeći jezik"</string>
@@ -935,7 +944,7 @@
     <string name="ongoing_privacy_dialog_attribution_text" msgid="4738795925380373994">"(putem apl. <xliff:g id="APPLICATION_NAME_S_">%s</xliff:g>)"</string>
     <string name="ongoing_privacy_dialog_attribution_label" msgid="3385241594101496292">"(<xliff:g id="ATTRIBUTION_LABEL">%s</xliff:g>)"</string>
     <string name="ongoing_privacy_dialog_attribution_proxy_label" msgid="1111829599659403249">"(<xliff:g id="ATTRIBUTION_LABEL">%1$s</xliff:g> • <xliff:g id="PROXY_LABEL">%2$s</xliff:g>)"</string>
-    <string name="privacy_type_camera" msgid="7974051382167078332">"fotoaparat"</string>
+    <string name="privacy_type_camera" msgid="7974051382167078332">"kamera"</string>
     <string name="privacy_type_location" msgid="7991481648444066703">"lokaciju"</string>
     <string name="privacy_type_microphone" msgid="9136763906797732428">"mikrofon"</string>
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"snimanje zaslona"</string>
@@ -1238,7 +1247,7 @@
     <string name="home_quick_affordance_unavailable_configure_the_app" msgid="604424593994493281">"• Dostupan je najmanje jedan uređaj ili ploča uređaja"</string>
     <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Odaberite zadanu aplikaciju za bilješke da biste koristili prečac za pisanje bilježaka"</string>
     <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Odaberite aplikaciju"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Prečac za dodirnuti i zadržati"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Dodirnite i zadržite prečac"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Odustani"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Promijenite zaslon odmah"</string>
     <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Otklopite telefon"</string>
@@ -1259,7 +1268,7 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Prijeđite na poslovni profil"</string>
     <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instaliraj poslovnu aplikaciju telefona"</string>
     <string name="call_from_work_profile_close" msgid="5830072964434474143">"Odustani"</string>
-    <string name="lock_screen_settings" msgid="6152703934761402399">"Prilagodi zaključavanje zaslona"</string>
+    <string name="lock_screen_settings" msgid="6152703934761402399">"Prilagodite zaključavanje zaslona"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Otključajte da biste prilagodili zaključani zaslon"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi nije dostupan"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Kamera je blokirana"</string>
diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
index 75fb325..e09cab5 100644
--- a/packages/SystemUI/res/values-hr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Isključeno"</item>
     <item msgid="5137565285664080143">"Uključeno"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 8b32095..baea240 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"A képernyőkép készítésének lehetőségét a rendszergazda letiltotta"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Szerkesztés"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Képernyőkép szerkesztése"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Megosztás"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Képernyőkép megosztása"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Több rögzítése"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Képernyőkép elvetése"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Arc keresése"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Küldés"</string>
     <string name="cancel" msgid="1089011503403416730">"Mégse"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Alkalmazás emblémája"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Megerősítés"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Újrapróbálkozás"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Koppintson a hitelesítés visszavonásához"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Arc felismerve. A folytatáshoz koppintson a Feloldásra."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Hitelesítve"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Hitelesítés megszakítása"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"További lehetőségek"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN-kód használata"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Minta használata"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Jelszó használata"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Normál"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Közepes"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Nagy"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Feloldja az eszköz mikrofonjának letiltását?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Feloldja az eszköz kamerájának letiltását?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Feloldja az eszköz kamerájának és mikrofonjának letiltását?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Eltávolítás"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Modul hozzáadása"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Kész"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Modulok hozzáadása"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Táblagépe feloldása nélkül, gyorsan hozzáférhet kedvenc alkalmazásmoduljaihoz."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Minden modult engedélyez a lezárási képernyőn?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Beállítások megnyitása"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Feloldja a munkahelyi appokat?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Az eszközt a szülőd felügyeli. A szülőd megtekintheti és kezelheti például a használt alkalmazásokra, a tartózkodási helyre és a képernyőidőre vonatkozó adatokat."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Feloldva tartva TrustAgent által"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Az eszköz túl sok hitelesítési kísérlet miatt zárolva lett."</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Eszköz zárolva\nSikertelen hitelesítés"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Hangbeállítások"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatikus feliratozás"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Osztott képernyő aktiválása; az aktuális alkalmazás kerüljön jobbra"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Osztott képernyő aktiválása; az aktuális alkalmazás kerüljön balra"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Váltás osztott képernyőről teljes képernyőre"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Váltás a jobb oldalt, illetve lent lévő appra osztott képernyő esetén"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Váltás a bal oldalt, illetve fent lévő appra osztott képernyő esetén"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Osztott képernyőn: az egyik alkalmazás lecserélése egy másikra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Bevitel"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Váltás a következő nyelvre"</string>
diff --git a/packages/SystemUI/res/values-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
index 3ca3914..8f75dc6 100644
--- a/packages/SystemUI/res/values-hu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Ki"</item>
     <item msgid="5137565285664080143">"Be"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 8151686..3f88746 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Ձեր ՏՏ ադմինիստրատորն արգելափակել է սքրինշոթներ անելու հնարավորությունը"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Փոփոխել"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Փոփոխել սքրինշոթը"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Կիսվել"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Ուղարկել սքրինշոթ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Մեծացնել սքրինշոթի տարածքը"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Փակել սքրինշոթը"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Դեմքի սկանավորում"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Ուղարկել"</string>
     <string name="cancel" msgid="1089011503403416730">"Չեղարկել"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Հավելվածի լոգո"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Հաստատել"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Նորից փորձել"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Հպեք՝ նույնականացումը չեղարկելու համար"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Դեմքը ճանաչվեց։ Սեղմեք ապակողպման պատկերակը։"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Նույնականացված է"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Չեղարկել իսկորոշումը"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Լրացուցիչ ընտրանքներ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Օգտագործել PIN կոդ"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Օգտագործել նախշ"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Օգտագործել գաղտնաբառ"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Սովորական"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Միջին"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Բարձր"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Արգելահանե՞լ սարքի խոսափողը"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Արգելահանե՞լ սարքի տեսախցիկը"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Արգելահանե՞լ սարքի տեսախցիկը և խոսափողը"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Հեռացնել"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Ավելացնել վիջեթ"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Պատրաստ է"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Ավելացնել վիջեթներ"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Արագ բացեք հավելվածների ձեր սիրելի վիջեթները առանց ապակողպելու պլանշետը։"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Թույլատրե՞լ վիջեթների ցուցադրումը կողպէկրանին"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Բացել կարգավորումները"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Վերսկսե՞լ աշխ. հավելվածները"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Միացնել էկրանի տրոհումը՝ ընթացիկ հավելվածն աջ կողմում"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Միացնել էկրանի տրոհումը՝ ընթացիկ հավելվածը ձախ կողմում"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Տրոհված էկրանից անցնել լիաէկրան ռեժիմ"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Անցեք աջ կողմի կամ ներքևի հավելվածին տրոհված էկրանի միջոցով"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Անցեք աջ կողմի կամ վերևի հավելվածին տրոհված էկրանի միջոցով"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Տրոհված էկրանի ռեժիմում մեկ հավելվածը փոխարինել մյուսով"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Ներածում"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Անցնել հաջորդ լեզվին"</string>
diff --git a/packages/SystemUI/res/values-hy/tiles_states_strings.xml b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
index 89a94e8..118915d 100644
--- a/packages/SystemUI/res/values-hy/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Անջատված է"</item>
     <item msgid="5137565285664080143">"Միացված է"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 565eaff..0b07a32 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Mengambil screenshot diblokir oleh admin IT Anda"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Mengedit screenshot"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Bagikan"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Bagikan screenshot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Ambil screenshot lagi"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Menutup screenshot"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Memindai wajah"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Kirim"</string>
     <string name="cancel" msgid="1089011503403416730">"Batal"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logo aplikasi"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Konfirmasi"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Coba lagi"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Ketuk untuk membatalkan autentikasi"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Wajah dikenali. Tekan ikon buka kunci untuk melanjutkan."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Diautentikasi"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Batalkan Autentikasi"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Opsi Lainnya"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gunakan PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gunakan pola"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Gunakan sandi"</string>
@@ -264,7 +265,7 @@
     <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Jangan Ganggu"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Perangkat yang disandingkan tak tersedia"</string>
-    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Ketuk untuk menghubungkan atau memutuskan koneksi perangkat"</string>
+    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Ketuk untuk memulai atau menghentikan koneksi perangkat"</string>
     <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Sambungkan perangkat baru"</string>
     <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Lihat semua"</string>
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Gunakan Bluetooth"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standar"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Sedang"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Tinggi"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Berhenti memblokir mikrofon perangkat?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Berhenti memblokir kamera perangkat?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Berhenti memblokir kamera dan mikrofon perangkat?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Hapus"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Tambahkan widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Selesai"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Tambahkan widget"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Dapatkan akses cepat ke widget aplikasi favorit Anda tanpa perlu membuka kunci tablet."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Izinkan widget di layar kunci?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Buka setelan"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Batalkan jeda aplikasi kerja?"</string>
@@ -470,10 +481,10 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Jika Anda membagikan, merekam, atau mentransmisikan suatu aplikasi, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> akan memiliki akses ke semua hal yang ditampilkan atau yang diputar di aplikasi tersebut. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio dan video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Mulai"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> telah menonaktifkan opsi ini"</string>
-    <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Mulai mentransmisikan?"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Jika mentransmisikan, Android akan memiliki akses ke semua hal yang ditampilkan di layar atau yang diputar di perangkat Anda. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
+    <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Mulai transmisi?"</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Jika Anda melakukan transmisi, Android akan memiliki akses ke semua hal yang ditampilkan di layar atau yang diputar di perangkat Anda. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Jika Anda mentransmisikan aplikasi, Android akan memiliki akses ke semua hal yang ditampilkan atau yang diputar di aplikasi tersebut. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
-    <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Mulai mentransmisikan"</string>
+    <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Mulai transmisi"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Mulai berbagi?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Jika Anda membagikan, merekam, atau mentransmisikan, Android akan memiliki akses ke semua hal yang ditampilkan di layar atau yang diputar di perangkat Anda. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Jika Anda membagikan, merekam, atau mentransmisikan suatu aplikasi, Android akan memiliki akses ke semua hal yang ditampilkan atau yang diputar di aplikasi tersebut. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Perangkat ini dikelola oleh orang tuamu. Orang tuamu bisa melihat dan mengelola berbagai informasi, seperti aplikasi yang kamu gunakan, lokasimu, dan lama pemakaian perangkat."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Tetap terbuka kuncinya oleh TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Perangkat dikunci, terlalu banyak upaya autentikasi"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Perangkat dikunci\nAutentikasi gagal"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Setelan suara"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Otomatis beri teks di media"</string>
@@ -587,9 +596,9 @@
     <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Getar"</string>
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Nonaktifkan"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"Transmisi"</string>
-    <string name="stream_notification_unavailable" msgid="4313854556205836435">"Tidak tersedia karena volume dering dibisukan"</string>
-    <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Tidak tersedia karena fitur Jangan Ganggu aktif"</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"Tidak tersedia karena fitur Jangan Ganggu aktif"</string>
+    <string name="stream_notification_unavailable" msgid="4313854556205836435">"Tidak tersedia - Volume dering dibisukan"</string>
+    <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Tidak tersedia - Fitur Jangan Ganggu aktif"</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"Tidak tersedia - Fitur Jangan Ganggu aktif"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Ketuk untuk menyuarakan."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Ketuk untuk menyetel agar bergetar. Layanan aksesibilitas mungkin dibisukan."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Ketuk untuk membisukan. Layanan aksesibilitas mungkin dibisukan."</string>
@@ -667,10 +676,10 @@
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Status:&lt;/b&gt; Didemosikan menjadi Senyap"</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Status:&lt;/b&gt; Diberi Peringkat Lebih Tinggi"</string>
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Status:&lt;/b&gt; Diberi Peringkat Lebih Rendah"</string>
-    <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Muncul di atas notifikasi percakapan dan sebagai foto profil di layar kunci"</string>
-    <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Muncul di atas notifikasi percakapan dan sebagai foto profil di layar kunci, ditampilkan sebagai balon"</string>
-    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Muncul di atas notifikasi percakapan dan sebagai foto profil di layar kunci, mengganggu mode Jangan Ganggu"</string>
-    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Muncul di atas notifikasi percakapan dan sebagai foto profil di layar kunci, ditampilkan sebagai balon, mengganggu mode Jangan Ganggu"</string>
+    <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Muncul teratas di notifikasi percakapan dan sebagai foto profil di layar kunci"</string>
+    <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Muncul teratas di notifikasi percakapan dan sebagai foto profil di layar kunci, ditampilkan sebagai balon"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Muncul teratas di notifikasi percakapan dan sebagai foto profil di layar kunci, menimpa mode Jangan Ganggu"</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Muncul teratas di notifikasi percakapan dan sebagai foto profil di layar kunci, ditampilkan sebagai balon, menimpa mode Jangan Ganggu"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Prioritas"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak mendukung fitur percakapan"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Notifikasi ini tidak dapat diubah."</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Masuk ke layar terpisah dengan aplikasi saat ini ke RHS"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Masuk ke layar terpisah dengan aplikasi saat ini ke LHS"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Beralih dari layar terpisah ke layar penuh"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Beralih ke aplikasi di bagian kanan atau bawah saat menggunakan layar terpisah"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Beralih ke aplikasi di bagian kiri atau atas saat menggunakan layar terpisah"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Dalam layar terpisah: ganti salah satu aplikasi dengan yang lain"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Beralih ke bahasa berikutnya"</string>
@@ -1118,7 +1125,7 @@
     <string name="basic_status" msgid="2315371112182658176">"Membuka percakapan"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Widget Percakapan"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Ketuk percakapan untuk menambahkannya ke Layar utama"</string>
-    <string name="no_conversations_text" msgid="5354115541282395015">"Percakapan terbaru Anda akan ditampilkan di sini"</string>
+    <string name="no_conversations_text" msgid="5354115541282395015">"Percakapan terbaru akan muncul di sini"</string>
     <string name="priority_conversations" msgid="3967482288896653039">"Percakapan prioritas"</string>
     <string name="recent_conversations" msgid="8531874684782574622">"Percakapan terbaru"</string>
     <string name="days_timestamp" msgid="5821854736213214331">"<xliff:g id="DURATION">%1$s</xliff:g> hari lalu"</string>
diff --git a/packages/SystemUI/res/values-in/tiles_states_strings.xml b/packages/SystemUI/res/values-in/tiles_states_strings.xml
index e1d5338..bd429c1 100644
--- a/packages/SystemUI/res/values-in/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-in/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Nonaktif"</item>
     <item msgid="5137565285664080143">"Aktif"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 149ba55..56ea0d5 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Kerfisstjórinn lokaði á skjámyndatöku"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Breyta"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Breyta skjámynd"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Deila"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Deila skjámynd"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Mynda meira"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Loka skjámynd"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Andlit skannað"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Senda"</string>
     <string name="cancel" msgid="1089011503403416730">"Hætta við"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Lógó forrits"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Staðfesta"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Reyna aftur"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Ýttu til að hætta við auðkenningu"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Andlitið var greint. Ýttu á opnunartáknið til að halda áfr."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Auðkennt"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Hætta við auðkenningu"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Fleiri valkostir"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Nota PIN-númer"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Nota mynstur"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Nota aðgangsorð"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Staðlað"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Miðlungs"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Mikið"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Opna fyrir hljóðnema tækisins?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Opna fyrir myndavél tækisins?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Opna fyrir myndavél og hljóðnema tækisins?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Fjarlægja"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Bæta græju við"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Lokið"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Bæta við græjum"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Fáðu skjótan aðgang að eftirlætis forritagræjunum án þess að taka spjaldtölvuna úr lás."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Leyfa allar græjur á lásskjá?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Opna stillingar"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Ljúka hléi vinnuforrita?"</string>
@@ -586,8 +597,8 @@
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Hljóð af"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"Senda út"</string>
     <string name="stream_notification_unavailable" msgid="4313854556205836435">"Ekki í boði þar sem hringing er þögguð"</string>
-    <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Ekki í boði vegna þess að kveikt er á „Ónáðið ekki“"</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"Ekki í boði vegna þess að kveikt er á „Ónáðið ekki“"</string>
+    <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Ekki í boði því að kveikt er á „Ónáðið ekki“"</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"Ekki í boði því að kveikt er á „Ónáðið ekki“"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Ýttu til að hætta að þagga."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Ýttu til að stilla á titring. Hugsanlega verður slökkt á hljóði aðgengisþjónustu."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Ýttu til að þagga. Hugsanlega verður slökkt á hljóði aðgengisþjónustu."</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Opna skjáskiptingu hægra megin með núverandi forriti"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Opna skjáskiptingu vinstra megin með núverandi forriti"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Skipta úr skjáskiptingu yfir á allan skjáinn"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skiptu í forrit til hægri eða fyrir neðan þegar skjáskipting er notuð"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skiptu í forrit til vinstri eða fyrir ofan þegar skjáskipting er notuð"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Í skjáskiptingu: Skipta forriti út fyrir annað forrit"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Innsláttur"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Skipta yfir í næsta tungumál"</string>
diff --git a/packages/SystemUI/res/values-is/tiles_states_strings.xml b/packages/SystemUI/res/values-is/tiles_states_strings.xml
index 1bd38ba..abdc3e7 100644
--- a/packages/SystemUI/res/values-is/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-is/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Slökkt"</item>
     <item msgid="5137565285664080143">"Kveikt"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index f701787..08f07ef 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"L\'acquisizione di screenshot è stata bloccata dall\'amministratore IT"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Modifica"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Modifica screenshot"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Condividi"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Condividi screenshot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Acquisisci di più"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ignora screenshot"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scansione del viso"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Invia"</string>
     <string name="cancel" msgid="1089011503403416730">"Annulla"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logo dell\'app"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Conferma"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Riprova"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Tocca per annullare l\'autenticazione"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Volto riconosciuto. Premi l\'icona Sblocca e continua."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticazione eseguita"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Annulla autenticazione"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Altre opzioni"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Utilizza PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usa sequenza"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Utilizza password"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Medio"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Alto"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Apparecchi acustici"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vuoi sbloccare il microfono del dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vuoi sbloccare la fotocamera del dispositivo?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vuoi sbloccare la fotocamera e il microfono del dispositivo?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Rimuovi"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Aggiungi widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Fine"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Aggiungi widget"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Accedi rapidamente ai widget delle tue app preferite senza sbloccare il tablet."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Consentire tutti i widget nella schermata di blocco?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Apri impostazioni"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Riattivare le app di lavoro?"</string>
@@ -540,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Questo dispositivo è gestito da uno dei tuoi genitori, il quale può visualizzare e gestire informazioni come le app che usi, la tua posizione e il tuo tempo di utilizzo."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Sbloccato da TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Dispositivo bloccato, troppi tentativi di autenticazione"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Dispositivo bloccato\nAutenticazione non riuscita"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Impostazioni audio"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Sottotitoli automatici"</string>
@@ -577,7 +585,7 @@
     <string name="stream_voice_call" msgid="7468348170702375660">"Chiamata"</string>
     <string name="stream_system" msgid="7663148785370565134">"Sistema"</string>
     <string name="stream_ring" msgid="7550670036738697526">"Suoneria"</string>
-    <string name="stream_music" msgid="2188224742361847580">"Supporti multimediali"</string>
+    <string name="stream_music" msgid="2188224742361847580">"Contenuti multimediali"</string>
     <string name="stream_alarm" msgid="16058075093011694">"Sveglia"</string>
     <string name="stream_notification" msgid="7930294049046243939">"Notifica"</string>
     <string name="stream_bluetooth_sco" msgid="6234562365528664331">"Bluetooth"</string>
@@ -589,7 +597,7 @@
     <string name="media_device_cast" msgid="4786241789687569892">"Trasmissione"</string>
     <string name="stream_notification_unavailable" msgid="4313854556205836435">"Non disponibile con l\'audio disattivato"</string>
     <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Non disponibile: modalità Non disturbare attiva"</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"Non disponibile: modalità Non disturbare attiva"</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"Non disponibili con \"Non disturbare\" attiva"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Tocca per riattivare l\'audio."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Tocca per attivare la vibrazione. L\'audio dei servizi di accessibilità può essere disattivato."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Tocca per disattivare l\'audio. L\'audio dei servizi di accessibilità può essere disattivato."</string>
@@ -765,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Attiva lo schermo diviso con l\'app corrente a destra"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Attiva lo schermo diviso con l\'app corrente a sinistra"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Passa da schermo diviso a schermo intero"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passa all\'app a destra o sotto mentre usi lo schermo diviso"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passa all\'app a sinistra o sopra mentre usi lo schermo diviso"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Con lo schermo diviso: sostituisci un\'app con un\'altra"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Inserimento"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Passa alla lingua successiva"</string>
diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml
index f7abea5..aa76983 100644
--- a/packages/SystemUI/res/values-it/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"Off"</item>
     <item msgid="5137565285664080143">"On"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"Non disponibile"</item>
+    <item msgid="3079622119444911877">"Off"</item>
+    <item msgid="3028994095749238254">"On"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 414f347..24ec785 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"‏יצירת צילומי המסך נחסמה על ידי מנהל ה-IT"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"עריכה"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"עריכת צילום מסך"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"שיתוף"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"שיתוף של צילום מסך"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"צילום תוכן נוסף"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"סגירת צילום מסך"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"סורק פנים"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"שליחה"</string>
     <string name="cancel" msgid="1089011503403416730">"ביטול"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"לוגו של האפליקציה"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"אישור"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ניסיון נוסף"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"יש להקיש כדי לבטל את האימות"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"הפנים זוהו. להמשך יש ללחוץ על סמל ביטול הנעילה."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"מאומת"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ביטול האימות"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"אפשרויות נוספות"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"שימוש בקוד אימות"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"שימוש בקו ביטול נעילה"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"שימוש בסיסמה"</string>
@@ -328,7 +329,7 @@
     <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"אפליקציות לעבודה"</string>
     <string name="quick_settings_work_mode_paused_state" msgid="6681788236383735976">"בהשהיה"</string>
     <string name="quick_settings_night_display_label" msgid="8180030659141778180">"תאורת לילה"</string>
-    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"התכונה מופעלת בשקיעה"</string>
+    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"מופעלת בשקיעה"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"עד הזריחה"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"תופעל בשעה <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"עד <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"רגילה"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"בינונית"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"גבוהה"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"לבטל את חסימת המיקרופון של המכשיר?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"לבטל את חסימת המצלמה של המכשיר?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"לבטל את חסימת המצלמה והמיקרופון של המכשיר?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"הסרה"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"הוספת ווידג\'ט"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"סיום"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"הוספת ווידג\'טים"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"קבלת גישה מהירה לווידג\'טים של האפליקציות המועדפות עליך בלי לבטל את נעילת הטאבלט."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"לאפשר להציג כל ווידג\'ט במסך הנעילה?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"לפתיחת ההגדרות"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"להפעיל את האפליקציות לעבודה?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"מכשיר זה מנוהל על ידי ההורה שלך. להורה שלך יש אפשרות לצפות בפרטים כמו האפליקציות שבשימוש, המיקום וזמן המסך שלך, ולנהל אותם."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"הנעילה נמנעת על ידי סביבה מהימנה"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"המכשיר ננעל, יותר מדי ניסיונות אימות"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"המכשיר ננעל\nהאימות נכשל"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>‏. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"הגדרות צליל"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"הוספת כתוביות באופן אוטומטי למדיה"</string>
@@ -595,7 +604,7 @@
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"‏%1$s. יש להקיש כדי להשתיק. ייתכן ששירותי הנגישות יושתקו."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"‏%1$s. יש להקיש כדי להעביר למצב רטט."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"‏%1$s. יש להקיש כדי להשתיק."</string>
-    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"בקרת הרעש"</string>
+    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"בקרת רעש"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"אודיו מרחבי"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"השבתה"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"מצב קבוע"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"‏כניסה למסך מפוצל עם האפליקציה הנוכחית ל-RHS"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"‏כניסה למסך מפוצל עם האפליקציה הנוכחית ל-LHS"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"החלפה ממסך מפוצל למסך מלא"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"מעבר לאפליקציה משמאל או למטה בזמן שימוש במסך מפוצל"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"מעבר לאפליקציה מימין או למעלה בזמן שימוש במסך מפוצל"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"כשהמסך מפוצל: החלפה בין אפליקציה אחת לאחרת"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"קלט"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"מעבר לשפה הבאה"</string>
diff --git a/packages/SystemUI/res/values-iw/tiles_states_strings.xml b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
index 1948685..196a6c2 100644
--- a/packages/SystemUI/res/values-iw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"מושבת"</item>
     <item msgid="5137565285664080143">"מופעל"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 78f1df2..6e2ca40 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"スクリーンショットの撮影は IT 管理者によってブロックされています。"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"編集"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"スクリーンショットを編集します"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"共有"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"スクリーンショットを共有"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"キャプチャ範囲を拡大"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"スクリーンショットを閉じます"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"顔のスキャン"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"送信"</string>
     <string name="cancel" msgid="1089011503403416730">"キャンセル"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"アプリのロゴ"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"確認"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"再試行"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"タップすると認証をキャンセルします"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"顔を認識しました。ロック解除アイコンを押して続行します。"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"認証済み"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"認証をキャンセルします"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"その他のオプション"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN を使用"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"パターンを使用"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"パスワードを使用"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"標準"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"中"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"高"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"補聴器"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"デバイスのマイクのブロックを解除しますか?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"デバイスのカメラのブロックを解除しますか?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"デバイスのカメラとマイクのブロックを解除しますか?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"削除"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ウィジェットを追加"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"完了"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"ウィジェットを追加"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"タブレットのロックを解除せずにお気に入りのアプリ ウィジェットにすばやくアクセスできます。"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"ロック画面でのウィジェットを許可しますか?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"設定を開く"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"仕事用アプリの停止解除"</string>
@@ -470,7 +480,7 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"アプリの共有、録画、キャスト中は、そのアプリで表示または再生される内容に <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> がアクセスできるため、パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"開始"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> がこのオプションを無効にしています"</string>
-    <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"キャスト開始しますか?"</string>
+    <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"キャストを開始しますか?"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"キャスト中は、画面に表示される内容やデバイスで再生される内容に Android がアクセスできるため、パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"アプリのキャスト中は、そのアプリで表示または再生される内容に Android がアクセスできるため、パスワード、お支払いの詳細、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"キャストを開始"</string>
@@ -609,8 +619,8 @@
     <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"音量スライダーを閉じました"</string>
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s をミュート"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s のミュートを解除"</string>
-    <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> を再生:"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"音声の再生形式:"</string>
+    <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> の再生先:"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"音声の再生先"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"システムUI調整ツール"</string>
     <string name="status_bar" msgid="4357390266055077437">"ステータスバー"</string>
     <string name="demo_mode" msgid="263484519766901593">"システム UI デモモード"</string>
@@ -656,7 +666,7 @@
     <string name="notification_silence_title" msgid="8608090968400832335">"サイレント"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"デフォルト"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string>
-    <string name="notification_channel_summary_low" msgid="4860617986908931158">"着信音もバイブレーションも無効になります"</string>
+    <string name="notification_channel_summary_low" msgid="4860617986908931158">"着信音もバイブレーションも OFF になります"</string>
     <string name="notification_conversation_summary_low" msgid="1734433426085468009">"着信音もバイブレーションも無効になり会話セクションの下に表示されます"</string>
     <string name="notification_channel_summary_default" msgid="777294388712200605">"デバイスの設定を基に着信音またはバイブレーションが有効になります"</string>
     <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"デバイスの設定を基に着信音またはバイブレーションが有効になります。デフォルトでは <xliff:g id="APP_NAME">%1$s</xliff:g> からの会話がふきだしで表示されます。"</string>
@@ -763,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"分割画面にして現在のアプリを右側に設定する"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"分割画面にして現在のアプリを左側に設定する"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"分割画面から全画面に切り替える"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"分割画面の使用時に右側または下部のアプリに切り替える"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"分割画面の使用時に左側または上部のアプリに切り替える"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"分割画面中: アプリを順に置換する"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"入力"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"次の言語に切り替える"</string>
diff --git a/packages/SystemUI/res/values-ja/tiles_states_strings.xml b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
index dd78c5e..790445c 100644
--- a/packages/SystemUI/res/values-ja/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"OFF"</item>
     <item msgid="5137565285664080143">"ON"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"使用不可"</item>
+    <item msgid="3079622119444911877">"OFF"</item>
+    <item msgid="3028994095749238254">"ON"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 64478d7..b2295f3 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ეკრანის ანაბეჭდის გადაღება დაბლოკილია თქვენი IT ადმინისტრატორის მიერ"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"რედაქტირება"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"ეკრანის ანაბეჭდის რედაქტირება"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"გაზიარება"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"ეკრანის ანაბეჭდის გაზიარება"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"მეტის აღბეჭდვა"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ეკრანის ანაბეჭდის დახურვა"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"მიმდინარეობს სახის სკანირება"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"გაგზავნა"</string>
     <string name="cancel" msgid="1089011503403416730">"გაუქმება"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"აპის ლოგო"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"დადასტურება"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ხელახლა ცდა"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"შეეხეთ ავტორიზაციის გასაუქმებლად"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ამოცნობილია სახით. გასაგრძელებლად დააჭირეთ განბლოკვის ხატულას."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ავტორიზებულია"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ავტორიზაციის გაუქმება"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"სხვა ვარიანტები"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN-კოდის გამოყენება"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ნიმუშის გამოყენება"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"პაროლის გამოყენება"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"სტანდარტული"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"საშუალო"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"მაღალი"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"სმენის აპარატები"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"გსურთ მოწყობილობის მიკროფონის განბლოკვა?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"გსურთ მოწყობილობის კამერის განბლოკვა?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"გსურთ მოწყობილობის კამერის და მიკროფონის განბლოკვა?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"ამოშლა"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ვიჯეტის დამატება"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"მზადაა"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"ვიჯეტების დამატება"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"მიიღეთ წვდომა თქვენი რჩეული აპების ვიჯეტებზე ტაბლეტის განბლოკვის გარეშე."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"ნებისმიერი ვიჯეტის დაშვება ჩაკეტილ ეკრანზე"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"პარამეტრების გახსნა"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"კვლავ გააქტიურდეს სამსახურის აპები?"</string>
@@ -597,7 +607,7 @@
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"სივრცითი აუდიო"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"გამორთული"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ფიქსირებული"</string>
-    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"თავის მოძრ. თვალყურის დევნა"</string>
+    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ხმის მიდევნებით"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"შეეხეთ მრეკავის რეჟიმის შესაცვლელად"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"დადუმება"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"დადუმების მოხსნა"</string>
@@ -763,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"ეკრანის გაყოფის შეყვანა მიმდინარე აპით RHS-ში"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"ეკრანის გაყოფის შეყვანა მიმდინარე აპით LHS-ში"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"გადართვა ეკრანის გაყოფიდან სრულ ეკრანზე"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ეკრანის გაყოფის გამოყენებისას აპზე მარჯვნივ ან ქვემოთ გადართვა"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ეკრანის გაყოფის გამოყენებისას აპზე მარცხნივ ან ზემოთ გადართვა"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ეკრანის გაყოფის დროს: ერთი აპის მეორით ჩანაცვლება"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"შეყვანა"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"შემდეგ ენაზე გადართვა"</string>
diff --git a/packages/SystemUI/res/values-ka/tiles_states_strings.xml b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
index 2691b69..21f8102 100644
--- a/packages/SystemUI/res/values-ka/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"გამორთული"</item>
     <item msgid="5137565285664080143">"ჩართული"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"მიუწვდომელია"</item>
+    <item msgid="3079622119444911877">"გამორთულია"</item>
+    <item msgid="3028994095749238254">"ჩართულია"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 8b86832..127e81e 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Әкімшіңіз скриншот жасауға тыйым салды."</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Өзгерту"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Скриншотты өзгерту"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Бөлісу"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Скриншотты бөлісу"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Тағы суретке түсіру"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Скриншотты жабу"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Бетті сканерлеу"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Жіберу"</string>
     <string name="cancel" msgid="1089011503403416730">"Бас тарту"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Қолданба логотипі"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Растау"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Қайта көру"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Аутентификациядан бас тарту үшін түртіңіз."</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Бет танылды. Жалғастыру үшін құлыпты ашу белгішесін басыңыз."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификацияланған"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Аутентификациядан бас тарту"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Қосымша опциялар"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN кодын пайдалану"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Өрнекті пайдалану"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Құпия сөзді пайдалану"</string>
@@ -362,11 +363,18 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Стандартты режим"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Орташа"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Жоғары"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Есту құрылғылары"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Құрылғы микрофонын блоктан шығару керек пе?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Құрылғы камерасын блоктан шығару керек пе?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Құрылғы камерасы мен микрофонын блоктан шығару керек пе?"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Микрофоныңызды пайдалануға рұқсат берілген барлық қолданба мен қызметтің бөгеуі алынады."</string>
-    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Камераңызды пайдалануға рұқсат берілген барлық қолданба мен қызметтің бөгеуі алынады."</string>
+    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Микрофоныңызды пайдалануға рұқсат берілген барлық қолданба мен қызмет блоктан шығарылады."</string>
+    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Камераңызды пайдалануға рұқсат берілген барлық қолданба мен қызмет блоктан шығарылады."</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Камераңызды немесе микрофоныңызды пайдалануға рұқсат берілген барлық қолданба мен қызметтің бөгеуі алынады."</string>
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Микрофон блокталған"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Камера блокталған"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Өшіру"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Виджет қосу"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Дайын"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Виджеттер қосу"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Таңдаулы қолданба виджеттерін планшет құлпын ашпай-ақ жылдам пайдаланыңыз."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Құлыптаулы экранда кез келген виджетке рұқсат беру керек пе?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Параметрлерді ашу"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Жұмыс қолданбаларын қайта қосасыз ба?"</string>
@@ -472,7 +482,7 @@
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы осы опцияны өшірді."</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Трансляциялау басталсын ба?"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Трансляциялау кезінде Android жүйесі экраныңызда көрінетін не құрылғыңызда ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Қолданба экранын трансляциялау кезінде Android жүйесі қолданбада көрінетін не ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Қолданба экранын трансляциялау кезінде Android қолданбада көрінетін не ойнатылатын барлық контентті пайдалана алады. Сондықтан құпия сөздер, төлем туралы мәлімет, хабарлар, фотосуреттер, дыбыстар мен бейнелер сияқты ақпаратқа сақ болыңыз."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Трансляциялауды бастау"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Бөлісу басталсын ба?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Бөлісу, жазу не трансляциялау кезінде Android жүйесі экраныңызда көрінетін не құрылғыңызда ойнатылатын барлық нәрсені пайдалана алады. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды немесе басқа құпия ақпаратты енгізген кезде сақ болыңыз."</string>
@@ -540,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Бұл құрылғыны ата-анаңыз басқарады. Ата-анаңыз сіз пайдаланатын қолданбалар, геодерегіңіз және пайдалану уақытыңыз сияқты ақпаратты көре және басқара алады."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent арқылы құлпы ашылды."</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Құрылғы құлыпталды, тым көп аутентификациялау талпынысы жасалды."</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Құрылғы құлыпталды\nАутентификация орындалмады"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Дыбыс параметрлері"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Автоматты субтитр қосу"</string>
@@ -765,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Бөлінген экран режиміне кіру (ағымдағы қолданбаны оңға орналастыру)"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Бөлінген экран режиміне кіру (ағымдағы қолданбаны солға орналастыру)"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Бөлінген экран режимінен толық экран режиміне ауысу"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Экранды бөлуді қолданғанда, оң не жоғары жақтағы қолданбаға ауысыңыз"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Экранды бөлуді қолданғанда, сол не жоғары жақтағы қолданбаға ауысыңыз"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Экранды бөлу кезінде: бір қолданбаны басқасымен алмастыру"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Енгізу"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Келесі тілге ауысу"</string>
@@ -1057,7 +1063,7 @@
     <string name="controls_media_button_pause" msgid="8614887780950376258">"Кідірту"</string>
     <string name="controls_media_button_prev" msgid="8126822360056482970">"Алдыңғы трек"</string>
     <string name="controls_media_button_next" msgid="6662636627525947610">"Келесі трек"</string>
-    <string name="controls_media_button_connecting" msgid="3138354625847598095">"Жалғануда"</string>
+    <string name="controls_media_button_connecting" msgid="3138354625847598095">"Жалғанып жатыр"</string>
     <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Ойнату"</string>
     <string name="controls_media_smartspace_rec_description" msgid="4136242327044070732">"<xliff:g id="APP_LABEL">%1$s</xliff:g> қолданбасын ашу"</string>
     <string name="controls_media_smartspace_rec_item_description" msgid="2189271793070870883">"<xliff:g id="APP_LABEL">%3$s</xliff:g> қолданбасында <xliff:g id="ARTIST_NAME">%2$s</xliff:g> орындайтын \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" әнін ойнату"</string>
diff --git a/packages/SystemUI/res/values-kk/tiles_states_strings.xml b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
index b37e982..cf3aa69 100644
--- a/packages/SystemUI/res/values-kk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"Өшірулі"</item>
     <item msgid="5137565285664080143">"Қосулы"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"Қолжетімді емес"</item>
+    <item msgid="3079622119444911877">"Өшірулі"</item>
+    <item msgid="3028994095749238254">"Қосулы"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 083586e..f2596db 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ការថតអេក្រង់ត្រូវបានទប់ស្កាត់ដោយអ្នកគ្រប់គ្រង​ផ្នែកព័ត៌មានវិទ្យារបស់អ្នក"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"កែ"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"កែ​រូបថត​អេក្រង់"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"ចែករំលែក"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"ចែករំលែករូបថតអេក្រង់"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ថត​ច្រើនទៀត"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ច្រានចោល​រូបថត​អេក្រង់"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ការ​ស្កេន​មុខ"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ផ្ញើ"</string>
     <string name="cancel" msgid="1089011503403416730">"បោះបង់"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"និមិត្តសញ្ញាកម្មវិធី"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"បញ្ជាក់"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ព្យាយាម​ម្ដង​ទៀត"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ចុចដើម្បីបោះបង់​ការផ្ទៀងផ្ទាត់"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"បានស្គាល់មុខ។ សូមចុចរូបដោះសោ ដើម្បីបន្ត។"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"បាន​ផ្ទៀងផ្ទាត់"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"បោះបង់ការផ្ទៀងផ្ទាត់"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ជម្រើស​ច្រើន​ទៀត"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ប្រើកូដ PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ប្រើ​លំនាំ"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"ប្រើពាក្យសម្ងាត់"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"ស្តង់ដារ"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"មធ្យម"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"ខ្ពស់"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"ឧបករណ៍ជំនួយការស្ដាប់"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ឈប់ទប់ស្កាត់​មីក្រូហ្វូន​របស់ឧបករណ៍ឬ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ឈប់ទប់ស្កាត់​កាមេរ៉ា​របស់ឧបករណ៍ឬ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ឈប់ទប់ស្កាត់​កាមេរ៉ា និងមីក្រូហ្វូន​របស់ឧបករណ៍ឬ?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"ដកចេញ"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"បញ្ចូលធាតុ​ក្រាហ្វិក"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"រួចរាល់"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"បញ្ចូលធាតុក្រាហ្វិក"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"ទទួលបានសិទ្ធិចូល​ប្រើប្រាស់​រហ័សទៅកាន់ធាតុក្រាហ្វិកកម្មវិធីដែលអ្នកចូលចិត្តដោយមិនចាំបាច់ដោះសោថេប្លេតរបស់អ្នក។"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"អនុញ្ញាត​ធាតុក្រាហ្វិក​នៅលើ​អេក្រង់ចាក់សោឬ?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"បើកការកំណត់"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"ឈប់ផ្អាកកម្មវិធីការងារឬ?"</string>
@@ -540,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ឧបករណ៍​នេះ​ស្ថិត​ក្រោម​ការ​គ្រប់គ្រង​របស់មាតាបិតាអ្នក។ មាតាបិតារបស់អ្នកអាចមើល និងគ្រប់គ្រងព័ត៌មាន​ដូចជា កម្មវិធីដែលអ្នកប្រើ ទីតាំងរបស់អ្នក និងរយៈពេលប្រើប្រាស់ឧបករណ៍របស់អ្នកជាដើម។"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"បាន​ដោះសោ​ដោយភ្នាក់ងារ​​ទុកចិត្ត"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"ឧបករណ៍ត្រូវបានចាក់សោ ដោយសារមានការព្យាយាមផ្ទៀងផ្ទាត់ច្រើនដងពេក"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"បានចាក់សោឧបករណ៍\nការផ្ទៀងផ្ទាត់មិនបានសម្រេច"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"ការកំណត់សំឡេង"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"ដាក់អក្សររត់លើមេឌៀដោយស្វ័យប្រវត្តិ"</string>
@@ -765,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"ចូលក្នុងមុខងារបំបែកអេក្រង់ដោយប្រើកម្មវិធីបច្ចុប្បន្ននៅខាងស្ដាំដៃ"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"ចូលក្នុងមុខងារ​បំបែកអេក្រង់ដោយប្រើកម្មវិធីបច្ចុប្បន្ននៅខាងឆ្វេងដៃ"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"ប្ដូរពីមុខងារ​បំបែកអេក្រង់ទៅជាអេក្រង់ពេញ"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ប្ដូរទៅកម្មវិធីនៅខាងស្ដាំ ឬខាងក្រោម ពេលកំពុងប្រើមុខងារ​បំបែកអេក្រង់"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ប្ដូរទៅកម្មវិធីនៅខាងឆ្វេង ឬខាងលើ ពេលកំពុងប្រើមុខងារ​បំបែកអេក្រង់"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ក្នុងអំឡុងពេលប្រើមុខងារបំបែកអេក្រង់៖ ជំនួសកម្មវិធីពីមួយទៅមួយទៀត"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"បញ្ចូល"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"ប្ដូរទៅភាសាបន្ទាប់"</string>
diff --git a/packages/SystemUI/res/values-km/tiles_states_strings.xml b/packages/SystemUI/res/values-km/tiles_states_strings.xml
index 0b2d5b3..54790f6 100644
--- a/packages/SystemUI/res/values-km/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-km/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"បិទ"</item>
     <item msgid="5137565285664080143">"បើក"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"មិនមានទេ"</item>
+    <item msgid="3079622119444911877">"បិទ"</item>
+    <item msgid="3028994095749238254">"បើក"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index df50db6..7323450 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳುವುದನ್ನು ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರು ನಿರ್ಬಂಧಿಸಿದ್ದಾರೆ"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"ಎಡಿಟ್ ಮಾಡಿ"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ ಅನ್ನು ಎಡಿಟ್ ಮಾಡಿ"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"ಹಂಚಿಕೊಳ್ಳಿ"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳಿ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ಇನ್ನಷ್ಟು ಕ್ಯಾಪ್ಚರ್ ಮಾಡಿ"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್ ಅನ್ನು ವಜಾಗೊಳಿಸಿ"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ಮುಖವನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ಕಳುಹಿಸಿ"</string>
     <string name="cancel" msgid="1089011503403416730">"ರದ್ದುಮಾಡಿ"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"ಆ್ಯಪ್ ಲೋಗೋ"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ದೃಢೀಕರಿಸಿ"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ದೃಢೀಕರಣವನ್ನು ರದ್ದುಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ಮುಖ ಗುರುತಿಸಲಾಗಿದೆ. ಮುಂದುವರಿಯಲು ಅನ್‌ಲಾಕ್ ಐಕಾನ್ ಅನ್ನು ಒತ್ತಿ."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ದೃಢೀಕರಿಸಲಾಗಿದೆ"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ದೃಢೀಕರಣವನ್ನು ರದ್ದುಗೊಳಿಸಿ"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ಇನ್ನಷ್ಟು ಆಯ್ಕೆಗಳು"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ಪಿನ್ ಬಳಸಿ"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ಪ್ಯಾಟರ್ನ್ ಬಳಸಿ"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"ಪಾಸ್‌ವರ್ಡ್ ಬಳಸಿ"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"ಪ್ರಮಾಣಿತ"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"ಮಧ್ಯಮ"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"ಹೆಚ್ಚು"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ಸಾಧನದ ಮೈಕ್ರೋಫೋನ್ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆಯಬೇಕೆ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ಸಾಧನದ ಕ್ಯಾಮರಾ ನಿರ್ಬಂಧವನ್ನು ತೆಗೆಯಬೇಕೆ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ಸಾಧನದ ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ರೋಫೋನ್ ಅನ್ನು ಅನ್‍ಬ್ಲಾಕ್ ಮಾಡಬೇಕೇ?"</string>
@@ -439,13 +448,15 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"ತೆಗೆದುಹಾಕಿ"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ವಿಜೆಟ್ ಅನ್ನು ಸೇರಿಸಿ"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"ಮುಗಿದಿದೆ"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"ವಿಜೆಟ್‌ಗಳನ್ನು ಸೇರಿಸಿ"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಅನ್‌ಲಾಕ್ ಮಾಡದೆಯೇ ನಿಮ್ಮ ಮೆಚ್ಚಿನ ಆ್ಯಪ್ ವಿಜೆಟ್‌ಗಳಿಗೆ ತ್ವರಿತ ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಪಡೆಯಿರಿ."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"ಲಾಕ್ ಸ್ಕ್ರೀನ್‌ನಲ್ಲಿ ಯಾವುದೇ ವಿಜೆಟ್ ಅನ್ನು ಅನುಮತಿಸಬೇಕೇ?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"ಕೆಲಸದ ಆ್ಯಪ್ ವಿರಾಮ ರದ್ದುಮಾಡಬೇಕೇ"</string>
     <string name="work_mode_turn_on" msgid="907813741770247267">"ವಿರಾಮವನ್ನು ರದ್ದುಗೊಳಿಸಿ"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ಪುಲ್‌ಡೌನ್ ಮೆನು"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ಈ ಸೆಷನ್‌ನಲ್ಲಿನ ಎಲ್ಲ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ಈ ಸೆಶನ್‌ನಲ್ಲಿನ ಎಲ್ಲಾ ಆ್ಯಪ್‌ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ."</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"ಮತ್ತೆ ಸುಸ್ವಾಗತ, ಅತಿಥಿ!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ನಿಮ್ಮ ಸೆಷನ್‌ ಮುಂದುವರಿಸಲು ಇಚ್ಚಿಸುವಿರಾ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ಪ್ರಾರಂಭಿಸಿ"</string>
@@ -470,8 +481,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತಿರುವಾಗ, ರೆಕಾರ್ಡಿಂಗ್ ಮಾಡುತ್ತಿರುವಾಗ ಅಥವಾ ಕ್ಯಾಸ್ಟ್ ಮಾಡುತ್ತಿರುವಾಗ, ಆ ಆ್ಯಪ್‌ನಲ್ಲಿ ತೋರಿಸುವ ಅಥವಾ ಪ್ಲೇ ಮಾಡುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಹಾಗೂ ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string>
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"ಪ್ರಾರಂಭಿಸಿ"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಈ ಆಯ್ಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದೆ"</string>
-    <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"ಕ್ಯಾಸ್ಟ್ ಮಾಡಲು ಪ್ರಾರಂಭಿಸಬೇಕೇ?"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"ನೀವು ಕ್ಯಾಸ್ಟ್ ಮಾಡುವಾಗ, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಕಾಣಿಸುವ ಅಥವಾ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಮಾಡುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ Android ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಹಾಗೂ ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string>
+    <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"ಕ್ಯಾಸ್ಟ್ ಮಾಡಲು ಪ್ರಾರಂಭಿಸಬೇಕೆ?"</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"ನೀವು ಕ್ಯಾಸ್ಟ್ ಮಾಡುತ್ತಿರುವಾಗ, ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಮೇಲೆ ಕಾಣಿಸುವ ಅಥವಾ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಪ್ಲೇ ಮಾಡುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ Android ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಹಾಗೂ ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ಕ್ಯಾಸ್ಟ್ ಮಾಡುತ್ತಿರುವಾಗ, ಆ ಆ್ಯಪ್‌ನಲ್ಲಿ ತೋರಿಸುವ ಅಥವಾ ಪ್ಲೇ ಮಾಡುವ ಯಾವುದೇ ವಿಷಯಕ್ಕೆ Android ಆ್ಯಕ್ಸೆಸ್ ಅನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಹಾಗೂ ಆಡಿಯೊ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಕುರಿತು ಜಾಗರೂಕರಾಗಿರಿ."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"ಕ್ಯಾಸ್ಟ್ ಮಾಡಲು ಪ್ರಾರಂಭಿಸಿ"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"ಹಂಚಿಕೊಳ್ಳಲು ಪ್ರಾರಂಭಿಸಬೇಕೇ?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ಈ ಸಾಧನವನ್ನು ನಿಮ್ಮ ಪೋಷಕರು ನಿರ್ವಹಿಸುತ್ತಿದ್ದಾರೆ. ನೀವು ಬಳಸುವ ಆ್ಯಪ್‌ಗಳು, ನಿಮ್ಮ ಸ್ಥಳ ಮತ್ತು ನಿಮ್ಮ ವೀಕ್ಷಣಾ ಅವಧಿಯಂತಹ ಮಾಹಿತಿಯನ್ನು ನಿಮ್ಮ ಪೋಷಕರು ನೋಡಬಹುದು ಮತ್ತು ನಿರ್ವಹಿಸಬಹುದು."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent ನಿಂದ ಅನ್‌ಲಾಕ್ ಮಾಡಲಾಗಿದೆ"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"ಸಾಧನವನ್ನು ಲಾಕ್ ಮಾಡಲಾಗಿದೆ, ಹಲವಾರು ದೃಢೀಕರಣ ಪ್ರಯತ್ನಗಳು"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"ಸಾಧನವನ್ನು ಲಾಕ್ ಮಾಡಲಾಗಿದೆ\nದೃಢೀಕರಣ ವಿಫಲವಾಗಿದೆ"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"ಸೌಂಡ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"ಸ್ವಯಂಚಾಲಿತ ಶೀರ್ಷಿಕೆ ಮಾಧ್ಯಮ"</string>
@@ -612,7 +621,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s ಮ್ಯೂಟ್ ಮಾಡಿ"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s ಅನ್‌ಮ್ಯೂಟ್ ಮಾಡಿ"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಆಗು..."</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"ಇಲ್ಲಿ ಆಡಿಯೋ ಪ್ಲೇ..."</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"ಇದರಲ್ಲಿ ಪ್ಲೇ ಆಗುತ್ತದೆ"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"ಸಿಸ್ಟಂ UI ಟ್ಯೂನರ್"</string>
     <string name="status_bar" msgid="4357390266055077437">"ಸ್ಥಿತಿ ಪಟ್ಟಿ"</string>
     <string name="demo_mode" msgid="263484519766901593">"ಸಿಸ್ಟಂ UI ಡೆಮೋ ಮೋಡ್"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHS ಗೆ ಇರುವ ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಸಹಾಯದಿಂದ ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ನಮೂದಿಸಿ"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHS ಗೆ ಇರುವ ಪ್ರಸ್ತುತ ಆ್ಯಪ್ ಸಹಾಯದಿಂದ ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ನಮೂದಿಸಿ"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್‌ನಿಂದ ಪೂರ್ಣ ಸ್ಕ್ರೀನ್‌ಗೆ ಬದಲಿಸಿ"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ಪರದೆ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಬಳಸುವಾಗ ಬಲಭಾಗ ಅಥವಾ ಕೆಳಭಾಗದಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ಪರದೆ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಬಳಸುವಾಗ ಎಡಭಾಗ ಅಥವಾ ಮೇಲ್ಭಾಗದಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸುವ ಸಮಯದಲ್ಲಿ: ಒಂದು ಆ್ಯಪ್‌ನಿಂದ ಮತ್ತೊಂದು ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ಇನ್‌ಪುಟ್"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"ಮುಂದಿನ ಭಾಷೆಗೆ ಬದಲಿಸಿ"</string>
diff --git a/packages/SystemUI/res/values-kn/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
index 3ae6578..9628323 100644
--- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"ಆಫ್ ಆಗಿದೆ"</item>
     <item msgid="5137565285664080143">"ಆನ್ ಆಗಿದೆ"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 4c44228..9a4c60b 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"IT 관리자가 스크린샷 촬영을 허용하지 않습니다."</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"수정"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"스크린샷 수정"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"공유"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"스크린샷 공유"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"더 캡처하기"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"스크린샷 닫기"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"얼굴 스캔 중"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"보내기"</string>
     <string name="cancel" msgid="1089011503403416730">"취소"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"앱 로고"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"확인"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"다시 시도하세요."</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"탭하여 인증 취소"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"얼굴이 인식되었습니다. 계속하려면 아이콘을 누르세요."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"인증됨"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"인증 취소"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"옵션 더보기"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN 사용"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"패턴 사용"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"비밀번호 사용"</string>
@@ -362,7 +363,15 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"표준"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"보통"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"높음"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"기기 마이크를 &amp;#173;차단 해제하시겠습니까?"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
+    <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"기기 마이크를 차단 해제하시겠습니까?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"기기 카메라를 차단 해제하시겠습니까?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"기기 카메라 및 마이크를 차단 해제하시겠습니까?"</string>
     <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"마이크를 사용할 수 있는 모든 앱 및 서비스에 대해 액세스가 차단 해제됩니다."</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"삭제"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"위젯 추가"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"완료"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"위젯 추가"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"태블릿을 잠금 해제하지 않고도 즐겨 사용하는 앱 위젯에 빠르게 액세스하세요"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"잠금 화면에서 위젯 사용을 허용하시겠습니까?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"설정 열기"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"직장 앱 일시중지를 해제하시겠습니까?"</string>
@@ -586,8 +597,8 @@
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"음소거"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"전송"</string>
     <string name="stream_notification_unavailable" msgid="4313854556205836435">"벨소리가 음소거되어 있으므로 사용할 수 없음"</string>
-    <string name="stream_alarm_unavailable" msgid="4059817189292197839">"방해 금지 모드가 사용 설정되어 있어 사용할 수 없음"</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"방해 금지 모드가 사용 설정되어 있어 사용할 수 없음"</string>
+    <string name="stream_alarm_unavailable" msgid="4059817189292197839">"방해 금지 모드로 설정되어 있어 사용할 수 없음"</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"방해 금지 모드로 설정되어 있어 사용할 수 없음"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. 탭하여 음소거를 해제하세요."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. 탭하여 진동으로 설정하세요. 접근성 서비스가 음소거될 수 있습니다."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. 탭하여 음소거로 설정하세요. 접근성 서비스가 음소거될 수 있습니다."</string>
@@ -603,7 +614,7 @@
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"음소거 해제"</string>
     <string name="volume_ringer_hint_vibrate" msgid="6211609047099337509">"진동"</string>
     <string name="volume_dialog_title" msgid="6502703403483577940">"%s 볼륨 컨트롤"</string>
-    <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"전화 및 알림이 오면 벨소리가 울림(<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)"</string>
+    <string name="volume_dialog_ringer_guidance_ring" msgid="9143194270463146858">"전화 및 알림이 오면 벨소리가 울립니다(<xliff:g id="VOLUME_LEVEL">%1$s</xliff:g>)."</string>
     <string name="volume_panel_enter_media_output_settings" msgid="8824244246272552669">"출력 설정 열기"</string>
     <string name="volume_panel_expanded_sliders" msgid="1885750987768506271">"볼륨 슬라이더 펼침"</string>
     <string name="volume_panel_collapsed_sliders" msgid="1413383759434791450">"볼륨 슬라이더 접힘"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"현재 앱을 오른쪽으로 보내는 화면 분할 입력"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"현재 앱을 왼쪽으로 보내는 화면 분할 입력"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"화면 분할에서 전체 화면으로 전환"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"화면 분할을 사용하는 중에 오른쪽 또는 아래쪽에 있는 앱으로 전환하기"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"화면 분할을 사용하는 중에 왼쪽 또는 위쪽에 있는 앱으로 전환하기"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"화면 분할 중: 다른 앱으로 바꾸기"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"입력"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"다음 언어로 전환"</string>
diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
index 002efb2..d30aff2 100644
--- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"사용 안함"</item>
     <item msgid="5137565285664080143">"사용"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 2044f92..d893887 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"IT администраторуңуз скриншот тартууга тыюу салган"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Түзөтүү"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Скриншотту түзөтүү"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Бөлүшүү"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Скриншотту бөлүшүү"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Көбүрөөк тартуу"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Скриншотту четке кагуу"</string>
@@ -107,7 +106,7 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Жаздырып баштайсызбы?"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Жаздырып жатканыңызда Android экраныңызда көрүнүп жана түзмөктө ойнотулуп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Колдонмону жаздырып жатканда Android ал колдонмодо көрсөтүлүп жана ойнотулуп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Колдонмону жаздырып жатканда Android анда көрүнүп же ойноп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Жаздырып баштоо"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Аудио жаздыруу"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Түзмөктөгү аудиолор"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Жүз скандалууда"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Жөнөтүү"</string>
     <string name="cancel" msgid="1089011503403416730">"Баш тартуу"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Колдонмонун логотиби"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Ырастоо"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Кайталоо"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Аныктыгын текшерүүнү жокко чыгаруу үчүн таптаңыз"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Жүз таанылды. Улантуу үчүн кулпусун ачуу сүрөтчөсүн басыңыз."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аныктыгы текшерилди"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Аныктыгын текшерүүнү жокко чыгаруу"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Дагы параметрлер"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN кодду колдонуу"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Графикалык ачкычты колдонуу"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Сырсөз колдонуу"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Кадимки"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Орточо"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Жогору"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Түзмөктүн микрофонун бөгөттөн чыгарасызбы?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Түзмөктүн камерасын бөгөттөн чыгарасызбы?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Түзмөктүн камерасы менен микрофону бөгөттөн чыгарылсынбы?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Өчүрүү"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Виджет кошуу"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Бүттү"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Виджеттерди кошуу"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Тандалма колдонмолордун виджеттерин планшеттин кулпусун ачпастан эле, ыкчам колдонуңуз."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Бардык виджеттер кулпуланган экранда көрсөтүлсүнбү?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Параметрлерди ачуу"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Жумуш колдонмолорун иштетесизби?"</string>
@@ -467,16 +478,16 @@
     <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Колдонмону бөлүшүү же жаздыруу"</string>
     <string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосу аркылуу жаздырып же тышкы экранга чыгарып баштайсызбы?"</string>
     <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Бөлүшүп, жаздырып же тышкы экранга чыгарып жатканда <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосу экраныңыздагы бардык маалыматты же түзмөктө ойнотулуп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
-    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Колдонмону бөлүшүп, жаздырып же тышкы экранга чыгарганда <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосу ал колдонмодо көрсөтүлүп жана ойнотулуп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Колдонмону бөлүшүп, жаздырып же тышкы экранга чыгарганда <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосу анда көрүнүп же ойноп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Баштоо"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> бул параметрди өчүрүп койду"</string>
-    <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Тышкы экранга чыгаруу башталсынбы?"</string>
+    <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Тышкы экранга чыгарып баштайсызбы?"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Тышкы экранга чыгарганда Android экраныңызда көрүнүп жана түзмөктө ойнотулуп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Колдонмону тышкы экранга чыгарганда Android ал колдонмодо көрсөтүлүп жана ойнотулуп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Колдонмону тышкы экранга чыгарганда Android анда көрүнүп же ойноп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Тышкы экранга чыгарып баштоо"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Бөлүшүү башталсынбы?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Бөлүшүп, жаздырып же тышкы экранга чыгарып жатканда Android экраныңыздагы бардык маалыматты же түзмөктө ойнотулуп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
-    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Колдонмону бөлүшүп, жаздырып же тышкы экранга чыгарганда Android ал колдонмодо көрсөтүлүп жана ойнотулуп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Колдонмону бөлүшүп, жаздырып же тышкы экранга чыгарганда Android анда көрүнүп же ойноп жаткан нерселерди көрө алат. Андыктан сырсөздөрдү, төлөмдүн чоо-жайын, билдирүүлөрдү, сүрөттөрдү, аудио жана видеону көрсөтүп албаңыз."</string>
     <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Баштоо"</string>
     <string name="media_projection_task_switcher_text" msgid="590885489897412359">"Колдонмо которулганда бөлүшүү тындырылат"</string>
     <string name="media_projection_task_switcher_action_switch" msgid="8682258717291921123">"Анын ордуна бул колдонмону бөлүшүү"</string>
@@ -610,7 +621,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s үнүн басуу"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s үнүн чыгаруу"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> аркылуу ойнотулууда"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Аудио төмөнкүдө ойнотулат:"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Аудио кайсы жерде ойнотулат:"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string>
     <string name="status_bar" msgid="4357390266055077437">"Абал тилкеси"</string>
     <string name="demo_mode" msgid="263484519766901593">"Системанын интерфейсинин демо режими"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Учурда оң жактагы колдонмо менен экранды бөлүүнү иштетүү"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Учурда сол жактагы колдонмо менен экранды бөлүүнү иштетүү"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Экранды бөлүү режиминен толук экранга которулуу"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Бөлүнгөн экранды колдонуп жатканда сол же төмөн жактагы колдонмого которулуңуз"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Бөлүнгөн экранды колдонуп жатканда сол же жогору жактагы колдонмого которулуңуз"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Экранды бөлүү режиминде бир колдонмону экинчисине алмаштыруу"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Киргизүү"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Кийинки тилге которулуу"</string>
@@ -1164,7 +1173,7 @@
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Туташты"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Убактылуу туташып турат"</string>
     <string name="mobile_data_poor_connection" msgid="819617772268371434">"Байланыш начар"</string>
-    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Мобилдик трафик автоматтык түрдө туташтырылбайт"</string>
+    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Мобилдик Интернетке автоматтык түрдө өтпөйт"</string>
     <string name="mobile_data_no_connection" msgid="1713872434869947377">"Байланыш жок"</string>
     <string name="non_carrier_network_unavailable" msgid="770049357024492372">"Башка тармактар жеткиликсиз"</string>
     <string name="all_network_unavailable" msgid="4112774339909373349">"Тармактар жеткиликтүү эмес"</string>
diff --git a/packages/SystemUI/res/values-ky/tiles_states_strings.xml b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
index bb03d0a..35795b7 100644
--- a/packages/SystemUI/res/values-ky/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Өчүк"</item>
     <item msgid="5137565285664080143">"Күйүк"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index 55606aa..56ebc06 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -94,4 +94,7 @@
 
     <dimen name="keyguard_indication_margin_bottom">8dp</dimen>
     <dimen name="lock_icon_margin_bottom">24dp</dimen>
+
+    <!-- Keyboard shortcuts helper -->
+    <dimen name="ksh_container_horizontal_margin">48dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index f109041..873d75e 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ຜູ້ເບິ່ງແຍງໄອທີຂອງທ່ານບລັອກການຖ່າຍຮູບໜ້າຈໍໄວ້."</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"ແກ້ໄຂ"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"ແກ້ໄຂຮູບໜ້າຈໍ"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"ແບ່ງປັນ"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"ແບ່ງປັນຮູບໜ້າຈໍ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ຖ່າຍຮູບເພີ່ມເຕີມ"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ປິດຮູບໜ້າຈໍ"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ການສະແກນໜ້າ"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ສົ່ງ"</string>
     <string name="cancel" msgid="1089011503403416730">"ຍົກເລີກ"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"ໂລໂກ້ແອັບ"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ຢືນຢັນ"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ລອງໃໝ່"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ແຕະເພື່ອຍົກເລີກການກວດສອບຄວາມຖືກຕ້ອງ"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ຈຳແນກໜ້າໄດ້ແລ້ວ. ກົດໄອຄອນປົດລັອກເພື່ອສືບຕໍ່."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ຮັບຮອງຄວາມຖືກຕ້ອງແລ້ວ"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ຍົກເລີກການພິສູດຢືນຢັນ"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ຕົວເລືອກເພີ່ມເຕີມ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ໃຊ້ PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ໃຊ້ຮູບແບບ"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"ໃຊ້ລະຫັດຜ່ານ"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"ມາດຕະຖານ"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"ປານກາງ"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"ສູງ"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"ອຸປະກອນຊ່ວຍຟັງ"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ປົດບລັອກໄມໂຄຣໂຟນອຸປະກອນບໍ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ປົດບລັອກກ້ອງຖ່າຍຮູບອຸ​ປະ​ກອນບໍ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ຍົກເລີກການບລັອກກ້ອງຖ່າຍຮູບ ຫຼື ໄມໂຄຣໂຟນອຸ​ປະ​ກອນບໍ?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"ລຶບອອກ"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ເພີ່ມວິດເຈັດ"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"ແລ້ວໆ"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"ເພີ່ມວິດເຈັດ"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"ຮັບການເຂົ້າເຖິງດ່ວນຫາແອັບວິດເຈັດທີ່ທ່ານມັກໂດຍບໍ່ຕ້ອງປົດລັອກແທັບເລັດຂອງທ່ານ."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"ອະນຸຍາດວິດເຈັດໃດກໍຕາມຢູ່ໜ້າຈໍລັອກບໍ?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"ເປີດການຕັ້ງຄ່າ"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"ຍົກເລີກການຢຸດຊົ່ວຄາວແອັບບ່ອນເຮັດວຽກບໍ?"</string>
@@ -540,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ອຸປະກອນນີ້ແມ່ນຈັດການໂດຍພໍ່ແມ່ຂອງທ່ານ. ພໍ່ແມ່ຂອງທ່ານສາມາດເບິ່ງ ແລະ ຈັດການຂໍ້ມູນໄດ້ ເຊັ່ນ: ແອັບທີ່ທ່ານໃຊ້, ສະຖານທີ່ ແລະ ເວລາໜ້າຈໍຂອງທ່ານ."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"ປັອດລັອກປະໄວ້ໂດຍ TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"ອຸປະກອນຖືກລັອກແລ້ວ, ພະຍາຍາມເຮັດການພິສູດຢືນຢັນຫຼາຍເທື່ອເກີນໄປ"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"ລັອກອຸປະກອນແລ້ວ\nການພິສູດຢືນຢັນບໍ່ສຳເລັດ"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"ການຕັ້ງຄ່າສຽງ"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"ສ້າງຄຳບັນຍາຍມີເດຍໂດຍອັດຕະໂນມັດ"</string>
@@ -765,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"ເຂົ້າສູ່ແບ່ງໜ້າຈໍດ້ວຍແອັບປັດຈຸບັນໄປຫາ RHS"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"ເຂົ້າສູ່ແບ່ງໜ້າຈໍດ້ວຍແອັບປັດຈຸບັນໄປຫາ LHS"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"ສະຫຼັບຈາກແບ່ງໜ້າຈໍໄປເປັນເຕັມຈໍ"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ສະຫຼັບໄປໃຊ້ແອັບຢູ່ຂວາ ຫຼື ທາງລຸ່ມໃນຂະນະທີ່ໃຊ້ແບ່ງໜ້າຈໍ"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ສະຫຼັບໄປໃຊ້ແອັບຢູ່ຊ້າຍ ຫຼື ທາງເທິງໃນຂະນະທີ່ໃຊ້ແບ່ງໜ້າຈໍ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ໃນລະຫວ່າງແບ່ງໜ້າຈໍ: ໃຫ້ປ່ຽນຈາກແອັບໜຶ່ງເປັນອີກແອັບໜຶ່ງ"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ການປ້ອນຂໍ້ມູນ"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"ສະຫຼັບເປັນພາສາຖັດໄປ"</string>
diff --git a/packages/SystemUI/res/values-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
index 3c288fc..9386e00 100644
--- a/packages/SystemUI/res/values-lo/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"ປິດ"</item>
     <item msgid="5137565285664080143">"ເປີດ"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"ບໍ່ພ້ອມໃຫ້ນຳໃຊ້"</item>
+    <item msgid="3079622119444911877">"ປິດ"</item>
+    <item msgid="3028994095749238254">"ເປີດ"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 5f1c7bb..d5d7929 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Jūsų IT administratorius užblokavo galimybę daryti ekrano kopijas."</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Redaguoti"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Redaguoti ekrano kopiją"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Bendrinti"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Bendrinti ekrano kopiją"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Fiksuoti daugiau"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Praleisti ekrano kopiją"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Nuskaitomas veidas"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Siųsti"</string>
     <string name="cancel" msgid="1089011503403416730">"Atšaukti"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Programos logotipas"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Patvirtinkite"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Bandyti dar kartą"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Palieskite, jei norite atšaukti autentifikavimą"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Veidas atpažintas. Tęskite paspaudę atrakinimo piktogramą."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikuota"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Atšaukti autentifikavimą"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Daugiau parinkčių"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Naudoti PIN kodą"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Naudoti atrakinimo piešinį"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Naudoti slaptažodį"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Įprastas"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Vidutinis"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Aukštas"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Panaikinti įrenginio mikrofono blokavimą?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Panaikinti įrenginio fotoaparato blokavimą?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Panaikinti įrenginio fotoaparato ir mikrofono blokavimą?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Pašalinti"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Pridėti valdiklį"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Atlikta"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Pridėti valdiklių"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Sparčiai pasiekite mėgstamiausius programų valdiklius neatrakinę planšetinio kompiuterio."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Leisti visus valdiklius užrakinimo ekrane?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Atidaryti nustatymus"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Atš. darbo progr. pristabd.?"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Eiti į išskaidyto ekrano režimą su dabartine programa dešinėje"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Eiti į išskaidyto ekrano režimą su dabartine programa kairėje"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Perjungti iš išskaidyto ekrano režimo į viso ekrano režimą"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Perjunkite į programą dešinėje arba apačioje išskaidyto ekrano režimu"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Perjunkite į programą kairėje arba viršuje išskaidyto ekrano režimu"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Išskaidyto ekrano režimu: pakeisti iš vienos programos į kitą"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Įvestis"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Perjungti į kitą kalbą"</string>
diff --git a/packages/SystemUI/res/values-lt/tiles_states_strings.xml b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
index 8c4515b..cfa5552 100644
--- a/packages/SystemUI/res/values-lt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Išjungta"</item>
     <item msgid="5137565285664080143">"Įjungta"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 0be94f1..4413780 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Jūsu IT administrators ir bloķējis ekrānuzņēmumu izveidi"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Rediģēt"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Rediģēt ekrānuzņēmumu"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Kopīgot"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Kopīgot ekrānuzņēmumu"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Tvert vairāk"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Nerādīt ekrānuzņēmumu"</string>
@@ -107,8 +106,8 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Aktīvs paziņojums par ekrāna ierakstīšanas sesiju"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Vai sākt ierakstīšanu?"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Ierakstīšanas laikā Android var piekļūt visam, kas tiek rādīts jūsu ekrānā vai atskaņots jūsu ierīcē. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Lietotnes ierakstīšanas laikā Android var piekļūt visam, kas tiek rādīts vai atskaņots attiecīgajā lietotnē. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu."</string>
-    <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Sāk ierakstīšanu"</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Lietotnes ierakstīšanas laikā Android var piekļūt visam, kas tiek rādīts vai atskaņots attiecīgajā lietotnē. Tāpēc ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu rīkojieties piesardzīgi."</string>
+    <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Sākt ierakstīšanu"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Ierakstīt audio"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Ierīces audio"</string>
     <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Skaņa no jūsu ierīces, piemēram, mūzika, sarunas un zvana signāli"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Sejas skenēšana"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Sūtīt"</string>
     <string name="cancel" msgid="1089011503403416730">"Atcelt"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Lietotnes logotips"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Apstiprināt"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Mēģināt vēlreiz"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Pieskarieties, lai atceltu autentifikāciju."</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Seja atpazīta. Lai turpinātu, nospiediet atbloķēšanas ikonu."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentifikācija veikta"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Atcelt autentificēšanu"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Citas opcijas"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Izmantot PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Izmantot kombināciju"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Izmantot paroli"</string>
@@ -265,7 +266,7 @@
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Nav pieejama neviena pārī savienota ierīce."</string>
     <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Lai pievienotu vai atvienotu kādu ierīci, pieskarieties."</string>
-    <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Savienošana pārī ar jaunu ierīci"</string>
+    <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Savienot pārī ar jaunu ierīci"</string>
     <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Skatīt visas"</string>
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Izmantot Bluetooth"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Savienojums izveidots"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standarta"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Vidējs"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Augsts"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vai atbloķēt ierīces mikrofonu?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vai vēlaties atbloķēt ierīces kameru?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vai atbloķēt ierīces kameru un mikrofonu?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Noņemt"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Pievienot logrīku"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Gatavs"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Pievienot logrīkus"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Ātri piekļūstiet saviem iecienītākajiem lietotņu logrīkiem, neatbloķējot planšetdatoru."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Vai atļaut jebkāda veida logrīkus bloķēšanas ekrānā?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Atvērt iestatījumus"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Vai aktivizēt darba lietotnes?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Šo ierīci pārvalda viens no jūsu vecākiem. Vecāki var skatīt un pārvaldīt tādu informāciju kā jūsu izmantotās lietotnes, atrašanās vieta un izmantošanas ilgums."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Bloķēšanu liedzis TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Ierīce tika bloķēta; pārāk daudz autentifikācijas mēģinājumu."</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Ierīce bloķēta\nAutentifikācija neizdevās"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Skaņas iestatījumi"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Autom. paraksti multividei"</string>
@@ -576,7 +585,7 @@
     <string name="screen_pinning_exit" msgid="4553787518387346893">"Lietotne tika atsprausta"</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"Zvans"</string>
     <string name="stream_system" msgid="7663148785370565134">"Sistēma"</string>
-    <string name="stream_ring" msgid="7550670036738697526">"Zvans"</string>
+    <string name="stream_ring" msgid="7550670036738697526">"Skaņas signāls"</string>
     <string name="stream_music" msgid="2188224742361847580">"Multivide"</string>
     <string name="stream_alarm" msgid="16058075093011694">"Signāls"</string>
     <string name="stream_notification" msgid="7930294049046243939">"Paziņojums"</string>
@@ -599,7 +608,7 @@
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Telpiskais audio"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Izslēgts"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Fiksēts"</string>
-    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Galvas kustību reģistrēšana"</string>
+    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Seko galvai"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Pieskarieties, lai mainītu zvanītāja režīmu."</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"izslēgt skaņu"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"ieslēgt skaņu"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Pāriet ekrāna sadalīšanas režīmā ar pašreizējo lietotni pa labi"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Pāriet ekrāna sadalīšanas režīmā ar pašreizējo lietotni pa kreisi"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Pārslēgties no ekrāna sadalīšanas režīma uz pilnekrāna režīmu"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Pāriet uz lietotni pa labi/lejā, kamēr izmantojat sadalīto ekrānu."</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pāriet uz lietotni pa kreisi/augšā, kamēr izmantojat sadalīto ekrānu."</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ekrāna sadalīšanas režīmā: pārvietot lietotni no viena ekrāna uz otru"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Ievade"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Pārslēgt uz nākamo valodu"</string>
diff --git a/packages/SystemUI/res/values-lv/tiles_states_strings.xml b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
index a75e9d8..e6b4dea 100644
--- a/packages/SystemUI/res/values-lv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Izslēgts"</item>
     <item msgid="5137565285664080143">"Ieslēgts"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 3a84c9c..4f5bf6c 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Зачувувањето слики од екранот е блокирано од IT-администраторот"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Измени"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Изменете ја сликата од екранот"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Сподели"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Споделете слика од екранот"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Сними повеќе"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Отфрлете ја сликата од екранот"</string>
@@ -107,7 +106,7 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Тековно известување за сесија за снимање на екранот"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Да се започне со снимање?"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Додека снимате, Android има пристап до сѐ што е видливо на вашиот екран или пуштено на вашиот уред. Затоа, бидете внимателни со работи како лозинки, детали за плаќање, пораки, фотографии и аудио и видео."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Додека снимате апликација, Android има пристап до сѐ што се прикажува или пушта на таа апликација. Затоа, бидете внимателни со лозинки, детали за плаќање, пораки фотографии и аудио и видео."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Додека снимате апликација, Android има пристап до сѐ што се прикажува или пушта на таа апликација. Затоа, бидете внимателни со лозинки, детали за плаќање, пораки, фотографии и аудио и видео."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Започни со снимање"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Снимај аудио"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Аудио од уредот"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Скенирање лице"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Испрати"</string>
     <string name="cancel" msgid="1089011503403416730">"Откажи"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Лого на апликацијата"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Потврди"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Обиди се повторно"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Допрете за да ја откажете проверката"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицето е препознаено. Притиснете ја иконата за отклучување за да продолжите."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Проверена"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Откажување автентикација"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Повеќе опции"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Користи PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Користи шема"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Користи лозинка"</string>
@@ -264,7 +265,7 @@
     <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Не вознемирувај"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Нема достапни спарени уреди"</string>
-    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Допрете за да поврзете уред или да ја прекинете врската со уред"</string>
+    <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Допрете за да воспоставите или да прекинете врска со уред"</string>
     <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Спарете нов уред"</string>
     <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Прикажи ги сите"</string>
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Користи Bluetooth"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Стандарден"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Среден"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Висок"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Да се одблокира пристапот до микрофонот на уредот?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Да се одблокира пристапот до камерата на уредот?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Да се одблокира пристапот до камерата и микрофонот на уредот?"</string>
@@ -439,13 +448,15 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Отстранува"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Додајте виџет"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Готово"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Додајте виџети"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Добијте брз пристап до вашите омилени виџети за апликации без да го отклучите таблетот."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Да се дозволи каков било виџет на заклучен екран?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Отвори ги поставките"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Да се актив. работните аплик.?"</string>
     <string name="work_mode_turn_on" msgid="907813741770247267">"Прекини ја паузата"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"Промени го корисникот"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"паѓачко мени"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Сите апликации и податоци во сесијата ќе се избришат."</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"Сите апликации и податоци во сесијава ќе се избришат."</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"Добре дојде пак, гостине!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"Дали сакате да продолжите со сесијата?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Почни одново"</string>
@@ -575,7 +586,7 @@
     <string name="stream_voice_call" msgid="7468348170702375660">"Повик"</string>
     <string name="stream_system" msgid="7663148785370565134">"Систем"</string>
     <string name="stream_ring" msgid="7550670036738697526">"Ѕвони"</string>
-    <string name="stream_music" msgid="2188224742361847580">"Аудио-визуелни содржини"</string>
+    <string name="stream_music" msgid="2188224742361847580">"Аудиовизуелни содржини"</string>
     <string name="stream_alarm" msgid="16058075093011694">"Аларм"</string>
     <string name="stream_notification" msgid="7930294049046243939">"Известување"</string>
     <string name="stream_bluetooth_sco" msgid="6234562365528664331">"Bluetooth"</string>
@@ -585,7 +596,7 @@
     <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вибрации"</string>
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Исклучи звук"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"Емитување"</string>
-    <string name="stream_notification_unavailable" msgid="4313854556205836435">"Недостапно бидејќи ѕвонењето е исклучено"</string>
+    <string name="stream_notification_unavailable" msgid="4313854556205836435">"Недостапно бидејќи звукот е исклучен"</string>
     <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Недостапно бидејќи е вклучено „Не вознемирувај“"</string>
     <string name="stream_media_unavailable" msgid="6823020894438959853">"Недостапно бидејќи е вклучено „Не вознемирувај“"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Допрете за да вклучите звук."</string>
@@ -593,7 +604,7 @@
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Допрете за да исклучите звук. Можеби ќе се исклучи звукот на услугите за достапност."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Допрете за да се постави на вибрации."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Допрете за да се исклучи звукот."</string>
-    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Контрола на бучавата"</string>
+    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Контрола на шум"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Просторен звук"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Исклучено"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Фиксно"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Активирајте поделен екран со тековната апликација десно"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Активирајте поделен екран со тековната апликација лево"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Префрлете од поделен екран во цел екран"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Префрлете на апликацијата десно или долу при користењето поделен екран"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Префрлете на апликацијата лево или горе при користењето поделен екран"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"При поделен екран: префрлете ги аплик. од едната на другата страна"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Внесување"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Префрлете на следниот јазик"</string>
diff --git a/packages/SystemUI/res/values-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
index 4dd9e73..0d81120 100644
--- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Исклучено"</item>
     <item msgid="5137565285664080143">"Вклучено"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index e2ee3ec..8ce3796 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"സ്ക്രീൻഷോട്ടുകൾ എടുക്കുന്നത് നിങ്ങളുടെ ഐടി അഡ്‌മിൻ ബ്ലോക്ക് ചെയ്തിരിക്കുന്നു"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"എഡിറ്റ് ചെയ്യുക"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"സ്ക്രീൻഷോട്ട് എഡിറ്റ് ചെയ്യുക"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"പങ്കിടുക"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"സ്‌ക്രീൻഷോട്ട് പങ്കിടുക"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"കൂടുതൽ ക്യാപ്‌ചർ ചെയ്യുക"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"സ്ക്രീൻഷോട്ട് ഡിസ്‌മിസ് ചെയ്യുക"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"മുഖം സ്കാൻ ചെയ്യുന്നു"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"അയയ്ക്കുക"</string>
     <string name="cancel" msgid="1089011503403416730">"റദ്ദാക്കുക"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"ആപ്പ് ലോഗോ"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"സ്ഥിരീകരിക്കുക"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"വീണ്ടും ശ്രമിക്കുക"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"പരിശോധിച്ചുറപ്പിക്കൽ റദ്ദാക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"മുഖം തിരിച്ചറിഞ്ഞു. തുടരാൻ അൺലോക്ക് ഐക്കൺ അമർത്തുക."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"പരിശോധിച്ചുറപ്പിച്ചു"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"പരിശോധിച്ചുറപ്പിക്കൽ റദ്ദാക്കുക"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"കൂടുതൽ ഓപ്‌ഷനുകൾ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"പിൻ ഉപയോഗിക്കുക"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"പാറ്റേൺ ഉപയോഗിക്കുക"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"പാസ്‌വേഡ് ഉപയോഗിക്കുക"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"സ്‌റ്റാൻഡേർഡ്"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"ഇടത്തരം"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"കൂടുതൽ"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"കേൾവിക്കുള്ള ഉപകരണങ്ങൾ"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ഉപകരണ മൈക്രോഫോൺ അൺബ്ലോക്ക് ചെയ്യണോ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ഉപകരണ ക്യാമറ അൺബ്ലോക്ക് ചെയ്യണോ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ഉപകരണ ക്യാമറയോ മൈക്രോഫോണോ അൺബ്ലോക്ക് ചെയ്യണോ?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"നീക്കം ചെയ്യുക"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"വിജറ്റ് ചേർക്കുക"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"പൂർത്തിയായി"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"വിജറ്റുകൾ ചേർക്കുക"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"ടാബ്‌ലെറ്റ് അൺലോക്ക് ചെയ്യാതെ തന്നെ നിങ്ങളുടെ പ്രിയപ്പെട്ട ആപ്പ് വിജറ്റുകളിലേക്ക് പെട്ടെന്ന് ആക്‌സസ് നേടുക."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"ലോക്ക് സ്ക്രീനിൽ ഏതെങ്കിലും വിജറ്റ് അനുവദിക്കണോ?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"ക്രമീകരണം തുറക്കുക"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"വർക്ക് ആപ്പുകൾ പുനരാരംഭിക്കണോ?"</string>
@@ -763,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"നിലവിലെ ആപ്പ് വലതുവശത്ത് വരുന്ന രീതിയിൽ സ്ക്രീൻ വിഭജന മോഡിൽ കടക്കുക"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"നിലവിലെ ആപ്പ് ഇടതുവശത്ത് വരുന്ന രീതിയിൽ സ്ക്രീൻ വിഭജന മോഡിൽ കടക്കുക"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"സ്‌ക്രീൻ വിഭജന മോഡിൽ നിന്ന് പൂർണ്ണ സ്ക്രീനിലേക്ക് മാറുക"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുമ്പോൾ വലതുവശത്തെ/താഴത്തെ ആപ്പിലേക്ക് മാറൂ"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുമ്പോൾ ഇടതുവശത്തെ/മുകളിലെ ആപ്പിലേക്ക് മാറൂ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"സ്‌ക്രീൻ വിഭജന മോഡിൽ: ഒരു ആപ്പിൽ നിന്ന് മറ്റൊന്നിലേക്ക് മാറുക"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ഇൻപുട്ട്"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"അടുത്ത ഭാഷയിലേക്ക് മാറുക"</string>
diff --git a/packages/SystemUI/res/values-ml/tiles_states_strings.xml b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
index 18e7b29..609fdde 100644
--- a/packages/SystemUI/res/values-ml/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"ഓഫാണ്"</item>
     <item msgid="5137565285664080143">"ഓണാണ്"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"ലഭ്യമല്ല"</item>
+    <item msgid="3079622119444911877">"ഓഫാണ്"</item>
+    <item msgid="3028994095749238254">"ഓണാണ്"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 84ff51b..1a2e4b1f 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Таны IT админ дэлгэцийн агшин авахыг блоклосон байна"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Засах"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Дэлгэцийн агшныг засах"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Хуваалцах"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Дэлгэцийн агшныг хуваалцах"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Ихийг багтаасан зураг авах"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Дэлгэцийн агшныг хаах"</string>
@@ -117,7 +116,7 @@
     <string name="screenrecord_continue" msgid="4055347133700593164">"Эхлүүлэх"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Дэлгэцийг бичиж байна"</string>
     <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Дэлгэц болон аудиог бичиж байна"</string>
-    <string name="screenrecord_taps_label" msgid="1595690528298857649">"Дэлгэц дээр мэдрэгчийг харуулах"</string>
+    <string name="screenrecord_taps_label" msgid="1595690528298857649">"Дэлгэц дээр хүрэхийг харуулах"</string>
     <string name="screenrecord_stop_label" msgid="72699670052087989">"Зогсоох"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"Хуваалцах"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"Дэлгэцийн бичлэгийг хадгалсан"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Скан хийх нүүр царай"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Илгээх"</string>
     <string name="cancel" msgid="1089011503403416730">"Цуцлах"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Аппын лого"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Баталгаажуулах"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Дахин оролдох"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Нотолгоог цуцлахын тулд товшино уу"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Царайг таньсан. Үргэлжлүүлэх бол түгжээг тайлах дүрсийг дар."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Баталгаажуулагдсан"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Баталгаажуулалтыг цуцлах"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Бусад сонголт"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ПИН ашиглах"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Хээ ашиглах"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Нууц үг ашиглах"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Стандарт"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Дунд зэрэг"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Өндөр"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Төхөөрөмжийн микрофоныг блокоос гаргах уу?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Төхөөрөмжийн камерыг блокоос гаргах уу?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Төхөөрөмжийн камер болон микрофоныг блокоос гаргах уу?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Хасах"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Виджет нэмэх"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Болсон"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Виджетүүд нэмэх"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Таблетынхаа түгжээг тайлалгүйгээр дуртай аппынхаа виджетүүдэд шуурхай хандах эрх аваарай."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Түгжээтэй дэлгэц дээр дурын виджетийг зөвшөөрөх үү?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Тохиргоог нээх"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Ажлын аппыг үргэлжлүүлэх үү?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Энэ төхөөрөмжийг таны эцэг эх удирддаг. Таны эцэг эх таны хэрэглэдэг апп, байршил, дэлгэцийн цаг зэрэг мэдээллийг харж, удирдах боломжтой."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent-р түгжээгүй байлгасан"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Төхөөрөмжийг түгжсэн. Хэт олон удаа баталгаажуулах оролдлого хийсэн"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Төхөөрөмжийг түгжсэн\nБаталгаажуулж чадсангүй"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Дууны тохиргоо"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Медиад автоматаар тайлбар нэмэх"</string>
@@ -669,7 +678,7 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Төлөв:&lt;/b&gt; Доогуур зэрэглэл хийсэн"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"Харилцан ярианы дээд талд болон түгжигдсэн дэлгэц дээр профайл зураг байдлаар харуулна"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"Харилцан ярианы мэдэгдлийн дээд талд болон түгжигдсэн дэлгэц дээр профайл зураг байдлаар харуулах бөгөөд бөмбөлөг хэлбэрээр харагдана"</string>
-    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Харилцан ярианы мэдэгдлийн дээд талд болон түгжигдсэн дэлгэц дээр профайл зураг байдлаар харуулах бөгөөд Бүү саад бол горимыг тасалдуулна"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"Харилцан ярианы мэдэгдлийн дээд талд болон түгжээтэй дэлгэц дээр профайл зураг байдлаар харуулах бөгөөд Бүү саад бол горимыг тасалдуулна"</string>
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"Харилцан ярианы мэдэгдлийн дээд талд болон түгжигдсэн дэлгэц дээр профайл зураг байдлаар харуулах бөгөөд бөмбөлөг хэлбэрээр харагдана. Бүү саад бол горимыг тасалдуулна"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Чухал"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь харилцан ярианы онцлогуудыг дэмждэггүй"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Одоогийн аппаар баруун гар талд дэлгэц хуваахад орох"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Одоогийн аппаар зүүн гар талд дэлгэц хуваахад орох"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Дэлгэц хуваахаас бүтэн дэлгэц рүү сэлгэх"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Дэлгэц хуваахыг ашиглаж байхдаа баруун эсвэл доор байх апп руу сэлгэ"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Дэлгэц хуваахыг ашиглаж байхдаа зүүн эсвэл дээр байх апп руу сэлгэ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Дэлгэц хуваах үеэр: аппыг нэгээс нөгөөгөөр солих"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Оролт"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Дараагийн хэл рүү сэлгэх"</string>
diff --git a/packages/SystemUI/res/values-mn/tiles_states_strings.xml b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
index 95f835e..cfaf693 100644
--- a/packages/SystemUI/res/values-mn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Унтраалттай"</item>
     <item msgid="5137565285664080143">"Асаалттай"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 7372368..2e21fd0 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"तुमच्या आयटी ॲडमिनने स्क्रीनशॉट घेणे ब्लॉक केले आहे"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"संपादित करा"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"स्क्रीनशॉट संपादित करा"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"शेअर करा"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"स्क्रीनशॉट शेअर करा"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"आणखी गोष्टी कॅप्चर करा"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"स्क्रीनशॉट डिसमिस करा"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"चेहरा स्कॅन करत आहे"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"पाठवा"</string>
     <string name="cancel" msgid="1089011503403416730">"रद्द करा"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"अ‍ॅप लोगो"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"कन्फर्म करा"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"पुन्हा प्रयत्न करा"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ऑथेंटिकेशन रद्द करण्यासाठी टॅप करा"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"चेहरा ओळखला आहे. पुढे सुरू ठेवण्यासाठी अनलॉक करा आयकन प्रेस करा."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ऑथेंटिकेशन केलेले"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ऑथेंटिकेशन रद्द करा"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"अधिक पर्याय"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"पिन वापरा"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"पॅटर्न वापरा"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"पासवर्ड वापरा"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"साधारण"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"मध्यम"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"उच्च"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"डिव्हाइसचा मायक्रोफोन अनब्लॉक करायचा आहे का?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"डिव्हाइसचा कॅमेरा अनब्लॉक करायचा आहे का?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"डिव्हाइसचा कॅमेरा आणि मायक्रोफोन अनब्लॉक करायचा आहे का?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"काढून टाका"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"विजेट जोडा"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"पूर्ण झाले"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"विजेट जोडा"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"तुमचा टॅबलेट अनलॉक न करता तुमच्या आवडत्या ॲपची विजेट झटपट अ‍ॅक्सेस करा."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"लॉक स्क्रीनवर कोणत्याही विजेटला अनुमती द्यायची आहे का?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"सेटिंग्ज उघडा"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"वर्क ॲप्स पुन्हा सुरू करायची?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"हे डिव्हाइस तुमच्या पालकाने व्यवस्थापित केले आहे. तुम्ही वापरत असलेली ॲप्स, तुमचे स्थान आणि तुमचा स्क्रीन वेळ यांसारखी माहिती तुमचे पालक पाहू आणि व्यवस्‍थापित करू शकतात."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent ने अनलॉक ठेवले"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"डिव्हाइस लॉक केले होते, ऑथेंटिकेशनचे खूप वेळा प्रयत्न केले गेले"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"डिव्हाइस लॉक केले आहे\nऑथेंटिकेशन यशस्वी झाले नाही"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"आवाज सेटिंग्ज"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"मीडियाला आपोआप सबटायटल द्या"</string>
@@ -669,7 +678,7 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;स्थिती&lt;/b&gt; ला थोडी कमी म्हणून रँक केले गेले"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"संभाषण सूचनांच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"संभाषण सूचनांच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते, बबल म्हणून दिसते"</string>
-    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"संभाषण सूचनांच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते, व्यत्यय आणू नका यामध्ये अडथळा आणते"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"संभाषण नोटिफिकेशनच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते, व्यत्यय आणू नका यामध्ये अडथळा आणते"</string>
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"संभाषण सूचनांच्या वरती आणि लॉक स्क्रीनवरील प्रोफाइल फोटो म्हणून दिसते, बबल म्हणून दिसते, व्यत्यय आणू नका यामध्ये अडथळा आणते"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"प्राधान्य"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> हे संभाषण वैशिष्ट्यांना सपोर्ट करत नाही"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"उजव्या बाजूला सध्याचे अ‍ॅप असलेल्या स्प्लिट स्क्रीनवर जा"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"डाव्या बाजूला सध्याचे अ‍ॅप असलेल्या स्प्लिट स्क्रीनवर जा"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"स्प्लिट स्क्रीनवरून फुल स्क्रीनवर स्विच करा"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रीन वापरताना उजवीकडील किंवा खालील अ‍ॅपवर स्विच करा"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रीन वापरताना डावीकडील किंवा वरील अ‍ॅपवर स्विच करा"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रीनदरम्यान: एक अ‍ॅप दुसऱ्या अ‍ॅपने बदला"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"इनपुट"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"पुढील भाषेवर स्विच करा"</string>
@@ -943,7 +950,7 @@
     <string name="privacy_type_media_projection" msgid="8136723828804251547">"स्क्रीन रेकॉर्डिंग"</string>
     <string name="music_controls_no_title" msgid="4166497066552290938">"शीर्षक नाही"</string>
     <string name="inattentive_sleep_warning_title" msgid="3891371591713990373">"स्टँडबाय"</string>
-    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"फॉंट आकार"</string>
+    <string name="font_scaling_dialog_title" msgid="6273107303850248375">"फॉंटचा आकार"</string>
     <string name="font_scaling_smaller" msgid="1012032217622008232">"आणखी लहान करा"</string>
     <string name="font_scaling_larger" msgid="5476242157436806760">"आणखी मोठे करा"</string>
     <string name="magnification_window_title" msgid="4863914360847258333">"मॅग्निफिकेशन विंडो"</string>
diff --git a/packages/SystemUI/res/values-mr/tiles_states_strings.xml b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
index 6902a2f..abb7ace 100644
--- a/packages/SystemUI/res/values-mr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"बंद आहे"</item>
     <item msgid="5137565285664080143">"सुरू आहे"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 3839df3..9ae774f 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Pengambilan tangkapan skrin disekat oleh pentadbir IT anda"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Edit"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Edit tangkapan skrin"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Kongsi"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Kongsi tangkapan skrin"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Tangkap imej lagi"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ketepikan tangkapan skrin"</string>
@@ -106,8 +105,8 @@
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Memproses rakaman skrin"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Pemberitahuan breterusan untuk sesi rakaman skrin"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Mulakan Rakaman?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Apabila anda membuat rakaman, Android boleh mengakses apa-apa sahaja yang boleh dilihat pada skrin anda atau dimainkan pada peranti anda. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Semasa anda merakam apl, Android boleh mengakses apa-apa sahaja yang ditunjukan atau dimainkan pada apl itu. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Apabila anda merakam, Android boleh mengakses apa-apa sahaja yang kelihatan pada skrin anda atau dimainkan pada peranti anda. Oleh hal yang demikian, berhati-hati apabila memasukkan kata laluan, butiran pembayaran, mesej, foto, audio dan video."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Semasa anda merakam apl, Android boleh mengakses apa-apa sahaja yang ditunjukkan atau dimainkan pada apl itu. Oleh hal yang demikian, berhati-hati ketika memasukkan kata laluan, butiran pembayaran, mesej, foto, audio dan video."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Mulakan rakaman"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Rakam audio"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audio peranti"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Mengimbas wajah"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Hantar"</string>
     <string name="cancel" msgid="1089011503403416730">"Batal"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logo apl"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Sahkan"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Cuba lagi"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Ketik untuk membatalkan pengesahan"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Wajah dicam. Tekan ikon buka kunci untuk meneruskan."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Disahkan"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Batalkan Pengesahan"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Lagi Pilihan"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gunakan PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gunakan corak"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Gunakan kata laluan"</string>
@@ -328,7 +329,7 @@
     <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Apl kerja"</string>
     <string name="quick_settings_work_mode_paused_state" msgid="6681788236383735976">"Dijeda"</string>
     <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Cahaya Malam"</string>
-    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Dihidupkan pd senja"</string>
+    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Hidup waktu senja"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Hingga matahari terbit"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Dihidupkan pada <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Hingga <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Sederhana"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Tinggi"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Peranti pendengaran"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Nyahsekat mikrofon peranti?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Nyahsekat kamera peranti?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Nyahsekat kamera dan mikrofon peranti?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Alih keluar"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Tambahkan widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Selesai"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Tambahkan widget"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Dapatkan akses pantas kepada widget apl kegemaran anda tanpa membuka kunci tablet anda."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Benarkan sebarang widget pada skrin kunci?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Buka tetapan"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Nyahjeda apl kerja?"</string>
@@ -471,8 +481,8 @@
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Mula"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> telah melumpuhkan pilihan ini"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Mulakan penghantaran?"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Apabila anda membuat penghantaran, Android boleh mengakses apa-apa sahaja yang boleh dilihat pada skrin anda atau dimainkan pada peranti anda. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Apabila anda menghantar apl, Android boleh mengakses apa-apa sahaja yang ditunjukan atau dimainkan pada apl itu. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Apabila anda membuat penghantaran, Android boleh mengakses apa-apa sahaja yang kelihatan pada skrin atau dimainkan pada peranti anda. Oleh hal yang demikian, berhati-hati apabila memasukkan kata laluan, butiran pembayaran, mesej, foto, audio dan video."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Apabila anda menghantar apl, Android boleh mengakses apa-apa sahaja yang ditunjukkan atau dimainkan pada apl itu. Oleh hal yang demikian, berhati-hati apabila memasukkan kata laluan, butiran pembayaran, mesej, foto, audio dan video."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Mulakan penghantaran"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Mulakan perkongsian?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Apabila anda membuat perkongsian, rakaman atau penghantaran, Android boleh mengakses apa-apa sahaja yang boleh dilihat pada skrin anda atau dimainkan pada peranti anda. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string>
@@ -540,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Peranti ini diurus oleh ibu bapa anda. Ibu bapa anda dapat melihat dan mengurus maklumat seperti apl yang anda gunakan, lokasi dan masa skrin anda."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Dibiarkan tidak berkunci oleh TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Peranti telah dikunci, terlalu banyak percubaan pengesahan"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Peranti dikunci\nPengesahan gagal"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Tetapan bunyi"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Sari kata media automatik"</string>
@@ -765,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Masuk skrin pisah dengan apl semasa pada sisi kanan"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Masuk skrin pisah dengan apl semasa pada sisi kiri"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Beralih daripada skrin pisah kepada skrin penuh"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Tukar kepada apl di sebelah kanan/bawah semasa menggunakan skrin pisah"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Tukar kepada apl di sebelah kiri/atas semasa menggunakan skrin pisah"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Semasa skrin pisah: gantikan apl daripada satu apl kepada apl lain"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Beralih kepada bahasa seterusnya"</string>
@@ -1240,7 +1246,7 @@
     <string name="home_quick_affordance_unavailable_configure_the_app" msgid="604424593994493281">"• Sekurang-kurangnya satu peranti atau panel peranti tersedia"</string>
     <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Pilih apl nota lalai untuk menggunakan pintasan pengambilan nota"</string>
     <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Pilih apl"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Pintasan sentuh &amp; tahan"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Sentuh &amp; tahan pintasan"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Batal"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Tukar skrin sekarang"</string>
     <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Buka telefon"</string>
diff --git a/packages/SystemUI/res/values-ms/tiles_states_strings.xml b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
index a280916..174e416e 100644
--- a/packages/SystemUI/res/values-ms/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"Mati"</item>
     <item msgid="5137565285664080143">"Hidup"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"Tidak tersedia"</item>
+    <item msgid="3079622119444911877">"Mati"</item>
+    <item msgid="3028994095749238254">"Hidup"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index dd3e3a7..1249885 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ဖန်သားပြင်ဓာတ်ပုံရိုက်ခြင်းကို သင့် IT စီမံခန့်ခွဲသူက ပိတ်ထားသည်"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"တည်းဖြတ်ရန်"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"ဖန်သားပြင်ဓာတ်ပုံကို တည်းဖြတ်သည်"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"မျှဝေရန်"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"ဖန်သားပြင်ဓာတ်ပုံကို မျှဝေနိုင်သည်"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"နောက်ထပ် ရိုက်ကူးရန်"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ဖန်သားပြင်ဓာတ်ပုံကို ပယ်သည်"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"မျက်နှာ စကင်ဖတ်နေသည်"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ပို့ရန်"</string>
     <string name="cancel" msgid="1089011503403416730">"မလုပ်တော့"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"အက်ပ်လိုဂို"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"အတည်ပြုရန်"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ထပ်စမ်းကြည့်ရန်"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"အထောက်အထားစိစစ်ခြင်းကို ပယ်ဖျက်ရန် တို့ပါ"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"မျက်နှာ မှတ်မိသည်။ ရှေ့ဆက်ရန် လော့ခ်ဖွင့်သင်္ကေတကို နှိပ်ပါ။"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"အထောက်အထားစိစစ်ပြီးပြီ"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"အထောက်အထားစိစစ်ခြင်းကို ပယ်ဖျက်ရန်"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"နောက်ထပ်ရွေးစရာများ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ပင်နံပါတ်သုံးရန်"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ပုံစံကို သုံးရန်"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"စကားဝှက် သုံးရန်"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"ပုံမှန်"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"အသင့်အတင့်"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"များ"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"နားကြားကိရိယာ"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"စက်၏မိုက်ခရိုဖုန်းကို ပြန်ဖွင့်မလား။"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"စက်၏ကင်မရာကို ပြန်ဖွင့်မလား။"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"စက်၏ကင်မရာနှင့် မိုက်ခရိုဖုန်းကို ပြန်ဖွင့်မလား။"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"ဖယ်ရှားရန်"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ဝိဂျက်ထည့်ရန်"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"ပြီးပြီ"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"ဝိဂျက်များ ထည့်ရန်"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"တက်ဘလက်မဖွင့်ဘဲ သင့်အကြိုက်ဆုံး အက်ပ်ဝိဂျက်များကို အမြန်သုံးခွင့် ရယူပါ။"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"လော့ခ်မျက်နှာပြင်ရှိ ဝိဂျက်အားလုံးကို ခွင့်ပြုမလား။"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"ဆက်တင်များ ဖွင့်ရန်"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"အလုပ်သုံးအက်ပ် ပြန်ဖွင့်မလား။"</string>
@@ -540,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ဤစက်ပစ္စည်းကို သင့်မိဘက စီမံခန့်ခွဲသည်။ သင့်မိဘက သင်သုံးသောအက်ပ်များ၊ သင်၏တည်နေရာနှင့် အသုံးပြုချိန် ကဲ့သို့သော အချက်အလက်များကို မြင်နိုင်ပြီး စီမံခန့်ခွဲနိုင်သည်။"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent ဖြင့် ဆက်ဖွင့်ထားရန်"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"စက်လော့ခ်ကျနေသည်၊ အထောက်အထားစိစစ်ရန် ကြိုးပမ်းမှုအကြိမ်ရေ များလွန်းသည်"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"စက်လော့ခ်ကျနေသည်\nအထောက်အထားစိစစ်၍ မရပါ"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>။ <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"အသံဆက်တင်များ"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"အလိုအလျောက် စာတန်းထိုးရန်"</string>
@@ -576,7 +584,7 @@
     <string name="screen_pinning_exit" msgid="4553787518387346893">"အက်ပ်ကို ပင်ဖြုတ်လိုက်သည်"</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"ဖုန်းခေါ်ရန်"</string>
     <string name="stream_system" msgid="7663148785370565134">"စနစ်"</string>
-    <string name="stream_ring" msgid="7550670036738697526">"အသံမြည်စေသည်"</string>
+    <string name="stream_ring" msgid="7550670036738697526">"ဖုန်းမြည်သံ"</string>
     <string name="stream_music" msgid="2188224742361847580">"မီဒီယာ"</string>
     <string name="stream_alarm" msgid="16058075093011694">"နှိုးစက်"</string>
     <string name="stream_notification" msgid="7930294049046243939">"အကြောင်းကြားချက်"</string>
@@ -598,8 +606,8 @@
     <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ဆူညံသံ ထိန်းချုပ်ရန်"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"ထောင့်စုံအော်ဒီယို"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"ပိတ်"</string>
-    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ဖွင့်ပြီးပြီ"</string>
-    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ဦးခေါင်းလှုပ်ရှားမှု စောင့်ကြည့်ခြင်း"</string>
+    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ပုံသေ"</string>
+    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"ခေါင်းလှုပ်ရှားမှု စောင့်ကြည့်ခြင်း"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"ဖုန်းခေါ်သံမုဒ်သို့ ပြောင်းရန် တို့ပါ"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"အသံပိတ်ရန်"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"အသံဖွင့်ရန်"</string>
@@ -612,7 +620,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s အသံပိတ်ရန်"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s အသံပြန်ဖွင့်ရန်"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> ကို ဖွင့်နေသည်"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"အောက်တွင်အသံဖွင့်မည်"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"အသံဖွင့်မည့်နေရာ"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"စနစ် UI ဖမ်းစက်"</string>
     <string name="status_bar" msgid="4357390266055077437">"အခြေအနေပြနေရာ"</string>
     <string name="demo_mode" msgid="263484519766901593">"စနစ် UI စရုပ်ပြမုဒ်"</string>
@@ -669,7 +677,7 @@
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;အခြေအနေ-&lt;/b&gt; အဆင့်လျှော့ထားသည်"</string>
     <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းတွင် ပြ၍ လော့ခ်မျက်နှာပြင်တွင် ပရိုဖိုင်ပုံအဖြစ် ပြသည်"</string>
     <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းတွင် ပြ၍ လော့ခ်မျက်နှာပြင်တွင် ပရိုဖိုင်ပုံအဖြစ် ပြကာ ပူဖောင်းကွက်အဖြစ် မြင်ရသည်"</string>
-    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းနှင့် ပရိုဖိုင်ပုံအဖြစ် လော့ခ်မျက်နှာပြင်တွင် ပြသည်။ ပူဖောင်းကွက်အဖြစ် မြင်ရပြီး ‘မနှောင့်ယှက်ရ’ ကို ကြားဖြတ်သည်"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းတွင်နှင့် လော့ခ်မျက်နှာပြင်တွင် ပရိုဖိုင်ပုံအဖြစ်  ပြသည်။ ‘မနှောင့်ယှက်ရ’ ကို ကြားဖြတ်သည်"</string>
     <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"စကားဝိုင်း အကြောင်းကြားချက်များ၏ ထိပ်ပိုင်းနှင့် ပရိုဖိုင်ပုံအဖြစ် လော့ခ်မျက်နှာပြင်တွင် ပြသည်။ ပူဖောင်းကွက်အဖြစ် မြင်ရပြီး ‘မနှောင့်ယှက်ရ’ ကို ကြားဖြတ်သည်"</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"ဦးစားပေး"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> က စကားဝိုင်းဝန်ဆောင်မှုများကို မပံ့ပိုးပါ"</string>
@@ -765,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"လက်ရှိအက်ပ်ကို မျက်နှာပြင် ခွဲ၍ပြသမှု၏ ညာဘက်တွင်ထည့်ရန်"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"လက်ရှိအက်ပ်ကို မျက်နှာပြင် ခွဲ၍ပြသမှု၏ ဘယ်ဘက်တွင်ထည့်ရန်"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"မျက်နှာပြင် ခွဲ၍ပြသမှုမှ မျက်နှာပြင်အပြည့်သို့ ပြောင်းရန်"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"မျက်နှာပြင်ခွဲ၍ပြသခြင်း သုံးစဉ် ညာ (သို့) အောက်ရှိအက်ပ်သို့ ပြောင်းရန်"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းသုံးစဉ် ဘယ် (သို့) အထက်ရှိအက်ပ်သို့ ပြောင်းရန်"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"မျက်နှာပြင် ခွဲ၍ပြသစဉ်- အက်ပ်တစ်ခုကို နောက်တစ်ခုနှင့် အစားထိုးရန်"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"စာရိုက်ခြင်း"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"နောက်ဘာသာစကားသို့ ပြောင်းရန်"</string>
@@ -1113,7 +1119,7 @@
     <string name="media_output_broadcast_last_update_error" msgid="5484328807296895491">"သိမ်း၍မရပါ။"</string>
     <string name="media_output_broadcast_code_hint_no_less_than_min" msgid="4663836092607696185">"အနည်းဆုံး အက္ခရာ ၄ လုံး သုံးရန်"</string>
     <string name="media_output_broadcast_edit_hint_no_more_than_max" msgid="3923625800037673922">"အက္ခရာ <xliff:g id="LENGTH">%1$d</xliff:g> လုံးအောက် သုံးရန်"</string>
-    <string name="build_number_clip_data_label" msgid="3623176728412560914">"တည်ဆောက်မှုနံပါတ်"</string>
+    <string name="build_number_clip_data_label" msgid="3623176728412560914">"တည်ဆောက်ပုံအမှတ်"</string>
     <string name="build_number_copy_toast" msgid="877720921605503046">"တည်ဆောက်မှုနံပါတ်ကို ကလစ်ဘုတ်သို့ မိတ္တူကူးပြီးပါပြီ။"</string>
     <string name="basic_status" msgid="2315371112182658176">"စကားဝိုင်းကို ဖွင့်ရန်"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"စကားဝိုင်း ဝိဂျက်များ"</string>
diff --git a/packages/SystemUI/res/values-my/tiles_states_strings.xml b/packages/SystemUI/res/values-my/tiles_states_strings.xml
index ce10c42..f665a00a 100644
--- a/packages/SystemUI/res/values-my/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-my/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"ပိတ်"</item>
     <item msgid="5137565285664080143">"ဖွင့်"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"မရနိုင်ပါ"</item>
+    <item msgid="3079622119444911877">"ပိတ်"</item>
+    <item msgid="3028994095749238254">"ဖွင့်"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 23c3f45..0f9bb46 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Funksjonen for å ta skjermdumper er blokkert av IT-administratoren din"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Rediger"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Rediger skjermdumpen"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Del"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Del skjermdumpen"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Utvidet skjermdump"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Avvis skjermdumpen"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skanning av ansikt"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Send"</string>
     <string name="cancel" msgid="1089011503403416730">"Avbryt"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Applogo"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bekreft"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Prøv på nytt"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Trykk for å avbryte autentiseringen"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet er gjenkjent. Trykk på lås opp-ikon for å fortsette"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentisert"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Avbryt autentisering"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Flere alternativer"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Bruk PIN-kode"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Bruk mønster"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Bruk passord"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Middels"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Høy"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vil du oppheve blokkeringen av enhetsmikrofonen?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vil du oppheve blokkeringen av enhetskameraet?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vil du oppheve blokkeringen av enhetskameraet og -mikrofonen?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Fjern"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Legg til modul"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Ferdig"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Legg til moduler"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Få rask tilgang til appmoduler uten å låse opp nettbrettet."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Vil du tillate alle moduler på låseskjermen?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Åpne innstillingene"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Vil du slå på jobbapper igjen?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Denne enheten administreres av forelderen din. Forelderen din kan se og administrere informasjon, for eksempel appene du bruker, posisjonen din og skjermtiden din."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Holdes opplåst med TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Enheten var låst – for mange autentiseringsforsøk"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Enheten er låst\nKunne ikke autentisere"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Lydinnstillinger"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatisk medieteksting"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Åpne delt skjerm med den aktive appen til høyre"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Åpne delt skjerm med den aktive appen til venstre"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Bytt fra delt skjerm til fullskjerm"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bytt til appen til høyre eller under mens du bruker delt skjerm"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bytt til appen til venstre eller over mens du bruker delt skjerm"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"I delt skjerm: Bytt ut en app"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Skrivespråk"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Bytt til neste språk"</string>
@@ -859,7 +866,7 @@
     <string name="data_connection_no_internet" msgid="691058178914184544">"Ingen internettilkobling"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="536838345505030893">"Åpne <xliff:g id="ID_1">%s</xliff:g>-innstillingene."</string>
     <string name="accessibility_quick_settings_edit" msgid="1523745183383815910">"Endre rekkefølgen på innstillingene."</string>
-    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"Av/på-meny"</string>
+    <string name="accessibility_quick_settings_power_menu" msgid="6820426108301758412">"På/av-meny"</string>
     <string name="accessibility_quick_settings_page" msgid="7506322631645550961">"Side <xliff:g id="ID_1">%1$d</xliff:g> av <xliff:g id="ID_2">%2$d</xliff:g>"</string>
     <string name="tuner_lock_screen" msgid="2267383813241144544">"Låseskjerm"</string>
     <string name="finder_active" msgid="7907846989716941952">"Du kan finne denne telefonen med Finn enheten min, selv når den er slått av"</string>
@@ -1240,7 +1247,7 @@
     <string name="home_quick_affordance_unavailable_configure_the_app" msgid="604424593994493281">"• Minst én enhet eller ett enhetspanel er tilgjengelig"</string>
     <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Velg en standard notatapp du vil bruke med notatsnarveien"</string>
     <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Velg app"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Trykk på og hold inne snarveien"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Trykk på snarveien og hold den inne"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Avbryt"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Bytt skjerm nå"</string>
     <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Åpne telefonen"</string>
diff --git a/packages/SystemUI/res/values-nb/tiles_states_strings.xml b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
index 71160d0..af00423 100644
--- a/packages/SystemUI/res/values-nb/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Av"</item>
     <item msgid="5137565285664080143">"På"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 23543c2..5f51a91 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"तपाईंको IT एड्मिनले स्क्रिनसट लिने सुविधा ब्लक गर्नुभएको छ"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"सम्पादन गर्नुहोस्"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"स्क्रिनसट सम्पादन गर्नुहोस्"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"सेयर गर्नुहोस्"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"स्क्रिनसट सेयर गर्नुहोस्"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"अन्य कुराहरू खिच्नुहोस्"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"स्क्रिनसट हटाउनुहोस्"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"अनुहार स्क्यान गर्दै"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"पठाउनुहोस्"</string>
     <string name="cancel" msgid="1089011503403416730">"रद्द गर्नुहोस्"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"एपको लोगो"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"पुष्टि गर्नुहोस्"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"फेरि प्रयास गर्नुहोस्"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"प्रमाणीकरण रद्द गर्न ट्याप गर्नुहोस्"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"अनुहार पहिचान गरियो। जारी राख्न अनलक आइकनमा थिच्नुहोस्।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"प्रमाणीकरण गरियो"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"प्रमाणीकरण रद्द गर्नुहोस्"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"थप विकल्पहरू"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN प्रयोग गर्नुहोस्"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ढाँचा प्रयोग गर्नुहोस्"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"पासवर्ड प्रयोग गर्नुहोस्"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"डिफल्ट"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"मध्यम"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"उच्च"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"डिभाइसको माइक्रोफोन अनब्लक गर्ने हो?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"डिभाइसको क्यामेरा अनब्लक गर्ने हो?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"डिभाइसको क्यामेरा र माइक्रोफोन अनब्लक गर्ने हो?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"हटाउनुहोस्"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"विजेट हाल्नुहोस्"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"पूरा भयो"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"विजेट हाल्नुहोस्"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"ट्याब्लेट अनलक नगरिकनै आफूलाई मन पर्ने एपका विजेटहरू तुरुन्तै एक्सेस गर्नुहोस्।"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"लक स्क्रिनमा कुनै विजेट देखाउने हो?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"सेटिङ खोल्नुहोस्"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"कामसम्बन्धी एपहरू अनपज गर्ने हो?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"यो डिभाइस तपाईंका अभिभावक व्यवस्थापन गर्नुहुन्छ। तपाईंका अभिभावक तपाईंले प्रयोग गर्ने एप, तपाईंको स्थान र तपाईंले यन्त्र चलाएर बिताउने समय जस्ता जानकारी हेर्न तथा व्यवस्थापन गर्न सक्नुहुन्छ।"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent ले खुला राखेको"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"डिभाइस लक गरिएको छ, प्रमाणीकरण गर्ने निकै धेरै प्रयास गरिएका छन्"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"डिभाइस लक गरिएको छ\nप्रमाणीकरण गर्न सकिएन"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"ध्वनिसम्बन्धी सेटिङहरू"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"मिडियाको स्वत: क्याप्सन बनाउनुहोस्"</string>
@@ -595,7 +604,7 @@
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। म्यूट गर्नाका लागि ट्याप गर्नुहोस्। पहुँच सम्बन्धी सेवाहरू म्यूट हुन सक्छन्।"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। कम्पन मोडमा सेट गर्न ट्याप गर्नुहोस्।"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। म्यूट गर्न ट्याप गर्नुहोस्।"</string>
-    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"नोइज कन्ट्रोल"</string>
+    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"न्वाइज कन्ट्रोल"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"स्पेसियल अडियो"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"अफ छ"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"निश्चित"</string>
@@ -612,7 +621,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s म्युट गर्नुहोस्"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s अनम्युट गर्नुहोस्"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> प्ले गरिँदै छ"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"अडियो प्ले भइरहने छ"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"अडियो यसमा प्ले हुने छ"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"सिस्टम UI ट्युनर"</string>
     <string name="status_bar" msgid="4357390266055077437">"स्थिति पट्टी"</string>
     <string name="demo_mode" msgid="263484519766901593">"सिस्टम UI को डेमो मोड"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"हालको एप दायाँतर्फ रहने गरी स्प्लिट स्क्रिन मोड सुरु गर्नुहोस्"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"हालको एप बायाँतर्फ रहने गरी स्प्लिट स्क्रिन मोड सुरु गर्नुहोस्"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"स्प्लिट स्क्रिनको साटो फुल स्क्रिन प्रयोग गर्नुहोस्"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रिन प्रयोग गर्दै गर्दा दायाँ वा तलको एप चलाउनुहोस्"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रिन प्रयोग गर्दै गर्दा बायाँ वा माथिको एप चलाउनुहोस्"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रिन प्रयोग गरिएका बेला: एउटा स्क्रिनमा भएको एप अर्कोमा लैजानुहोस्"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"इनपुट"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"अर्को भाषा प्रयोग गर्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-ne/tiles_states_strings.xml b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
index 1977706..005a473 100644
--- a/packages/SystemUI/res/values-ne/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"अफ छ"</item>
     <item msgid="5137565285664080143">"अन छ"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 976d2ab..1f780b3 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Screenshots maken is geblokkeerd door je IT-beheerder"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Bewerken"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Screenshot bewerken"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Delen"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Screenshot delen"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Meer opnemen"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Screenshot sluiten"</string>
@@ -106,8 +105,8 @@
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Schermopname verwerken"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Doorlopende melding voor een schermopname-sessie"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Opname starten?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Als je opneemt, heeft Android toegang tot alles dat zichtbaar is op je scherm of wordt afgespeeld op je apparaat. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Als je een app opneemt, heeft Android toegang tot alles dat wordt getoond of afgespeeld in die app. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Terwijl je aan het opnemen bent, heeft Android toegang tot alles dat zichtbaar is op je scherm of wordt afgespeeld op je apparaat. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Terwijl je een app aan het opnemen bent, heeft Android toegang tot alles dat wordt getoond of afgespeeld in die app. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Opname starten"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Audio opnemen"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Audio van apparaat"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Gezicht scannen"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Verzenden"</string>
     <string name="cancel" msgid="1089011503403416730">"Annuleren"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"App-logo"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bevestigen"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Opnieuw proberen"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Tik om de verificatie te annuleren"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Gezicht herkend. Druk op het ontgrendelicoon."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Geverifieerd"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Verificatie annuleren"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Meer opties"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Pincode gebruiken"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Patroon gebruiken"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Wachtwoord gebruiken"</string>
@@ -362,11 +363,19 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standaard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Gemiddeld"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Hoog"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Blokkeren van apparaatmicrofoon opheffen?"</string>
-    <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Blokkeren van apparaatcamera opheffen?"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
+    <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Microfoon van apparaat niet meer blokkeren?"</string>
+    <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Apparaatcamera niet meer blokkeren?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Blokkeren van apparaatcamera en -microfoon opheffen?"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Hiermee hef je de toegangsblokkering op voor alle apps en services die rechten hebben om je microfoon te gebruiken."</string>
-    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Hiermee hef je de toegangsblokkering op voor alle apps en services die rechten hebben om je camera te gebruiken."</string>
+    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Alle apps en services die je microfoon mogen gebruiken, krijgen dan toegang tot de microfoon."</string>
+    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Alle apps en services die je camera mogen gebruiken, krijgen dan toegang tot de camera."</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Hiermee hef je de toegangsblokkering op voor alle apps en services die rechten hebben om je camera of microfoon te gebruiken."</string>
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Microfoon is geblokkeerd"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Camera is geblokkeerd"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Verwijderen"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Widget toevoegen"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Klaar"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Widgets toevoegen"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Krijg snel toegang tot je favoriete app-widgets zonder je tablet te ontgrendelen."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Elke widget toestaan op het vergrendelscherm?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Instellingen openen"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Werk-apps hervatten?"</string>
@@ -472,7 +483,7 @@
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Voor <xliff:g id="APP_NAME">%1$s</xliff:g> staat deze optie uit"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Casten starten?"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Als je cast, heeft Android toegang tot alles dat zichtbaar is op je scherm of wordt afgespeeld op je apparaat. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Als je een app cast, heeft Android toegang tot alles dat zichtbaar is op je scherm of wordt afgespeeld op je apparaat. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Als je een app cast, heeft Android toegang tot alles dat wordt getoond of afgespeeld in die app. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Casten starten"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Delen starten?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Als je deelt, opneemt of cast, heeft Android toegang tot alles dat zichtbaar is op je scherm of wordt afgespeeld op je apparaat. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
@@ -626,7 +637,7 @@
     <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Ontgrendelen om te gebruiken"</string>
     <string name="wallet_error_generic" msgid="257704570182963611">"Er is een probleem opgetreden bij het ophalen van je kaarten. Probeer het later opnieuw."</string>
     <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"Instellingen voor vergrendelscherm"</string>
-    <string name="qr_code_scanner_title" msgid="1938155688725760702">"QR-code-scanner"</string>
+    <string name="qr_code_scanner_title" msgid="1938155688725760702">"QR-codescanner"</string>
     <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"Updaten"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"Werkprofiel"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"Vliegtuig­modus"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Gesplitst scherm openen met huidige app rechts"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Gesplitst scherm openen met huidige app links"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Van gesplitst scherm naar volledig scherm schakelen"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Ga naar de app rechts of onderaan als je een gesplitst scherm gebruikt"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Ga naar de app links of bovenaan als je een gesplitst scherm gebruikt"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Tijdens gesplitst scherm: een app vervangen door een andere"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Invoer"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Overschakelen naar volgende taal"</string>
@@ -1036,7 +1045,7 @@
     <string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Pincode bevat letters of symbolen"</string>
     <string name="controls_pin_verify" msgid="3452778292918877662">"<xliff:g id="DEVICE">%s</xliff:g> verifiëren"</string>
     <string name="controls_pin_wrong" msgid="6162694056042164211">"Onjuiste pincode"</string>
-    <string name="controls_pin_instructions" msgid="6363309783822475238">"Geef de pincode op"</string>
+    <string name="controls_pin_instructions" msgid="6363309783822475238">"Voer pincode in"</string>
     <string name="controls_pin_instructions_retry" msgid="1566667581012131046">"Andere pincode proberen"</string>
     <string name="controls_confirmation_message" msgid="7744104992609594859">"Bevestig de wijziging voor <xliff:g id="DEVICE">%s</xliff:g>"</string>
     <string name="controls_structure_tooltip" msgid="4355922222944447867">"Swipe om meer te zien"</string>
@@ -1116,7 +1125,7 @@
     <string name="basic_status" msgid="2315371112182658176">"Gesprek openen"</string>
     <string name="select_conversation_title" msgid="6716364118095089519">"Gesprekswidgets"</string>
     <string name="select_conversation_text" msgid="3376048251434956013">"Tik op een gesprek om het toe te voegen aan je startscherm"</string>
-    <string name="no_conversations_text" msgid="5354115541282395015">"Je ziet je recente gesprekken hier"</string>
+    <string name="no_conversations_text" msgid="5354115541282395015">"Hier staan je recente gesprekken"</string>
     <string name="priority_conversations" msgid="3967482288896653039">"Prioriteitsgesprekken"</string>
     <string name="recent_conversations" msgid="8531874684782574622">"Recente gesprekken"</string>
     <string name="days_timestamp" msgid="5821854736213214331">"<xliff:g id="DURATION">%1$s</xliff:g> dagen geleden"</string>
@@ -1176,7 +1185,7 @@
     <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"Wifi maakt momenteel niet automatisch verbinding"</string>
     <string name="see_all_networks" msgid="3773666844913168122">"Alles tonen"</string>
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Verbreek de ethernetverbinding om van netwerk te wisselen"</string>
-    <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Apps en services kunnen nog steeds op elk moment scannen op wifi-netwerken, zelfs als wifi uitstaat, om de apparaatfunctionaliteit te verbeteren. Je kunt dit aanpassen in de instellingen voor wifi-scannen. "<annotation id="link">"Wijzigen"</annotation></string>
+    <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Apps en services kunnen nog steeds op elk gewenst moment zoeken naar apparaten in de buurt om de apparaatfunctionaliteit te verbeteren, zelfs als bluetooth uitstaat. Je kunt dit aanpassen in de instellingen voor wifi-scannen. "<annotation id="link">"Wijzigen"</annotation></string>
     <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Vliegtuigmodus uitzetten"</string>
     <string name="qs_tile_request_dialog_text" msgid="3501359944139877694">"<xliff:g id="APPNAME">%1$s</xliff:g> wil de volgende tegel toevoegen aan Snelle instellingen"</string>
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"Tegel toevoegen"</string>
diff --git a/packages/SystemUI/res/values-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
index 7737794..1b286f3 100644
--- a/packages/SystemUI/res/values-nl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Uit"</item>
     <item msgid="5137565285664080143">"Aan"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index ee8c094..9a602b8 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ସ୍କ୍ରିନସଟଗୁଡ଼ିକ ନେବା ଆପଣଙ୍କ IT ଆଡମିନଙ୍କ ଦ୍ୱାରା ବ୍ଲକ କରାଯାଇଛି"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"ଏଡିଟ କରନ୍ତୁ"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"ସ୍କ୍ରିନସଟ୍ ଏଡିଟ କରନ୍ତୁ"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"ସେୟାର କରନ୍ତୁ"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"ସ୍କ୍ରିନସଟ ସେୟାର କରନ୍ତୁ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ଅଧିକ କେପଚର କରନ୍ତୁ"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ସ୍କ୍ରିନସଟ୍ ଖାରଜ କରନ୍ତୁ"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ଫେସ୍ ସ୍କାନିଙ୍ଗ କରାଯାଉଛି"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ପଠାନ୍ତୁ"</string>
     <string name="cancel" msgid="1089011503403416730">"ବାତିଲ କରନ୍ତୁ"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"ଆପ ଲୋଗୋ"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ପ୍ରାମାଣିକତା ବାତିଲ କରିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ଫେସ ଚିହ୍ନଟ କରାଯାଇଛି। ଜାରି ରଖିବାକୁ ଅନଲକ ଆଇକନ ଦବାନ୍ତୁ।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ପ୍ରାମାଣିକତା ହୋଇଛି"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ପ୍ରମାଣୀକରଣକୁ ବାତିଲ କରନ୍ତୁ"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ଅଧିକ ବିକଳ୍ପ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ପାଟର୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"ପାସ୍‌ୱାର୍ଡ୍ ବ୍ୟବହାର କରନ୍ତୁ"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"ଷ୍ଟାଣ୍ଡାର୍ଡ"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"ମଧ୍ୟମ"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"ଅଧିକ"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ଡିଭାଇସର ମାଇକ୍ରୋଫୋନକୁ ଅନବ୍ଲକ କରିବେ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ଡିଭାଇସର କେମେରାକୁ ଅନବ୍ଲକ କରିବେ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ଡିଭାଇସର କ୍ୟାମେରା ଏବଂ ମାଇକ୍ରୋଫୋନକୁ ଅନବ୍ଲକ୍ କରିବେ?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"କାଢ଼ି ଦିଅନ୍ତୁ"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ୱିଜେଟ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"ହୋଇଗଲା"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"ୱିଜେଟଗୁଡ଼ିକୁ ଯୋଗ କରନ୍ତୁ"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"ଆପଣଙ୍କ ଟାବଲେଟକୁ ଅନଲକ ନକରି ଆପଣଙ୍କ ପସନ୍ଦର ଆପ ୱିଜେଟଗୁଡ଼ିକୁ କୁଇକ ଆକ୍ସେସ ପାଆନ୍ତୁ।"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"ଲକସ୍କ୍ରିନରେ ଯେ କୌଣସି ୱିଜେଟକୁ ଅନୁମତି ଦେବେ?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"ସେଟିଂସ ଖୋଲନ୍ତୁ"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"ୱାର୍କ ଆପ୍ସକୁ ପୁଣି ଚାଲୁ କରିବେ?"</string>
@@ -472,7 +483,7 @@
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଏହି ବିକଳ୍ପକୁ ଅକ୍ଷମ କରିଛି"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"କାଷ୍ଟିଂ ଆରମ୍ଭ କରିବେ?"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"ଆପଣ କାଷ୍ଟ କରିବା ସମୟରେ, ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ଆପଣଙ୍କ ଡିଭାଇସରେ ପ୍ଲେ ହେଉଥିବା ସବୁକିଛିକୁ Androidର ଆକ୍ସେସ ଅଛି। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"ଆପଣ ଏକ ଆପ କାଷ୍ଟ କରିବା ସମୟରେ, ସେହି ଆପରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ପ୍ଲେ ହେଉଥିବା ସବୁକିଛିକୁ Androidର ଆକ୍ସେସ ଅଛି। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"ଆପଣ ଏକ ଆପ କାଷ୍ଟ କରିବା ସମୟରେ, ସେହି ଆପରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ପ୍ଲେ ହେଉଥିବା ସବୁକିଛିକୁ Androidର ଆକ୍ସେସ ଅଛି। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପାଇଁ ସତର୍କ ରୁହନ୍ତୁ।"</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"କାଷ୍ଟିଂ ଆରମ୍ଭ କରନ୍ତୁ"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"ସେୟାରିଂ ଆରମ୍ଭ କରିବେ?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"ଆପଣ ସେୟାର, ରେକର୍ଡ କିମ୍ବା କାଷ୍ଟ କରିବା ସମୟରେ, ଆପଣଙ୍କ ସ୍କ୍ରିନରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ଆପଣଙ୍କ ଡିଭାଇସରେ ପ୍ଲେ ହେଉଥିବା ସବୁକିଛିକୁ Androidର ଆକ୍ସେସ ଅଛି। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ଏହି ଡିଭାଇସ୍ ଆପଣଙ୍କ ବାପାମାଙ୍କ ଦ୍ୱାରା ପରିଚାଳିତ। ଆପଣଙ୍କ ବାପାମା ଆପଣ ବ୍ୟବହାର କରୁଥିବା ଆପ୍ସ, ଆପଣଙ୍କ ଲୋକେସନ୍ ଓ ସ୍କ୍ରିନ୍ ସମୟ ପରି ସୂଚନା ଦେଖିପାରିବେ ଏବଂ ପରିଚାଳନା କରିପାରିବେ।"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent ଦ୍ୱାରା ଅନ୍‌ଲକ୍ ରହିଛି"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"ଡିଭାଇସ ଲକ କରାଯାଇଛି, ଅନେକଗୁଡ଼ିଏ ପ୍ରମାଣୀକରଣ ପ୍ରଚେଷ୍ଟା କରାଯାଇଛି"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"ଡିଭାଇସ ଲକ ହୋଇଛି\nପ୍ରମାଣୀକରଣ ବିଫଳ ହୋଇଛି"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"ସାଉଣ୍ଡ ସେଟିଂସ୍"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"ସ୍ବଚାଳିତ କ୍ୟାପ୍ସନ୍ ମିଡିଆ"</string>
@@ -574,11 +583,11 @@
     <string name="screen_pinning_negative" msgid="6882816864569211666">"ନାହିଁ, ଥାଉ"</string>
     <string name="screen_pinning_start" msgid="7483998671383371313">"ଆପ୍ ପିନ୍ କରାଯାଇଛି"</string>
     <string name="screen_pinning_exit" msgid="4553787518387346893">"ଆପ୍ ଅନପିନ୍ କରାଯାଇଛି"</string>
-    <string name="stream_voice_call" msgid="7468348170702375660">"କଲ୍ କରନ୍ତୁ"</string>
+    <string name="stream_voice_call" msgid="7468348170702375660">"କଲ କରନ୍ତୁ"</string>
     <string name="stream_system" msgid="7663148785370565134">"ସିଷ୍ଟମ"</string>
     <string name="stream_ring" msgid="7550670036738697526">"ରିଙ୍ଗ"</string>
     <string name="stream_music" msgid="2188224742361847580">"ମିଡିଆ"</string>
-    <string name="stream_alarm" msgid="16058075093011694">"ଆଲାରାମ୍"</string>
+    <string name="stream_alarm" msgid="16058075093011694">"ଆଲାରାମ"</string>
     <string name="stream_notification" msgid="7930294049046243939">"ବିଜ୍ଞପ୍ତି"</string>
     <string name="stream_bluetooth_sco" msgid="6234562365528664331">"ବ୍ଲୁଟୁଥ୍‍‌"</string>
     <string name="stream_dtmf" msgid="7322536356554673067">"ଡୁଆଲ୍‍ ମଲ୍ଟି ଟୋନ୍‍ ଫ୍ରିକ୍ୱେନ୍ସୀ"</string>
@@ -612,7 +621,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%sକୁ ମ୍ୟୁଟ କରନ୍ତୁ"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%sକୁ ଅନମ୍ୟୁଟ କରନ୍ତୁ"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g>ରେ ପ୍ଲେ କରାଯାଉଛି"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"ଅଡିଓ ପ୍ଲେ ହେବ"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"ଅଡିଓ ଏଥିରେ ପ୍ଲେ ହେବ"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"ସିଷ୍ଟମ୍ UI ଟ୍ୟୁନର୍‍"</string>
     <string name="status_bar" msgid="4357390266055077437">"ଷ୍ଟାଟସ୍‍ ବାର୍‍"</string>
     <string name="demo_mode" msgid="263484519766901593">"ସିଷ୍ଟମ୍‌ UI ଡେମୋ ମୋଡ୍‌"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHSରେ ବର୍ତ୍ତମାନର ଆପ ସହ ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନକୁ ପ୍ରବେଶ କରାନ୍ତୁ"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHSରେ ବର୍ତ୍ତମାନର ଆପ ସହ ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନକୁ ପ୍ରବେଶ କରାନ୍ତୁ"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନରୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନକୁ ସୁଇଚ କରନ୍ତୁ"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବା ସମୟରେ ଡାହାଣପଟର ବା ତଳର ଆପକୁ ସୁଇଚ କରନ୍ତୁ"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବା ସମୟରେ ବାମପଟର ବା ଉପରର ଆପକୁ ସୁଇଚ କରନ୍ତୁ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ସମୟରେ: କୌଣସି ଆପକୁ ଗୋଟିଏରୁ ଅନ୍ୟ ଏକ ଆପରେ ବଦଳାନ୍ତୁ"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ଇନପୁଟ କରନ୍ତୁ"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"ପରବର୍ତ୍ତୀ ଭାଷାକୁ ସୁଇଚ କରନ୍ତୁ"</string>
@@ -901,7 +908,7 @@
     <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g>, <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
     <string name="wifi_is_off" msgid="5389597396308001471">"ୱାଇ-ଫାଇ ବନ୍ଦ ଅଛି"</string>
-    <string name="bt_is_off" msgid="7436344904889461591">"ବ୍ଲୁଟୂଥ୍‍‌ ଅଫ୍ ଅଛି"</string>
+    <string name="bt_is_off" msgid="7436344904889461591">"ବ୍ଲୁଟୁଥ ବନ୍ଦ ଅଛି"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଅଫ୍‍ ଅଛି"</string>
     <string name="dnd_is_on" msgid="7009368176361546279">"\"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ଚାଲୁ ଅଛି"</string>
     <string name="qs_dnd_prompt_auto_rule" msgid="3535469468310002616">"ଏକ (<xliff:g id="ID_1">%s</xliff:g>) ନିୟମ ଦ୍ୱାରା \"ବିରକ୍ତ କରନ୍ତୁ ନାହିଁ\" ସ୍ୱଚାଳିତ ଭାବେ ଅନ୍‍ କରାଗଲା।"</string>
diff --git a/packages/SystemUI/res/values-or/tiles_states_strings.xml b/packages/SystemUI/res/values-or/tiles_states_strings.xml
index 046db2f..fd727bf 100644
--- a/packages/SystemUI/res/values-or/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-or/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"ବନ୍ଦ ଅଛି"</item>
     <item msgid="5137565285664080143">"ଚାଲୁ ଅଛି"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 49156bc..40efd0b 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ਤੁਹਾਡੇ ਆਈ.ਟੀ. ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈਣ ਦੀ ਸੁਵਿਧਾ ਨੂੰ ਬਲਾਕ ਕੀਤਾ ਗਿਆ ਹੈ"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"ਸੰਪਾਦਨ ਕਰੋ"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਦਾ ਸੰਪਾਦਨ ਕਰੋ"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"ਸਾਂਝਾ ਕਰੋ"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਸਾਂਝਾ ਕਰੋ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"ਹੋਰ ਕੈਪਚਰ ਕਰੋ"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਖਾਰਜ ਕਰੋ"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ਚਿਹਰਾ ਸਕੈਨ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ਭੇਜੋ"</string>
     <string name="cancel" msgid="1089011503403416730">"ਰੱਦ ਕਰੋ"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"ਐਪ ਲੋਗੋ"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ਤਸਦੀਕ ਕਰੋ"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ਪ੍ਰਮਾਣੀਕਰਨ ਰੱਦ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ਚਿਹਰੇ ਦੀ ਪਛਾਣ ਹੋਈ। ਜਾਰੀ ਰੱਖਣ ਲਈ \'ਅਣਲਾਕ ਕਰੋ\' ਪ੍ਰਤੀਕ ਨੂੰ ਦਬਾਓ।"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ਪ੍ਰਮਾਣਿਤ ਹੋਇਆ"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ਪ੍ਰਮਾਣੀਕਰਨ ਰੱਦ ਕਰੋ"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ਹੋਰ ਵਿਕਲਪ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ਪਿੰਨ ਵਰਤੋ"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ਪੈਟਰਨ ਵਰਤੋ"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"ਪਾਸਵਰਡ ਵਰਤੋ"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"ਮਿਆਰੀ"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"ਦਰਮਿਆਨਾ"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"ਜ਼ਿਆਦਾ"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ਕੀ ਡੀਵਾਈਸ ਦੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੂੰ ਅਣਬਲਾਕ ਕਰਨਾ ਹੈ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ਕੀ ਡੀਵਾਈਸ ਦੇ ਕੈਮਰੇ ਨੂੰ ਅਣਬਲਾਕ ਕਰਨਾ ਹੈ?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"ਕੀ ਡੀਵਾਈਸ ਦੇ ਕੈਮਰੇ ਅਤੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੂੰ ਅਣਬਲਾਕ ਕਰਨਾ ਹੈ?"</string>
@@ -439,13 +448,15 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"ਹਟਾਓ"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ਵਿਜੇਟ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"ਹੋ ਗਿਆ"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"ਵਿਜੇਟ ਸ਼ਾਮਲ ਕਰੋ"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"ਆਪਣੇ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕੀਤੇ ਬਿਨਾਂ ਆਪਣੇ ਮਨਪਸੰਦ ਐਪ ਵਿਜੇਟ ਤੱਕ ਤਤਕਾਲ ਪਹੁੰਚ ਪ੍ਰਾਪਤ ਕਰੋ।"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"ਕੀ ਲਾਕ-ਸਕ੍ਰੀਨ \'ਤੇ ਕਿਸੇ ਵੀ ਵਿਜੇਟ ਨੂੰ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"ਕੰਮ ਸੰਬੰਧੀ ਐਪਾਂ ਤੋਂ ਰੋਕ ਹਟਾਈਏ?"</string>
     <string name="work_mode_turn_on" msgid="907813741770247267">"ਰੋਕ ਹਟਾਓ"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"ਵਰਤੋਂਕਾਰ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"ਪੁੱਲਡਾਊਨ ਮੀਨੂ"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ਇਸ ਸੈਸ਼ਨ ਵਿਚਲੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟਾ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਏਗਾ।"</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"ਇਸ ਸੈਸ਼ਨ ਵਿਚਲੀਆਂ ਸਾਰੀਆਂ ਐਪਾਂ ਅਤੇ ਡਾਟੇ ਨੂੰ ਮਿਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"ਮਹਿਮਾਨ, ਫਿਰ ਤੁਹਾਡਾ ਸੁਆਗਤ ਹੈ!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"ਕੀ ਤੁਸੀਂ ਆਪਣਾ ਸੈਸ਼ਨ ਜਾਰੀ ਰੱਖਣਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"ਮੁੜ-ਸ਼ੁਰੂ ਕਰੋ"</string>
@@ -472,7 +483,7 @@
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੇ ਇਸ ਵਿਕਲਪ ਨੂੰ ਬੰਦ ਕਰ ਦਿੱਤਾ ਹੈ"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"ਕੀ ਕਾਸਟ ਕਰਨਾ ਸ਼ੁਰੂ ਕਰਨਾ ਹੈ?"</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਕਾਸਟ ਕਰਨ \'ਤੇ, Android ਕੋਲ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਸਣ ਵਾਲੀ ਜਾਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਚਲਾਈ ਜਾਣ ਵਾਲੀ ਹਰੇਕ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਵਾਸਤੇ ਸਾਵਧਾਨ ਰਹੋ।"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਕਾਸਟ ਕਰਨ \'ਤੇ, Android ਕੋਲ ਉਸ ਐਪ \'ਤੇ ਦਿਖਾਈ ਗਈ ਜਾਂ ਚਲਾਈ ਗਈ ਹਰੇਕ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਸੰਬੰਧੀ ਸਾਵਧਾਨ ਰਹੋ।"</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਕਿਸੇ ਐਪ ਨੂੰ ਕਾਸਟ ਕਰਨ \'ਤੇ, Android ਕੋਲ ਉਸ ਐਪ \'ਤੇ ਦਿਖਾਈ ਗਈ ਜਾਂ ਚਲਾਈ ਗਈ ਹਰੇਕ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਸੰਬੰਧੀ ਸਾਵਧਾਨ ਰਹੋ।"</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"ਕਾਸਟ ਕਰਨਾ ਸ਼ੁਰੂ ਕਰੋ"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"ਕੀ ਸਾਂਝਾਕਰਨ ਸ਼ੁਰੂ ਕਰਨਾ ਹੈ?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਸਾਂਝਾ ਕਰਨ, ਰਿਕਾਰਡ ਕਰਨ, ਜਾਂ ਕਾਸਟ ਕਰਨ \'ਤੇ, Android ਕੋਲ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਦਿਸਦੀ ਜਾਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਚਲਾਈ ਗਈ ਹਰੇਕ ਚੀਜ਼ ਤੱਕ ਪਹੁੰਚ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਵਾਸਤੇ ਸਾਵਧਾਨ ਰਹੋ।"</string>
@@ -494,7 +505,7 @@
     <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"ਸਾਰੀਆਂ ਸ਼ਾਂਤ ਸੂਚਨਾਵਾਂ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"\'ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ\' ਵੱਲੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਰੋਕਿਆ ਗਿਆ"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"ਹੁਣੇ ਸ਼ੁਰੂ ਕਰੋ"</string>
-    <string name="empty_shade_text" msgid="8935967157319717412">"ਕੋਈ ਸੂਚਨਾਵਾਂ ਨਹੀਂ"</string>
+    <string name="empty_shade_text" msgid="8935967157319717412">"ਕੋਈ ਸੂਚਨਾ ਨਹੀਂ"</string>
     <string name="no_unseen_notif_text" msgid="395512586119868682">"ਕੋਈ ਨਵੀਂ ਸੂਚਨਾ ਨਹੀਂ ਹੈ"</string>
     <string name="unlock_to_see_notif_text" msgid="7439033907167561227">"ਪੁਰਾਣੀਆਂ ਸੂਚਨਾਵਾਂ ਦੇਖਣ ਲਈ ਅਣਲਾਕ ਕਰੋ"</string>
     <string name="quick_settings_disclosure_parental_controls" msgid="2114102871438223600">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਮਾਂ-ਪਿਓ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ਇਸ ਡੀਵਾਈਸ ਦਾ ਪ੍ਰਬੰਧਨ ਤੁਹਾਡੇ ਮਾਂ-ਪਿਓ ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ। ਤੁਹਾਡੇ ਮਾਂ-ਪਿਓ ਤੁਹਾਡੀਆਂ ਐਪਾਂ ਦੀ ਵਰਤੋਂ, ਤੁਹਾਡੇ ਟਿਕਾਣੇ ਅਤੇ ਤੁਹਾਡੇ ਸਕ੍ਰੀਨ ਸਮੇਂ ਵਰਗੀ ਜਾਣਕਾਰੀ ਨੂੰ ਦੇਖ ਅਤੇ ਉਸਦਾ ਪ੍ਰਬੰਧਨ ਕਰ ਸਕਦੇ ਹਨ।"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"ਟਰੱਸਟ-ਏਜੰਟ ਵੱਲੋਂ ਅਣਲਾਕ ਰੱਖਿਆ ਗਿਆ"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"ਡੀਵਾਈਸ ਲਾਕ ਕੀਤਾ ਗਿਆ ਸੀ, ਬਹੁਤ ਸਾਰੀਆਂ ਪ੍ਰਮਾਣੀਕਰਨ ਕੋਸ਼ਿਸ਼ਾਂ ਕੀਤੀਆਂ ਗਈਆਂ"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"ਡੀਵਾਈਸ ਲਾਕ ਹੈ\nਪ੍ਰਮਾਣੀਕਰਨ ਅਸਫਲ ਰਿਹਾ"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"ਧੁਨੀ ਸੈਟਿੰਗਾਂ"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"ਸਵੈਚਲਿਤ ਸੁਰਖੀ ਮੀਡੀਆ"</string>
@@ -595,7 +604,7 @@
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s। ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ। ਪਹੁੰਚਯੋਗਤਾ ਸੇਵਾਵਾਂ ਮਿਊਟ ਹੋ ਸਕਦੀਆਂ ਹਨ।"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s। ਥਰਥਰਾਹਟ \'ਤੇ ਸੈੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s। ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
-    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ਸ਼ੋਰ ਨੂੰ ਕੰਟਰੋਲ ਕਰੋ"</string>
+    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"ਨੋਇਸ ਕੰਟਰੋਲ"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"ਸਪੇਸ਼ਿਅਲ ਆਡੀਓ"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"ਬੰਦ"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ਸਥਿਰ"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHS ਲਈ ਮੌਜੂਦਾ ਐਪ ਨਾਲ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHS ਲਈ ਮੌਜੂਦਾ ਐਪ ਨਾਲ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਤੋਂ ਪੂਰੀ ਸਕ੍ਰੀਨ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਸੱਜੇ ਜਾਂ ਹੇਠਾਂ ਮੌਜੂਦ ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਖੱਬੇ ਜਾਂ ਉੱਪਰ ਮੌਜੂਦ ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੌਰਾਨ: ਇੱਕ ਐਪ ਨਾਲ ਦੂਜੀ ਐਪ ਨੂੰ ਬਦਲੋ"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ਇਨਪੁੱਟ"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"ਅਗਲੀ ਭਾਸ਼ਾ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
diff --git a/packages/SystemUI/res/values-pa/tiles_states_strings.xml b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
index df870cd..afb1e8b 100644
--- a/packages/SystemUI/res/values-pa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
@@ -152,7 +152,7 @@
     <item msgid="8998632451221157987">"ਚਾਲੂ ਹੈ"</item>
   </string-array>
   <string-array name="tile_states_controls">
-    <item msgid="8199009425335668294">"ਅਣਉਪਲਬਧ ਹੈ"</item>
+    <item msgid="8199009425335668294">"ਅਣਉਪਲਬਧ ਹਨ"</item>
     <item msgid="4544919905196727508">"ਬੰਦ ਹੈ"</item>
     <item msgid="3422023746567004609">"ਚਾਲੂ ਹੈ"</item>
   </string-array>
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"ਬੰਦ"</item>
     <item msgid="5137565285664080143">"ਚਾਲੂ"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 9ee0b78..48262a0 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -105,8 +105,8 @@
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Przetwarzam nagrywanie ekranu"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Stałe powiadomienie o sesji rejestrowania zawartości ekranu"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Rozpocząć nagrywanie?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Podczas nagrywania Android ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Podczas nagrywania treści z aplikacji Android ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Podczas nagrywania Android ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, dźwięku i filmów."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Podczas nagrywania treści z aplikacji Android ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, dźwięku i filmów."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Zacznij nagrywać"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Nagrywaj dźwięk"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Dźwięki z urządzenia"</string>
@@ -151,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skanowanie twarzy"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Wyślij"</string>
     <string name="cancel" msgid="1089011503403416730">"Anuluj"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logo aplikacji"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potwierdź"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Spróbuj jeszcze raz"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Kliknij, by anulować uwierzytelnianie"</string>
@@ -165,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Twarz rozpoznana. Aby kontynuować, kliknij ikonę odblokowywania."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Uwierzytelniono"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Anuluj uwierzytelnianie"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Więcej opcji"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Użyj kodu PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Użyj wzoru"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Użyj hasła"</string>
@@ -266,7 +268,7 @@
     <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Kliknij, aby podłączyć lub odłączyć urządzenie"</string>
     <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Sparuj nowe urządzenie"</string>
     <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Pokaż wszystkie"</string>
-    <string name="turn_on_bluetooth" msgid="5681370462180289071">"Użyj Bluetootha"</string>
+    <string name="turn_on_bluetooth" msgid="5681370462180289071">"Używaj Bluetootha"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Połączone"</string>
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"Zapisane"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"rozłącz"</string>
@@ -361,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standardowy"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Średni"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Wysoki"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokować mikrofon urządzenia?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokować aparat urządzenia?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Odblokować aparat i mikrofon urządzenia?"</string>
@@ -438,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Usuń"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodaj widżet"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Gotowe"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Dodaj widżety"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Uzyskaj szybki dostęp do ulubionych widżetów aplikacji bez odblokowywania tabletu."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Zezwolić na dowolny widżet na ekranie blokady?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Otwórz ustawienia"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Cofnąć wstrzymanie aplikacji służbowych?"</string>
@@ -465,17 +477,17 @@
     <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Pojedyncza aplikacja"</string>
     <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Udostępnianie i nagrywanie aplikacji"</string>
     <string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Rozpocząć nagrywanie lub przesyłanie za pomocą aplikacji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
-    <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Podczas udostępniania, nagrywania lub przesyłania treści aplikacja <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
-    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Podczas udostępniania, nagrywania lub przesyłania treści aplikacja <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Podczas udostępniania, nagrywania lub przesyłania treści aplikacja <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, dźwięku i filmów."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Podczas udostępniania, nagrywania lub przesyłania treści aplikacja <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, dźwięku i filmów."</string>
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Rozpocznij"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ma wyłączoną tę opcję"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Rozpocząć przesyłanie?"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Podczas przesyłania, Android ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Podczas przesyłania treści z aplikacji Android ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Podczas przesyłania, Android ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, dźwięku i filmów."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Podczas przesyłania treści z aplikacji Android ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, dźwięku i filmów."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Rozpocznij przesyłanie"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Rozpocząć udostępnianie?"</string>
-    <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Podczas udostępniania, nagrywania lub przesyłania treści Android ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
-    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Podczas udostępniania, nagrywania lub przesyłania treści Android ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Podczas udostępniania, nagrywania lub przesyłania treści Android ma dostęp do wszystkiego, co jest widoczne na ekranie lub odtwarzane na urządzeniu. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, dźwięku i filmów."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Podczas udostępniania, nagrywania lub przesyłania treści Android ma dostęp do wszystkiego, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, dźwięku i filmów."</string>
     <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Rozpocznij"</string>
     <string name="media_projection_task_switcher_text" msgid="590885489897412359">"Udostępnianie zostanie wstrzymane, gdy przełączysz aplikacje"</string>
     <string name="media_projection_task_switcher_action_switch" msgid="8682258717291921123">"Udostępnij tę aplikację"</string>
@@ -585,8 +597,8 @@
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Wyciszenie"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"Przesyłanie"</string>
     <string name="stream_notification_unavailable" msgid="4313854556205836435">"Niedostępne, bo dzwonek jest wyciszony"</string>
-    <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Niedostępne, bo włączone jest „Nie przeszkadzać”"</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"Niedostępne, bo włączone jest „Nie przeszkadzać”"</string>
+    <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Niedostępne, włączone jest „Nie przeszkadzać”"</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"Niedostępne, włączone jest „Nie przeszkadzać”"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Kliknij, by wyłączyć wyciszenie."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Kliknij, by włączyć wibracje. Ułatwienia dostępu mogą być wyciszone."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Kliknij, by wyciszyć. Ułatwienia dostępu mogą być wyciszone."</string>
@@ -596,7 +608,7 @@
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Dźwięk przestrzenny"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Wyłączony"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Stały"</string>
-    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Monitorowanie głowy"</string>
+    <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"Śledzenie głowy"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"Kliknij, aby zmienić tryb dzwonka"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"wycisz"</string>
     <string name="volume_ringer_hint_unmute" msgid="6119086890306456976">"wyłącz wyciszenie"</string>
@@ -656,9 +668,9 @@
     <string name="notification_alert_title" msgid="3656229781017543655">"Domyślne"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatycznie"</string>
     <string name="notification_channel_summary_low" msgid="4860617986908931158">"Bez dźwięku i wibracji"</string>
-    <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Brak dźwięku i wibracji, wyświetla się niżej w sekcji rozmów"</string>
-    <string name="notification_channel_summary_default" msgid="777294388712200605">"Może włączać dzwonek lub wibracje w zależności od ustawień urządzenia"</string>
-    <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Może włączyć dzwonek lub wibracje w zależności od ustawień urządzenia. Rozmowy z aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g> są domyślnie wyświetlane jako dymki."</string>
+    <string name="notification_conversation_summary_low" msgid="1734433426085468009">"Brak dźwięku i wibracji, wyświetlają się niżej w sekcji rozmów"</string>
+    <string name="notification_channel_summary_default" msgid="777294388712200605">"Mogą włączać dzwonek lub wibracje w zależności od ustawień urządzenia"</string>
+    <string name="notification_channel_summary_default_with_bubbles" msgid="3482483084451555344">"Mogą włączyć dzwonek lub wibracje w zależności od ustawień urządzenia. Rozmowy z aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g> są domyślnie wyświetlane jako dymki."</string>
     <string name="notification_channel_summary_automatic" msgid="5813109268050235275">"Pozwól systemowi decydować, czy o powiadomieniu powinien informować dźwięk czy wibracja"</string>
     <string name="notification_channel_summary_automatic_alerted" msgid="954166812246932240">"&lt;b&gt;Stan:&lt;/b&gt; zmieniony na Domyślny"</string>
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Stan:&lt;/b&gt; zmieniono na Ciche"</string>
@@ -1235,7 +1247,7 @@
     <string name="home_quick_affordance_unavailable_configure_the_app" msgid="604424593994493281">"• Dostępne jest co najmniej 1 urządzenie lub panel urządzenia"</string>
     <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Wybierz domyślną aplikację do obsługi notatek, której skrótu będziesz używać do funkcji notowania"</string>
     <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Wybierz aplikację"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Skrót – naciśnij i przytrzymaj"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Naciśnij i przytrzymaj skrót"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Anuluj"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Przełącz ekrany teraz"</string>
     <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Otwieranie telefonu"</string>
diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
index c667b99..5d1c02e 100644
--- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Wyłączono"</item>
     <item msgid="5137565285664080143">"Włączono"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index a519883..04bdf14 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"As capturas de tela foram bloqueadas pelo administrador de TI"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de tela"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Compartilhar"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Compartilhar captura de tela"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturar mais"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dispensar captura de tela"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Verificando rosto"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logotipo do app"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar novamente"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Toque para cancelar a autenticação"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Pressione o ícone para continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticação"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mais opções"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrão"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Usar senha"</string>
@@ -357,11 +358,19 @@
     <item msgid="1627504621139124393">"Interface do usuário"</item>
     <item msgid="8309220355268900335">"Bateria"</item>
   </string-array>
-    <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Modo para uma mão"</string>
+    <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Modo uma mão"</string>
     <string name="quick_settings_contrast_label" msgid="988087460210159123">"Contraste"</string>
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Padrão"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Médio"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Alto"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmera do dispositivo?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Desbloquear a câmera e o microfone do dispositivo?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Remover"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Adicionar widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Concluído"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Adicionar widgets"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Tenha acesso rápido aos widgets de seus apps favoritos sem desbloquear o tablet."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Permitir qualquer widget na tela de bloqueio?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Abrir as configurações"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Reativar apps de trabalho?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Este dispositivo é gerenciado pelo seu familiar responsável, que pode ver e gerenciar informações como os apps que você usa, sua localização e seu tempo de uso."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Desbloqueado pelo TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"O dispositivo foi bloqueado devido a muitas tentativas de autenticação"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Dispositivo bloqueado\nA autenticação falhou"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Configurações de som"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Transcrição automática"</string>
@@ -587,7 +596,7 @@
     <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string>
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Desativar som"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"Transmitir"</string>
-    <string name="stream_notification_unavailable" msgid="4313854556205836435">"Indisponível com o toque foi silenciado"</string>
+    <string name="stream_notification_unavailable" msgid="4313854556205836435">"Indisponível com o toque silenciado"</string>
     <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Indisponível porque o Não perturbe está ativado"</string>
     <string name="stream_media_unavailable" msgid="6823020894438959853">"Indisponível porque o Não perturbe está ativado"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toque para ativar o som."</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Usar a tela dividida com o app atual à direita"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Usar a tela dividida com o app atual à esquerda"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Mudar da tela dividida para a tela cheia"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mude para o app à direita ou abaixo ao usar a tela dividida"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mude para o app à esquerda ou acima ao usar a tela dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Com a tela dividida: substituir um app por outro"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Mudar para o próximo idioma"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
index ae2bd05..453d813 100644
--- a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Desativado"</item>
     <item msgid="5137565285664080143">"Ativado"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index f0f451b..b627090 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -151,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"A analisar o rosto…"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logótipo da app"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar novamente"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Toque para cancelar a autenticação."</string>
@@ -165,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Prima ícone de desbloqueio para continuar"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticação"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mais opções"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrão"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Usar palavra-passe"</string>
@@ -258,7 +260,7 @@
     <string name="accessibility_rotation_lock_on_landscape" msgid="936972553861524360">"O ecrã está bloqueado na orientação horizontal."</string>
     <string name="accessibility_rotation_lock_on_portrait" msgid="2356633398683813837">"O ecrã está bloqueado na orientação vertical."</string>
     <string name="dessert_case" msgid="9104973640704357717">"Vitrina de sobremesas"</string>
-    <string name="start_dreams" msgid="9131802557946276718">"Proteção de ecrã"</string>
+    <string name="start_dreams" msgid="9131802557946276718">"Proteção ecrã"</string>
     <string name="ethernet_label" msgid="2203544727007463351">"Ethernet"</string>
     <string name="quick_settings_dnd_label" msgid="7728690179108024338">"Não incomodar"</string>
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
@@ -283,9 +285,9 @@
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Rotação auto."</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Rodar o ecrã automaticamente"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Localização"</string>
-    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Proteção de ecrã"</string>
+    <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Proteção ecrã"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Acesso câmara"</string>
-    <string name="quick_settings_mic_label" msgid="8392773746295266375">"Ac. microfone"</string>
+    <string name="quick_settings_mic_label" msgid="8392773746295266375">"Acesso micro"</string>
     <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponível"</string>
     <string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Bloqueado"</string>
     <string name="quick_settings_media_device_label" msgid="8034019242363789941">"Dispositivo multimédia"</string>
@@ -327,13 +329,13 @@
     <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Apps trabalho"</string>
     <string name="quick_settings_work_mode_paused_state" msgid="6681788236383735976">"Pausado"</string>
     <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Luz noturna"</string>
-    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Ativ. ao pôr-do-sol"</string>
+    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Ativa ao pôr do sol"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Até ao amanhecer"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Ativada à(s) <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Até à(s) <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"Tema escuro"</string>
     <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"Poup. bateria"</string>
-    <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Ativ. ao pôr do sol"</string>
+    <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"Ativa ao pôr do sol"</string>
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"Até ao amanhecer"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"Ativado à(s) <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="quick_settings_dark_mode_secondary_label_until" msgid="2289774641256492437">"Até à(s) <xliff:g id="TIME">%s</xliff:g>."</string>
@@ -361,12 +363,19 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Padrão"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Médio"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Alto"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Dispositivos auditivos"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmara do dispositivo?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Quer desbloquear a câmara e o microfone?"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Isto desbloqueia o acesso a todas as apps e serviços com autorização para utilizar o seu microfone."</string>
-    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Isto desbloqueia o acesso a todas as apps e serviços com autorização para utilizar a sua câmara."</string>
-    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Isto desbloqueia o acesso a todas as apps e serviços com autorização para utilizar a sua câmara ou microfone."</string>
+    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Esta ação desbloqueia o acesso de todas as apps e serviços com autorização para usar o microfone."</string>
+    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Esta ação desbloqueia o acesso de todas as apps e serviços com autorização para usar a câmara."</string>
+    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Esta ação desbloqueia o acesso de todas as apps e serviços com autorização para usar a câmara ou microfone."</string>
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"O microfone está bloqueado"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"A câmara está bloqueada"</string>
     <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"O microfone e a câmara estão bloqueados"</string>
@@ -438,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Remover"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Adicionar widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Concluir"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Adicionar widgets"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Tenha acesso rápido aos widgets das suas apps favoritas sem desbloquear o tablet."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Permitir qualquer widget no ecrã de bloqueio?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Abrir definições"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Retomar apps de trabalho?"</string>
@@ -568,7 +579,7 @@
     <string name="screen_pinning_toast_recents_invisible" msgid="6850978077443052594">"Para soltar esta app, toque sem soltar nos botões Anterior e Página inicial."</string>
     <string name="screen_pinning_toast_gesture_nav" msgid="170699893395336705">"Para soltar esta app, deslize rapidamente para cima sem soltar."</string>
     <string name="screen_pinning_positive" msgid="3285785989665266984">"OK"</string>
-    <string name="screen_pinning_negative" msgid="6882816864569211666">"Não, obrigado"</string>
+    <string name="screen_pinning_negative" msgid="6882816864569211666">"Não"</string>
     <string name="screen_pinning_start" msgid="7483998671383371313">"App fixada"</string>
     <string name="screen_pinning_exit" msgid="4553787518387346893">"App solta"</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"Chamada"</string>
@@ -584,9 +595,9 @@
     <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string>
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Desativar som"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"Transmitir"</string>
-    <string name="stream_notification_unavailable" msgid="4313854556205836435">"Indisponível porque o toque está desat."</string>
+    <string name="stream_notification_unavailable" msgid="4313854556205836435">"Indisponível com toque desativado"</string>
     <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Indisponível porque Não incomodar está ativado"</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"Indisponível porque Não incomodar está ativado"</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"Indisponível com Não incomodar ativado"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toque para reativar o som."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Toque para ativar a vibração. Os serviços de acessibilidade podem ser silenciados."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Toque para desativar o som. Os serviços de acessibilidade podem ser silenciados."</string>
@@ -609,7 +620,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"desativar o som de %s"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"reativar o som de %s"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"A ouvir <xliff:g id="LABEL">%s</xliff:g> em"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"O áudio será ouv. em"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Áudio ouvido em:"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"Sintonizador da interface do sistema"</string>
     <string name="status_bar" msgid="4357390266055077437">"Barra de estado"</string>
     <string name="demo_mode" msgid="263484519766901593">"Modo de demonstração da IU do sistema"</string>
@@ -1084,7 +1095,7 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> dispositivos selecionados"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(desligado)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"Não é possível mudar. Toque para tentar novamente."</string>
-    <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Ligue um dispositivo"</string>
+    <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"Ligar um dispositivo"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"Para transmitir esta sessão, abra a app."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"App desconhecida"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"Parar transmissão"</string>
@@ -1256,7 +1267,7 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"Mudar para perfil de trabalho"</string>
     <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"Instalar app telefone de trabalho"</string>
     <string name="call_from_work_profile_close" msgid="5830072964434474143">"Cancelar"</string>
-    <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizar o ecrã de bloqueio"</string>
+    <string name="lock_screen_settings" msgid="6152703934761402399">"Personalizar ecrã de bloqueio"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"Desbloqueie para personalizar o ecrã de bloqueio"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi indisponível"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"Câmara bloqueada"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
index 666963b..34a5ed7 100644
--- a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
@@ -63,8 +63,8 @@
   </string-array>
   <string-array name="tile_states_rotation">
     <item msgid="4578491772376121579">"Indisponível"</item>
-    <item msgid="5776427577477729185">"Desligado"</item>
-    <item msgid="7105052717007227415">"Ligado"</item>
+    <item msgid="5776427577477729185">"Desligada"</item>
+    <item msgid="7105052717007227415">"Ligada"</item>
   </string-array>
   <string-array name="tile_states_bt">
     <item msgid="5330252067413512277">"Indisponível"</item>
@@ -118,7 +118,7 @@
   </string-array>
   <string-array name="tile_states_night">
     <item msgid="7857498964264855466">"Indisponível"</item>
-    <item msgid="2744885441164350155">"Desligado"</item>
+    <item msgid="2744885441164350155">"Desligada"</item>
     <item msgid="151121227514952197">"Ligado"</item>
   </string-array>
   <string-array name="tile_states_screenrecord">
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"Desativado"</item>
     <item msgid="5137565285664080143">"Ativado"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"Indisponíveis"</item>
+    <item msgid="3079622119444911877">"Desativados"</item>
+    <item msgid="3028994095749238254">"Ativados"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index a519883..04bdf14 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"As capturas de tela foram bloqueadas pelo administrador de TI"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Editar"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Editar captura de tela"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Compartilhar"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Compartilhar captura de tela"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Capturar mais"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Dispensar captura de tela"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Verificando rosto"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Enviar"</string>
     <string name="cancel" msgid="1089011503403416730">"Cancelar"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logotipo do app"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmar"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tentar novamente"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Toque para cancelar a autenticação"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Rosto reconhecido. Pressione o ícone para continuar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autenticado"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Cancelar autenticação"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mais opções"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Usar PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Usar padrão"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Usar senha"</string>
@@ -357,11 +358,19 @@
     <item msgid="1627504621139124393">"Interface do usuário"</item>
     <item msgid="8309220355268900335">"Bateria"</item>
   </string-array>
-    <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Modo para uma mão"</string>
+    <string name="quick_settings_onehanded_label" msgid="2416537930246274991">"Modo uma mão"</string>
     <string name="quick_settings_contrast_label" msgid="988087460210159123">"Contraste"</string>
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Padrão"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Médio"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Alto"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmera do dispositivo?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Desbloquear a câmera e o microfone do dispositivo?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Remover"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Adicionar widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Concluído"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Adicionar widgets"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Tenha acesso rápido aos widgets de seus apps favoritos sem desbloquear o tablet."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Permitir qualquer widget na tela de bloqueio?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Abrir as configurações"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Reativar apps de trabalho?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Este dispositivo é gerenciado pelo seu familiar responsável, que pode ver e gerenciar informações como os apps que você usa, sua localização e seu tempo de uso."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Desbloqueado pelo TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"O dispositivo foi bloqueado devido a muitas tentativas de autenticação"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Dispositivo bloqueado\nA autenticação falhou"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Configurações de som"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Transcrição automática"</string>
@@ -587,7 +596,7 @@
     <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Vibrar"</string>
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Desativar som"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"Transmitir"</string>
-    <string name="stream_notification_unavailable" msgid="4313854556205836435">"Indisponível com o toque foi silenciado"</string>
+    <string name="stream_notification_unavailable" msgid="4313854556205836435">"Indisponível com o toque silenciado"</string>
     <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Indisponível porque o Não perturbe está ativado"</string>
     <string name="stream_media_unavailable" msgid="6823020894438959853">"Indisponível porque o Não perturbe está ativado"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Toque para ativar o som."</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Usar a tela dividida com o app atual à direita"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Usar a tela dividida com o app atual à esquerda"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Mudar da tela dividida para a tela cheia"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mude para o app à direita ou abaixo ao usar a tela dividida"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mude para o app à esquerda ou acima ao usar a tela dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Com a tela dividida: substituir um app por outro"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Entrada"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Mudar para o próximo idioma"</string>
diff --git a/packages/SystemUI/res/values-pt/tiles_states_strings.xml b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
index ae2bd05..453d813 100644
--- a/packages/SystemUI/res/values-pt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Desativado"</item>
     <item msgid="5137565285664080143">"Ativado"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 4fea189..7d65f96 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Administratorul IT a blocat crearea capturilor de ecran"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Editează"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Editează captura de ecran"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Distribuie"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Trimite captura de ecran"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Surprinde mai mult"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Închide captura de ecran"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Scanarea chipului"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Trimite"</string>
     <string name="cancel" msgid="1089011503403416730">"Anulează"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Sigla aplicației"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Confirmă"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Încearcă din nou"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Atinge pentru a anula autentificarea"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Chip recunoscut. Apasă pictograma Deblocare ca să continui."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentificat"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Anulează autentificarea"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Mai multe opțiuni"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Folosește PIN-ul"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Folosește modelul"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Folosește parola"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Mediu"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Ridicat"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblochezi microfonul dispozitivului?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblochezi camera dispozitivului?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Deblochezi camera și microfonul dispozitivului?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Elimină"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Adaugă un widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Gata"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Adaugă widgeturi"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Accesează rapid widgeturile aplicațiilor preferate fără să deblochezi tableta."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Permiți vreun widget pe ecranul de blocare?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Deschide setările"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Reactivezi aplicații de lucru?"</string>
@@ -451,13 +462,13 @@
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"Începe din nou"</string>
     <string name="guest_wipe_session_dontwipe" msgid="3211052048269304205">"Da, continuă"</string>
     <string name="guest_notification_app_name" msgid="2110425506754205509">"Modul pentru invitați"</string>
-    <string name="guest_notification_session_active" msgid="5567273684713471450">"Folosește modul pentru invitați"</string>
+    <string name="guest_notification_session_active" msgid="5567273684713471450">"Folosești modul pentru invitați"</string>
     <string name="user_add_user_message_guest_remove" msgid="5589286604543355007">\n\n"Dacă adaugi un utilizator nou, vei ieși din modul pentru invitați și se vor șterge toate aplicațiile și datele din sesiunea actuală pentru invitați."</string>
     <string name="user_limit_reached_title" msgid="2429229448830346057">"Ai atins limita de utilizatori"</string>
     <string name="user_limit_reached_message" msgid="1070703858915935796">"{count,plural, =1{Se poate crea doar un utilizator.}few{Poți adăuga până la # utilizatori.}other{Poți adăuga până la # de utilizatori.}}"</string>
     <string name="user_remove_user_title" msgid="9124124694835811874">"Excluzi utilizatorul?"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"Toate aplicațiile și datele acestui utilizator vor fi șterse."</string>
-    <string name="user_remove_user_remove" msgid="8387386066949061256">"Elimină"</string>
+    <string name="user_remove_user_remove" msgid="8387386066949061256">"Exclude"</string>
     <string name="media_projection_dialog_title" msgid="3316063622495360646">"Începi să înregistrezi sau să proiectezi cu <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_dialog_warning" msgid="1303664408388363598">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> va avea acces la toate informațiile vizibile pe ecran sau redate pe dispozitiv în timp ce înregistrezi sau proiectezi. Între aceste informații se numără parole, detalii de plată, fotografii, mesaje și conținutul audio pe care îl redai."</string>
     <string name="media_projection_sys_service_dialog_title" msgid="3751133258891897878">"Începi să înregistrezi sau să proiectezi?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Dispozitivul este gestionat de unul dintre părinți. Părintele poate să vadă și să gestioneze informații cum ar fi aplicațiile pe care le folosești, locația ta și durata de folosire a dispozitivului."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Deblocat de TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Dispozitivul a fost blocat. Prea multe încercări de autentificare."</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Dispozitiv blocat\nAutentificare nereușită"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Setări de sunet"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Adaugă subtitrări automate la fișierele media"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Accesează ecranul împărțit cu aplicația actuală în dreapta"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Accesează ecranul împărțit cu aplicația actuală în stânga"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Comută de la ecranul împărțit la ecranul complet"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Treci la aplicația din dreapta sau de mai jos cu ecranul împărțit"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Treci la aplicația din stânga sau de mai sus cu ecranul împărțit"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"În modul ecran împărțit: înlocuiește o aplicație cu alta"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Introducere"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Comută la următoarea limbă"</string>
diff --git a/packages/SystemUI/res/values-ro/tiles_states_strings.xml b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
index ed8285d..5b96618 100644
--- a/packages/SystemUI/res/values-ro/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Dezactivat"</item>
     <item msgid="5137565285664080143">"Activat"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index d70d8ff..5e47464 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Системный администратор запретил делать скриншоты."</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Изменить"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Изменить скриншот"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Поделиться"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Поделиться скриншотом"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Увеличить площадь скриншота"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Закрыть скриншот"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканирование лица"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Отправить"</string>
     <string name="cancel" msgid="1089011503403416730">"Отмена"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Логотип приложения"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Подтвердить"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Повторить попытку"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Нажмите, чтобы отменить аутентификацию"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лицо распознано. Нажмите на значок разблокировки."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Аутентификация выполнена"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Отмена распознавания лица"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Ещё"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN-код"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Использовать графический ключ"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Использовать пароль"</string>
@@ -287,7 +288,7 @@
     <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Заставка"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Доступ к камере"</string>
     <string name="quick_settings_mic_label" msgid="8392773746295266375">"Доступ к микрофону"</string>
-    <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Доступно"</string>
+    <string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Есть"</string>
     <string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Заблокировано"</string>
     <string name="quick_settings_media_device_label" msgid="8034019242363789941">"Режим медиа"</string>
     <string name="quick_settings_user_title" msgid="8673045967216204537">"Пользователь"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Стандартная"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Средняя"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Высокая"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Разблокировать микрофон устройства?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Разблокировать камеру устройства?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Разблокировать камеру и микрофон устройства?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Удалить"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Добавить виджет"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Готово"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Добавить виджеты"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Быстрый доступ к виджетам любимых приложений, даже когда планшет заблокирован"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Разрешить добавлять любые виджеты на заблокированный экран?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Открыть настройки"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Включить рабочие приложения?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Этим устройством управляет один из твоих родителей. Он может видеть, например, какими приложениями ты пользуешься и где находишься, а также задавать определенные настройки (например, ограничивать время использования устройства)."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"Сеть VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Разблокировано агентом доверия"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Устройство заблокировано. Слишком много попыток аутентификации."</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Устройство заблокировано\nСбой аутентификации"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>."</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Настройки звука"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Автоматически добавлять субтитры"</string>
@@ -587,7 +596,7 @@
     <string name="volume_ringer_status_vibrate" msgid="6970078708957857825">"Вибрация"</string>
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Без звука"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"Трансляция"</string>
-    <string name="stream_notification_unavailable" msgid="4313854556205836435">"Недоступно, когда отключен звук вызовов"</string>
+    <string name="stream_notification_unavailable" msgid="4313854556205836435">"Недоступно в беззвучном режиме"</string>
     <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Недоступно при включенном режиме \"Не беспокоить\"."</string>
     <string name="stream_media_unavailable" msgid="6823020894438959853">"Недоступно при включенном режиме \"Не беспокоить\"."</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Нажмите, чтобы включить звук."</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Включить разделение экрана с текущим приложением справа"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Включить разделение экрана с текущим приложением слева"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Изменить режим разделения экрана на полноэкранный режим"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Перейти к приложению справа или внизу на разделенном экране"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Перейти к приложению слева или вверху на разделенном экране"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"В режиме разделения экрана заменить одно приложение другим"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Ввод"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Выбрать следующий язык"</string>
diff --git a/packages/SystemUI/res/values-ru/tiles_states_strings.xml b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
index 48ecf26..cdc4a98 100644
--- a/packages/SystemUI/res/values-ru/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Выключено"</item>
     <item msgid="5137565285664080143">"Включено"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 720f76d..5eea02c 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"තිර රූ ගැනීම ඔබගේ IT පරිපාලක විසින් අවහිර කර ඇත"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"සංස්කරණය කරන්න"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"තිර රුව සංස්කරණය කරන්න"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"බෙදා ගන්න"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"තිර රුව බෙදා ගන්න"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"තව ග්‍රහණය කරන්න"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"තිර රුව ඉවත ලන්න"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"මුහුණ ස්කෑන් කිරීම"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"යවන්න"</string>
     <string name="cancel" msgid="1089011503403416730">"අවලංගු කරන්න"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"යෙදුම් ලාංඡනය"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"තහවුරු කරන්න"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"නැවත උත්සාහ කරන්න"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"සත්‍යාපනය අවලංගු කිරීමට තට්ටු කරන්න"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"මුහුණ හඳුනා ගන්නා ලදි. ඉදිරියට යාමට අගුලු හැරීමේ නිරූපකය ඔබන්න."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"සත්‍යාපනය විය"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"සත්‍යාපනය අවලංගු කරන්න"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"තවත් විකල්ප"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN භාවිත කරන්න"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"රටාව භාවිත කරන්න"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"මුරපදය භාවිත කරන්න"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"සම්මත"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"මධ්‍යම"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"ඉහළ"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"උපාංග මයික්‍රෆෝනය අවහිර කිරීම ඉවත් කරන්නද?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"උපාංග කැමරාව අවහිර කිරීම ඉවත් කරන්නද?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"උපාංග කැමරාව සහ මයික්‍රෆෝනය අවහිර කිරීම ඉවත් කරන්නද?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"ඉවත් කරන්න"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"විජට්ටුව එක් කරන්න"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"නිමයි"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"විජට් එක් කරන්න"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"ඔබේ ටැබ්ලටය අගුළු හැරීමෙන් තොරව ඔබේ ප්‍රියතම යෙදුම් විජට් වෙත ඉක්මන් ප්‍රවේශය ලබා ගන්න."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"අගුළු තිරය මත ඕනෑම විජට් එකකට ඉඩ දෙන්න"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"සැකසීම් විවෘත කරන්න"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"කාර්ය යෙදුම් විරාම නොකරන්න ද?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"මෙම උපාංගය ඔබගේ මාපියන් විසින් කළමනාකරණය කෙරේ. ඔබ භාවිත කරන යෙදුම්, ඔබගේ ස්ථානය සහ ඔබගේ තිර කාලය වැනි තොරතුරු ඔබගේ මාපියන්ට බැලීමට සහ කළමනාකරණය කිරීමට හැකිය."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent මඟින් අඟුලු දමා තබා ගන්න"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"උපාංගය අගුළු දමා ඇත, බොහෝ සත්‍යාපන උත්සාහයන් ගණනකි"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"උපාංගය අගුළු දමා ඇත\nසත්‍යාපනය අසමත් විය"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"ශබ්ද සැකසීම්"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"මාධ්‍ය ස්වයංක්‍රීයව සිරස්තල"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHS වෙත වත්මන් යෙදුම සමග බෙදුම් තිරයට ඇතුළු වන්න"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHS වෙත වත්මන් යෙදුම සමග බෙදුම් තිරයට ඇතුළු වන්න"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"බෙදුම් තිරයේ සිට පූර්ණ තිරයට මාරු වන්න"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"බෙදුම් තිරය භාවිත කරන අතරතුර දකුණේ හෝ පහළින් ඇති යෙදුමට මාරු වන්න"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"බෙදුම් තිරය භාවිත කරන අතරතුර වමේ හෝ ඉහළ ඇති යෙදුමට මාරු වන්න"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"බෙදුම් තිරය අතරතුර: යෙදුමක් එකකින් තවත් එකක් ප්‍රතිස්ථාපනය කරන්න"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ආදානය"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"මීළඟ භාෂාවට මාරු වන්න"</string>
diff --git a/packages/SystemUI/res/values-si/tiles_states_strings.xml b/packages/SystemUI/res/values-si/tiles_states_strings.xml
index cbbc0e7..e7e9034 100644
--- a/packages/SystemUI/res/values-si/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-si/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"ක්‍රියාවිරහිතයි"</item>
     <item msgid="5137565285664080143">"ක්‍රියාත්මකයි"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 7722736..ea1a8f8 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Vytváranie snímok obrazovky zablokoval váš správca IT"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Upraviť"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Upraviť snímku obrazovky"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Zdieľať"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Zdieľať snímku obrazovky"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Zachytiť viac"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Zavrieť snímku obrazovky"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Skenovanie tváre"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Odoslať"</string>
     <string name="cancel" msgid="1089011503403416730">"Zrušiť"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logo aplikácie"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potvrdiť"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Skúsiť znova"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Klepnutím zrušíte overenie"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Tvár bola rozpoznaná. Pokračujte stlačením ikony odomknutia"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Overené"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Zrušiť overenie"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Ďalšie možnosti"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Použiť PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Použiť vzor"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Použiť heslo"</string>
@@ -328,7 +329,7 @@
     <string name="quick_settings_work_mode_label" msgid="6440531507319809121">"Pracovné aplikácie"</string>
     <string name="quick_settings_work_mode_paused_state" msgid="6681788236383735976">"Pozastavené"</string>
     <string name="quick_settings_night_display_label" msgid="8180030659141778180">"Nočný režim"</string>
-    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Zap. pri záp. slnka"</string>
+    <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="3358706312129866626">"Pri západe slnka"</string>
     <string name="quick_settings_night_secondary_label_until_sunrise" msgid="4063448287758262485">"Do východu slnka"</string>
     <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"Od <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"Do <xliff:g id="TIME">%s</xliff:g>"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Štandardný"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Stredný"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Vysoký"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Načúvacie zariadenia"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Chcete odblokovať mikrofón zariadenia?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Chcete odblokovať kameru zariadenia?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Chcete odblokovať fotoaparát a mikrofón zariadenia?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Odstrániť"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Pridať miniaplikáciu"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Hotovo"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Pridať miniaplikácie"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Majte k dispozícii rýchly prístup k svojim obľúbeným miniaplikáciám bez odomykania tabletu"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Chcete povoliť akúkoľvek miniaplikáciu na uzamknutej obrazovke?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Otvoriť nastavenia"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Zrušiť pozast. prac. aplikácií?"</string>
@@ -540,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Toto zariadenie spravuje tvoj rodič. Vidí a môže spravovať informácie, napríklad aplikácie, ktoré používaš, tvoju polohu a čas používania."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Odomknutie udržiava TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Zariadenie bolo uzamknuté, príliš mnoho pokusov o overenie"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Zariadenie je uzamknuté\nOverenie sa nepodarilo"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Nastavenia zvuku"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Automatické titulkovanie médií"</string>
@@ -589,7 +597,7 @@
     <string name="media_device_cast" msgid="4786241789687569892">"Prenos"</string>
     <string name="stream_notification_unavailable" msgid="4313854556205836435">"Nedostupné, pretože je vypnuté zvonenie"</string>
     <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Nedostupné, pretože je zapnutý režim bez vyrušení"</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"Nedostupné, pretože je zapnutý režim bez vyrušení"</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"Nedostupné, zapnutý režim bez vyrušení"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Klepnutím zapnite zvuk."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Klepnutím aktivujte režim vibrovania. Služby dostupnosti je možné stlmiť."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Klepnutím vypnite zvuk. Služby dostupnosti je možné stlmiť."</string>
@@ -612,7 +620,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"vypnete zvuk %s"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"zapnete zvuk %s"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> sa prehráva v:"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Zvuk sa prehrá v:"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Zvuk sa prehrá cez"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"Tuner používateľského rozhrania systému"</string>
     <string name="status_bar" msgid="4357390266055077437">"Stavový riadok"</string>
     <string name="demo_mode" msgid="263484519766901593">"Ukážka používateľského rozhrania systému"</string>
@@ -765,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Rozdelenie obrazovky s aktuálnou aplikáciou vpravo"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Rozdelenie obrazovky s aktuálnou aplikáciou vľavo"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Prepnutie rozdelenej obrazovky na celú"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prechod na aplikáciu vpravo alebo dole pri rozdelenej obrazovke"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Prechod na aplikáciu vľavo alebo hore pri rozdelenej obrazovke"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Počas rozdelenej obrazovky: nahradenie aplikácie inou"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vstup"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Prepnutie na ďalší jazyk"</string>
@@ -1166,7 +1172,7 @@
     <string name="mobile_data_connection_active" msgid="944490013299018227">"Pripojené"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"Dočasne pripojené"</string>
     <string name="mobile_data_poor_connection" msgid="819617772268371434">"Slabé pripojenie"</string>
-    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Automatické pripojenie cez mobilné dáta nefunguje"</string>
+    <string name="mobile_data_off_summary" msgid="3663995422004150567">"Mobilné dáta sa nepripájajú automaticky"</string>
     <string name="mobile_data_no_connection" msgid="1713872434869947377">"Bez pripojenia"</string>
     <string name="non_carrier_network_unavailable" msgid="770049357024492372">"Nie sú k dispozícii žiadne ďalšie siete"</string>
     <string name="all_network_unavailable" msgid="4112774339909373349">"Nie sú k dispozícii žiadne siete"</string>
diff --git a/packages/SystemUI/res/values-sk/tiles_states_strings.xml b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
index 50f5c25..6b5af80 100644
--- a/packages/SystemUI/res/values-sk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"Vypnuté"</item>
     <item msgid="5137565285664080143">"Zapnuté"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"Nedostupné"</item>
+    <item msgid="3079622119444911877">"Vypnuté"</item>
+    <item msgid="3028994095749238254">"Zapnuté"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index cbf5512..514d2f9 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Skrbnik za IT je onemogočil zajemanje posnetkov zaslona."</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Uredi"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Urejanje posnetka zaslona"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Deli"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Deljenje posnetka zaslona"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Zajemi več"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Opusti posnetek zaslona"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Optično branje obraza"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Pošlji"</string>
     <string name="cancel" msgid="1089011503403416730">"Prekliči"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logotip aplikacije"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Potrdite"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Poskusi znova"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Če želite preklicati preverjanje pristnosti, se dotaknite"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Obraz je prepoznan. Za nadaljevanje pritisnite ikono za odklepanje."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Preverjena pristnost"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Prekliči preverjanje pristnosti"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Več možnosti"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Uporabi kodo PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Uporabi vzorec"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Uporabi geslo"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standardni"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Srednji"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Visok"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite odblokirati mikrofon v napravi?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite odblokirati fotoaparat v napravi?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Želite odblokirati fotoaparat in mikrofon v napravi?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Odstrani"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Dodajanje pripomočka"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Končano"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Dodajte pripomočke"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Hitro dostopajte do priljubljenih pripomočkov za aplikacije brez odklepanja tabličnega računalnika."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Želite dovoliti poljubne pripomočke na zaklenjenem zaslonu?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Odpri nastavitve"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Želite znova aktivirati delovne aplikacije?"</string>
@@ -471,7 +482,7 @@
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Začni"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogočila to možnost"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Želite začeti predvajati?"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Pri predvajanju ima Android dostop do vsega, kar je prikazano na zaslonu ali se predvaja v napravi. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Pri predvajanju ima Android dostop do vsega, kar je prikazano na zaslonu ali se predvaja v napravi, zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
     <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Pri predvajanju aplikacije ima Android dostop do vsega, kar je prikazano ali predvajano v tej aplikaciji, zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Začni predvajanje"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Želite začeti deliti?"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Vklop razdeljenega zaslona s trenutno aplikacijo na desni"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Vklop razdeljenega zaslona s trenutno aplikacijo na levi"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Preklop iz razdeljenega zaslona v celozaslonski način"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Preklop na aplikacijo desno ali spodaj med uporabo razdeljenega zaslona"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Preklop na aplikacijo levo ali zgoraj med uporabo razdeljenega zaslona"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Pri razdeljenem zaslonu: medsebojna zamenjava aplikacij"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vnosna naprava"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Preklop na naslednji jezik"</string>
diff --git a/packages/SystemUI/res/values-sl/tiles_states_strings.xml b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
index 33ba216..9f9175e 100644
--- a/packages/SystemUI/res/values-sl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Izklopljeno"</item>
     <item msgid="5137565285664080143">"Vklopljeno"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index ac5955b..c13d76b 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Shkrepja e pamjeve të ekranit është bllokuar nga administratori i teknologjisë së informacionit"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Modifiko"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Modifiko pamjen e ekranit"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Ndaj"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Ndaj pamjen e ekranit"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Regjistro më shumë"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Hiq pamjen e ekranit"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Po skanon fytyrën"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Dërgo"</string>
     <string name="cancel" msgid="1089011503403416730">"Anulo"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logoja e aplikacionit"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Konfirmo"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Provo përsëri"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Trokit për të anuluar vërtetimin"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Fytyra u njoh. Shtyp ikonën e shkyçjes për të vazhduar."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"U vërtetua"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Anulo vërtetimin"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Opsione të tjera…"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Përdor kodin PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Përdor motivin"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Përdor fjalëkalimin"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Mesatar"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"I lartë"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Të zhbllokohet mikrofoni i pajisjes?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Të zhbllokohet kamera e pajisjes?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Të zhbllokohen kamera dhe mikrofoni i pajisjes?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Hiq"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Shto miniaplikacionin"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"U krye"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Shto miniaplikacionet"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Merr qasjen e shpejtë në miniaplikacionet e tua të preferuara pa e shkyçur tabletin."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Të lejohet ndonjë miniaplikacion te ekrani i kyçjes?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Hap cilësimet"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Hiq nga pauza apl. e punës?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Kjo pajisje menaxhohet nga prindi yt. Prindi yt mund të shikojë dhe menaxhojë informacionet, si p.sh. aplikacionet që përdor, vendndodhjen tënde dhe kohën para ekranit."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Mbajtur shkyçur nga TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Pajisja u kyç. Shumë përpjekje vërtetimi"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Pajisja është kyçur\nVërtetimi dështoi"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Cilësimet e zërit"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Media me titra automatike"</string>
@@ -588,8 +597,8 @@
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Pa zë"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"Transmeto"</string>
     <string name="stream_notification_unavailable" msgid="4313854556205836435">"Nuk ofrohet; ziles i është hequr zëri"</string>
-    <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Nuk ofrohet sepse \"Mos shqetëso\" është aktiv"</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"Nuk ofrohet sepse \"Mos shqetëso\" është aktiv"</string>
+    <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Nuk ofrohet; \"Mos shqetëso\" është aktiv"</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"Nuk ofrohet; \"Mos shqetëso\" është aktiv"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Trokit për të aktivizuar."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Trokit për ta caktuar te dridhja. Shërbimet e qasshmërisë mund të çaktivizohen."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Trokit për të çaktivizuar. Shërbimet e qasshmërisë mund të çaktivizohen."</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Hyr në ekranin e ndarë me aplikacionin aktual në anën e djathtë"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Hyr në ekranin e ndarë me aplikacionin aktual në anën e majtë"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Kalo nga ekrani i ndarë në ekranin e plotë"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Kalo tek aplikacioni djathtas ose poshtë kur përdor ekranin e ndarë"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Kalo tek aplikacioni në të majtë ose sipër kur përdor ekranin e ndarë"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Gjatë ekranit të ndarë: zëvendëso një aplikacion me një tjetër"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Hyrja"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Kalo te gjuha tjetër"</string>
diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
index fa06795..aa4832d 100644
--- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Joaktive"</item>
     <item msgid="5137565285664080143">"Aktive"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 085f1b0..bc6642a 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ИТ администратор блокира прављење снимака екрана"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Измени"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Измените снимак екрана"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Делите"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Делите снимак екрана"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Снимите још"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Одбаците снимак екрана"</string>
@@ -106,8 +105,8 @@
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"Обрађујемо видео снимка екрана"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"Обавештење о сесији снимања екрана је активно"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"Желите да започнете снимање?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Android има приступ комплетном садржају који је видљив на екрану или се пушта на уређају док снимате. Зато будите пажљиви са лозинкама, информацијама о плаћању, порукама, сликама и аудио и видеима."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Када снимате апликацију, Android има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Зато будите пажљиви са лозинкама, информацијама о плаћању, порукама, сликама и аудио и видеима."</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"Android има приступ комплетном садржају који је видљив на екрану или се пушта на уређају док снимате. Зато пазите на лозинке, информације о плаћању, поруке, слике, и аудио и видео садржај."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"Када снимате апликацију, Android има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Зато пазите на лозинке, информације о плаћању, поруке, слике, и аудио и видео садржај."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Започни снимање"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Снимај звук"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Звук уређаја"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Скенирање лица"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Пошаљи"</string>
     <string name="cancel" msgid="1089011503403416730">"Откажи"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Логотип апликације"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Потврди"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Пробај поново"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Додирните да бисте отказали потврду идентитета"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Лице препознато. Притисните икону откључавања за наставак."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Идентитет је потврђен"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Откажите потврду идентитета"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Још опција"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Користите PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Користите шаблон"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Користите лозинку"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Стандардно"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Средње"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Високо"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Слушни апарати"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Желите да одблокирате микрофон уређаја?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Желите да одблокирате камеру уређаја?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Желите да одблокирате камеру и микрофон уређаја?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Уклони"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Додај виџет"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Готово"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Додај виџете"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Брзо приступајте омиљеним виџетима за апликације без откључавања таблета."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Желите да дозволите све виџете на закључаном екрану?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Отвори подешавања"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Укључити пословне апликације?"</string>
@@ -466,17 +476,17 @@
     <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Једна апликација"</string>
     <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Делите или снимите апликацију"</string>
     <string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Желите да почнете снимање или пребацивање помоћу апликације <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
-    <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Када делите, снимате или пребацујете, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има приступ комплетном садржају који је видљив на екрану или се пушта на уређају. Зато будите пажљиви са лозинкама, информацијама о плаћању, порукама, сликама и аудио и видеима."</string>
-    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Када делите, снимате или пребацујете апликацију, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Зато будите пажљиви са лозинкама, информацијама о плаћању, порукама, сликама и аудио и видеима."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Када делите, снимате или пребацујете, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има приступ комплетном садржају који је видљив на екрану или се пушта на уређају. Зато пазите на лозинке, информације о плаћању, поруке, слике, и аудио и видео садржај."</string>
+    <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Када делите, снимате или пребацујете апликацију, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Зато пазите на лозинке, информације о плаћању, поруке, слике, и аудио и видео садржај."</string>
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"Покрени"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је онемогућила ову опцију"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"Желите да започнете пребацивање?"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Када пребацујете, Android има приступ комплетном садржају који је видљив на екрану или се пушта на уређају. Зато будите пажљиви са лозинкама, информацијама о плаћању, порукама, сликама и аудио и видеима."</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Када пребацујете апликацију, Android има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Зато будите пажљиви са лозинкама, информацијама о плаћању, порукама, сликама и аудио и видеима."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"Када пребацујете, Android има приступ комплетном садржају који је видљив на екрану или се пушта на уређају. Зато пазите на лозинке, информације о плаћању, поруке, слике, и аудио и видео садржај."</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"Када пребацујете апликацију, Android има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Зато пазите на лозинке, информације о плаћању, поруке, слике, и аудио и видео садржај."</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"Започни пребацивање"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"Желите да почнете да делите?"</string>
-    <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Када делите, снимате или пребацујете, Android има приступ комплетном садржају који је видљив на екрану или се пушта на уређају. Зато будите пажљиви са лозинкама, информацијама о плаћању, порукама, сликама и аудио и видеима."</string>
-    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Када делите, снимате или пребацујете апликацију, Android има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Зато будите пажљиви са лозинкама, информацијама о плаћању, порукама, сликама и аудио и видеима."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"Када делите, снимате или пребацујете, Android има приступ комплетном садржају који је видљив на екрану или се пушта на уређају. Зато пазите на лозинке, информације о плаћању, поруке, слике, и аудио и видео садржај."</string>
+    <string name="media_projection_entry_generic_permission_dialog_warning_single_app" msgid="3454859977888159495">"Када делите, снимате или пребацујете апликацију, Android има приступ комплетном садржају који је видљив или се пушта у тој апликацији. Зато пазите на лозинке, информације о плаћању, поруке, слике, и аудио и видео садржај."</string>
     <string name="media_projection_entry_generic_permission_dialog_continue" msgid="8640381403048097116">"Покрени"</string>
     <string name="media_projection_task_switcher_text" msgid="590885489897412359">"Дељење се зауставља када мењате апликације"</string>
     <string name="media_projection_task_switcher_action_switch" msgid="8682258717291921123">"Дели ову апликацију"</string>
@@ -593,7 +603,7 @@
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Додирните да бисте искључили звук. Звук услуга приступачности ће можда бити искључен."</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s. Додирните да бисте подесили на вибрацију."</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s. Додирните да бисте искључили звук."</string>
-    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Контрола шума"</string>
+    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"Контрола буке"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"Просторни звук"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"Искључено"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"Фиксно"</string>
@@ -763,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Покрени подељени екран за актуелну апликацију на десној страни"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Покрени подељени екран за актуелну апликацију на левој страни"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Пређи са подељеног екрана на цео екран"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Пређите у апликацију здесна или испод док користите подељени екран"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Пређите у апликацију слева или изнад док користите подељени екран"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"У режиму подељеног екрана: замена једне апликације другом"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Унос"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Пређи на следећи језик"</string>
@@ -1152,7 +1160,7 @@
     <string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"Проблем са очитавањем мерача батерије"</string>
     <string name="battery_state_unknown_notification_text" msgid="13720937839460899">"Додирните за више информација"</string>
     <string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"Није подешен"</string>
-    <string name="accessibility_bouncer" msgid="5896923685673320070">"унесите закључавање екрана"</string>
+    <string name="accessibility_bouncer" msgid="5896923685673320070">"унесите откључавање екрана"</string>
     <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сензор за отисак прста"</string>
     <string name="accessibility_authenticate_hint" msgid="798914151813205721">"потврдите идентитет"</string>
     <string name="accessibility_enter_hint" msgid="2617864063504824834">"унесите уређај"</string>
@@ -1174,7 +1182,7 @@
     <string name="wifi_empty_list_wifi_on" msgid="3864376632067585377">"Траже се мреже…"</string>
     <string name="wifi_failed_connect_message" msgid="4161863112079000071">"Повезивање са мрежом није успело"</string>
     <string name="wifi_wont_autoconnect_for_now" msgid="5782282612749867762">"WiFi тренутно не може да се аутоматски повеже"</string>
-    <string name="see_all_networks" msgid="3773666844913168122">"Погледајте све"</string>
+    <string name="see_all_networks" msgid="3773666844913168122">"Прикажи све"</string>
     <string name="to_switch_networks_disconnect_ethernet" msgid="6698111101156951955">"Да бисте променили мрежу, прекините етернет везу"</string>
     <string name="wifi_scan_notify_message" msgid="3753839537448621794">"Ради бољег доживљаја уређаја, апликације и услуге и даље могу да траже WiFi мреже у било ком тренутку, чак и када је WiFi искључен. То можете да промените у подешавањима WiFi скенирања. "<annotation id="link">"Промените"</annotation></string>
     <string name="turn_off_airplane_mode" msgid="8425587763226548579">"Искључи режим рада у авиону"</string>
diff --git a/packages/SystemUI/res/values-sr/tiles_states_strings.xml b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
index 55f5a3f..2acf1d2 100644
--- a/packages/SystemUI/res/values-sr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"Искључено"</item>
     <item msgid="5137565285664080143">"Укључено"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"Недоступно"</item>
+    <item msgid="3079622119444911877">"Искључено"</item>
+    <item msgid="3028994095749238254">"Укључено"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 854e547..15c370c 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Möjligheten att ta skärmbilder blockeras av IT-administratören"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Redigera"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Redigera skärmbild"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Dela"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Dela skärmbild"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Fånga mer"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Stäng skärmbild"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Registrerar ansikte"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Skicka"</string>
     <string name="cancel" msgid="1089011503403416730">"Avbryt"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Appens logotyp"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Bekräfta"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Försök igen"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Tryck för att avbryta autentiseringen"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ansiktet har identifierats. Tryck på ikonen lås upp."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Autentiserad"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Avbryt autentiseringen"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Fler alternativ"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Använd pinkod"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Använd mönster"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Använd lösenord"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Medelhög"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Hög"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vill du återaktivera enhetens mikrofon?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vill du återaktivera enhetens kamera?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vill du återaktivera enhetens kamera och mikrofon?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Ta bort"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Lägg till widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Klar"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Lägg till widgetar"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Få snabbåtkomst till appwidgetar utan att låsa upp surfplattan."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Vill du tillåta alla widgetar på låsskärmen?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Öppna inställningarna"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Vill du återuppta jobbappar?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Den här enheten hanteras av din förälder. Föräldern kan se och hantera information som vilka appar du använder, din plats och din skärmtid."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Hålls olåst med TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Enheten låstes på grund av för många autentiseringsförsök"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Enheten har låsts\nAutentiseringen misslyckades"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Ljudinställningar"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Texta media automatiskt"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Öppna delad skärm med aktuell app till höger"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Öppna delad skärm med aktuell app till vänster"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Byt mellan delad skärm och helskärm"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Byt till appen till vänster eller nedanför när du använder delad skärm"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Byt till appen till vänster eller ovanför när du använder delad skärm"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Med delad skärm: ersätt en app med en annan"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Inmatning"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Byt till nästa språk"</string>
@@ -900,7 +907,7 @@
     <string name="mobile_data" msgid="4564407557775397216">"Mobildata"</string>
     <string name="mobile_data_text_format" msgid="6806501540022589786">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="mobile_carrier_text_format" msgid="8912204177152950766">"<xliff:g id="CARRIER_NAME">%1$s</xliff:g> <xliff:g id="MOBILE_DATA_TYPE">%2$s</xliff:g>"</string>
-    <string name="wifi_is_off" msgid="5389597396308001471">"wifi är inaktiverat"</string>
+    <string name="wifi_is_off" msgid="5389597396308001471">"Wifi är inaktiverat"</string>
     <string name="bt_is_off" msgid="7436344904889461591">"Bluetooth är inaktiverat"</string>
     <string name="dnd_is_off" msgid="3185706903793094463">"Stör ej är inaktiverat"</string>
     <string name="dnd_is_on" msgid="7009368176361546279">"Stör ej har aktiverats"</string>
diff --git a/packages/SystemUI/res/values-sv/tiles_states_strings.xml b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
index f921f27..522538a 100644
--- a/packages/SystemUI/res/values-sv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Av"</item>
     <item msgid="5137565285664080143">"På"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 9dc17ab..41bac7b 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Kupiga picha za skrini kumezuiwa na Msimamizi wako wa TEHAMA"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Badilisha"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Badilisha picha ya skrini"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Tuma"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Shiriki picha ya skrini"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Nasa zaidi"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ondoa picha ya skrini"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Inachanganua uso"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Tuma"</string>
     <string name="cancel" msgid="1089011503403416730">"Ghairi"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Nembo ya programu"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Thibitisha"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Jaribu tena"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Gusa ili ughairi uthibitishaji"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Uso umetambuliwa. Bonyeza aikoni ya kufungua ili uendelee."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Umethibitishwa"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Ghairi Uthibitishaji"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Chaguo Zaidi"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Tumia PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Tumia mchoro"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Tumia nenosiri"</string>
@@ -362,8 +363,15 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Kawaida"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Wastani"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Juu"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Vifaa vya kusikilizia"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Ungependa kuwacha kuzuia maikrofoni ya kifaa?"</string>
-    <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Ungependa kuwacha kuzuia kamera ya kifaa?"</string>
+    <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Ungependa kuacha kuzuia kamera ya kifaa?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Ungependa kuwacha kuzuia kamera na maikrofoni ya kifaa?"</string>
     <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Hatua hii huruhusu programu na huduma zote zenye idhini zitumie maikrofoni yako."</string>
     <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Hatua hii huruhusu programu na huduma zote zenye idhini zitumie kamera yako."</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Ondoa"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Ongeza wijeti"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Nimemaliza"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Weka wijeti"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Fikia haraka wijeti za programu unazopenda bila kufungua kishikwambi chako."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Ungependa kuruhusu wijeti yoyote kwenye skrini iliyofungwa?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Fungua mipangilio"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Je, ungependa kuacha kusitisha programu za kazini?"</string>
@@ -540,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Kifaa hiki kinadhibitiwa na mzazi wako. Mzazi wako anaweza kuona na kudhibiti maelezo kama vile programu unazotumia, mahali ulipo na muda unaotumia kwenye kifaa."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Imefunguliwa na kipengele cha kutathmini hali ya kuaminika"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Kifaa kimefungwa, majaribio ya uthibitishaji ni mengi mno"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Kifaa kimefungwa\nImeshindwa kuthibitisha"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Mipangilio ya sauti"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Wekea maudhui manukuu kiotomatiki"</string>
@@ -765,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Tumia programu kwenye skrini iliyogawanywa upande wa kulia"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Tumia programu kwenye skrini iliyogawanywa upande wa kushoto"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Badilisha kutoka skrini iliyogawanywa utumie skrini nzima"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Badilisha ili uende kwenye programu iliyo kulia au chini unapotumia hali ya kugawa skrini"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Badilisha uende kwenye programu iliyo kushoto au juu unapotumia hali ya kugawa skrini"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ukigawanya skrini: badilisha kutoka programu moja hadi nyingine"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Vifaa vya kuingiza data"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Badilisha utumie lugha inayofuata"</string>
diff --git a/packages/SystemUI/res/values-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
index 227eee8..15de7f8 100644
--- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"Umezima"</item>
     <item msgid="5137565285664080143">"Umewasha"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"Havipatikani"</item>
+    <item msgid="3079622119444911877">"Vimezimwa"</item>
+    <item msgid="3028994095749238254">"Vimewashwa"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 1e54fc9..2cfba01 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -110,4 +110,6 @@
     <dimen name="controls_content_padding">24dp</dimen>
     <dimen name="control_list_vertical_spacing">8dp</dimen>
     <dimen name="control_list_horizontal_spacing">16dp</dimen>
+    <!-- For portrait direction in unfold foldable device, we don't need keyguard_smartspace_top_offset-->
+    <dimen name="keyguard_smartspace_top_offset">0dp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 5d6b131..019dddc 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"ஸ்கிரீன்ஷாட்கள் எடுப்பதை உங்கள் IT நிர்வாகி தடைசெய்துள்ளார்"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"திருத்து"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"ஸ்கிரீன்ஷாட்டைத் திருத்தும்"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"பகிர்"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"ஸ்கிரீன்ஷாட்டைப் பகிர்"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"கூடுதலாக படமெடு"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ஸ்கிரீன்ஷாட்டை நிராகரிக்கும்"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"முகத்தை ஸ்கேன் செய்கிறது"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"அனுப்பு"</string>
     <string name="cancel" msgid="1089011503403416730">"ரத்துசெய்"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"ஆப்ஸ் லோகோ"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"உறுதிப்படுத்துக"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"மீண்டும் முயல்க"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"பயோமெட்ரிக் அடையாளத்தை ரத்துசெய்ய தட்டவும்"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"முகம் அங்கீகரிக்கப்பட்டது. தொடர அன்லாக் ஐகானை அழுத்தவும்."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"அங்கீகரிக்கப்பட்டது"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"அங்கீகரிப்பை ரத்துசெய்"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"கூடுதல் விருப்பங்கள்"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"பின்னைப் பயன்படுத்து"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"பேட்டர்னைப் பயன்படுத்து"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"கடவுச்சொல்லைப் பயன்படுத்து"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"இயல்புநிலை"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"நடுத்தரம்"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"அதிகம்"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"சாதனத்தின் மைக்ரோஃபோனுக்கான தடுப்பை நீக்கவா?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"சாதனத்தின் கேமராவுக்கான தடுப்பை நீக்கவா?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"சாதனத்தின் கேமராவுக்கும் மைக்ரோஃபோனுக்குமான தடுப்பை நீக்கவா?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"அகற்றும்"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"விட்ஜெட்டைச் சேர்"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"முடிந்தது"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"விட்ஜெட்களைச் சேர்"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"டேப்லெட்டை அன்லாக் செய்யாமலே உங்களுக்கு விருப்பமான ஆப்ஸ் விட்ஜெட்களுக்கு விரைவு அணுகலைப் பெறுங்கள்."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"பூட்டுத் திரையில் எந்தவொரு விட்ஜெட்டையும் அனுமதிக்கவா?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"அமைப்புகளைத் திற"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"பணி ஆப்ஸை மீண்டும் இயக்கவா?"</string>
@@ -574,7 +585,7 @@
     <string name="screen_pinning_exit" msgid="4553787518387346893">"ஆப்ஸ் பின்னிலிருந்து அகற்றப்பட்டது"</string>
     <string name="stream_voice_call" msgid="7468348170702375660">"அழைப்பு"</string>
     <string name="stream_system" msgid="7663148785370565134">"சிஸ்டம்"</string>
-    <string name="stream_ring" msgid="7550670036738697526">"ரிங் செய்"</string>
+    <string name="stream_ring" msgid="7550670036738697526">"அழைப்பு ஒலி"</string>
     <string name="stream_music" msgid="2188224742361847580">"மீடியா"</string>
     <string name="stream_alarm" msgid="16058075093011694">"அலாரம்"</string>
     <string name="stream_notification" msgid="7930294049046243939">"அறிவிப்பு"</string>
@@ -610,7 +621,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"%s ஐ ஒலியடக்கும்"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"%s ஐ ஒலி இயக்கும்"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"இதில் <xliff:g id="LABEL">%s</xliff:g> பிளே ஆகிறது"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"இல் ஆடியோ பிளே ஆகும்"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"ஆடியோ இதில் பிளே ஆகும்"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"System UI Tuner"</string>
     <string name="status_bar" msgid="4357390266055077437">"நிலைப் பட்டி"</string>
     <string name="demo_mode" msgid="263484519766901593">"சிஸ்டம் பயனர் இடைமுக டெமோ பயன்முறை"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"வலதுபுறத்தில் தற்போதைய ஆப்ஸ் தோன்றுமாறு திரைப் பிரிப்பை அமைத்தல்"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"இடதுபுறத்தில் தற்போதைய ஆப்ஸ் தோன்றுமாறு திரைப் பிரிப்பை அமைத்தல்"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"திரைப் பிரிப்பு பயன்முறையிலிருந்து முழுத்திரைக்கு மாற்றுதல்"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"திரைப் பிரிப்பைப் பயன்படுத்தும்போது வலது/கீழ் உள்ள ஆப்ஸுக்கு மாறுங்கள்"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"திரைப் பிரிப்பைப் பயன்படுத்தும்போது இடது/மேலே உள்ள ஆப்ஸுக்கு மாறுங்கள்"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"திரைப் பிரிப்பின்போது: ஓர் ஆப்ஸுக்குப் பதிலாக மற்றொன்றை மாற்றுதல்"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"உள்ளீடு"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"அடுத்த மொழிக்கு மாற்றுதல்"</string>
@@ -1087,7 +1096,7 @@
     <string name="media_output_dialog_multiple_devices" msgid="1093771040315422350">"<xliff:g id="COUNT">%1$d</xliff:g> சாதனங்கள் தேர்ந்தெடுக்கப்பட்டுள்ளன"</string>
     <string name="media_output_dialog_disconnected" msgid="7090512852817111185">"(துண்டிக்கப்பட்டது)"</string>
     <string name="media_output_dialog_connect_failed" msgid="3080972621975339387">"இணைக்க முடியவில்லை. மீண்டும் முயல தட்டவும்."</string>
-    <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"சாதனத்தை இணைத்தல்"</string>
+    <string name="media_output_dialog_pairing_new" msgid="5098212763195577270">"சாதனத்தை இணை"</string>
     <string name="media_output_dialog_launch_app_text" msgid="1527413319632586259">"இந்த அமர்வை அலைபரப்ப ஆப்ஸைத் திறங்கள்."</string>
     <string name="media_output_dialog_unknown_launch_app_name" msgid="1084899329829371336">"அறியப்படாத ஆப்ஸ்"</string>
     <string name="media_output_dialog_button_stop_casting" msgid="6581379537930199189">"அலைபரப்புவதை நிறுத்து"</string>
diff --git a/packages/SystemUI/res/values-ta/tiles_states_strings.xml b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
index 6043cf2..cacde5e 100644
--- a/packages/SystemUI/res/values-ta/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"முடக்கப்பட்டுள்ளது"</item>
     <item msgid="5137565285664080143">"இயக்கப்பட்டுள்ளது"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 5c5d828..1b3c5e2 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"స్క్రీన్‌షాట్‌లు తీయడాన్ని మీ IT అడ్మిన్ బ్లాక్ చేశారు"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"ఎడిట్ చేయండి"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"స్క్రీన్‌షాట్‌ను ఎడిట్ చేయండి"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"షేర్ చేయండి"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"స్క్రీన్‌షాట్‌ను షేర్ చేయండి"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"మరిన్ని క్యాప్చర్ చేయండి"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"స్క్రీన్‌షాట్‌ను విస్మరించు"</string>
@@ -107,7 +106,7 @@
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"స్క్రీన్ రికార్డ్ సెషన్ కోసం ఆన్‌గోయింగ్ నోటిఫికేషన్"</string>
     <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"రికార్డింగ్‌ను ప్రారంభించాలా?"</string>
     <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"మీరు రికార్డ్ చేసేటప్పుడు, మీ స్క్రీన్‌పై కనిపించే దేనికైనా లేదా మీ పరికరంలో ప్లే అయిన దేనికైనా Androidకు యాక్సెస్ ఉంటుంది. కాబట్టి పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"మీరు ఏదైనా యాప్‌ను రికార్డ్ చేసేటప్పుడు, ఆ యాప్‌లో చూపబడిన దేనికైనా లేదా ప్లే అయిన దేనికైనా Androidకు యాక్సెస్ ఉంటుంది. కాబట్టి పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"మీరు ఏదైనా యాప్‌ను రికార్డ్ చేసేటప్పుడు, ఆ యాప్‌లో చూపబడిన లేదా ప్లే అవుతున్న దేనినైనా Android యాక్సెస్ చేయగలదు. కాబట్టి పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, ఫోటోలు, ఆడియో, వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"రికార్డింగ్‌ను ప్రారంభించండి"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"ఆడియోను రికార్డ్ చేయండి"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"పరికరం ఆడియో"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"ముఖాన్ని స్కాన్ చేస్తోంది"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"పంపండి"</string>
     <string name="cancel" msgid="1089011503403416730">"రద్దు చేయండి"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"యాప్ లోగో"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"నిర్ధారించండి"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"మళ్లీ ట్రై చేయండి"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"ప్రామాణీకరణను రద్దు చేయడానికి నొక్కండి"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"ముఖం గుర్తించబడింది. కొనసాగడానికి అన్‌లాక్ చిహ్నం నొక్కండి."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ప్రామాణీకరించబడింది"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ప్రామాణీకరణను రద్దు చేయండి"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"మరిన్ని ఆప్షన్‌లు"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PINను ఉపయోగించండి"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ఆకృతిని ఉపయోగించండి"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"పాస్‌వర్డ్‌ను ఉపయోగించండి"</string>
@@ -308,7 +309,7 @@
     <string name="quick_settings_font_scaling_label" msgid="5289001009876936768">"ఫాంట్ సైజ్"</string>
     <string name="quick_settings_more_user_settings" msgid="7634653308485206306">"యూజర్‌లను మేనేజ్ చేయండి"</string>
     <string name="quick_settings_done" msgid="2163641301648855793">"పూర్తయింది"</string>
-    <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"మూసివేయి"</string>
+    <string name="quick_settings_close_user_panel" msgid="5599724542275896849">"మూసివేయండి"</string>
     <string name="quick_settings_connected" msgid="3873605509184830379">"కనెక్ట్ చేయబడినది"</string>
     <string name="quick_settings_connected_battery_level" msgid="1322075669498906959">"కనెక్ట్ చేయబడింది, బ్యాటరీ <xliff:g id="BATTERY_LEVEL_AS_PERCENTAGE">%1$s</xliff:g>"</string>
     <string name="quick_settings_connecting" msgid="2381969772953268809">"కనెక్ట్ అవుతోంది..."</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"స్టాండర్డ్"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"మధ్యస్థం"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"అధికం"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"పరికరం మైక్రోఫోన్‌ను అన్‌బ్లాక్ చేయమంటారా?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"పరికరంలోని కెమెరాను అన్‌బ్లాక్ చేయమంటారా?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"పరికరంలోని కెమెరా, మైక్రోఫోన్‌లను అన్‌బ్లాక్ చేయమంటారా?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"తీసివేయండి"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"విడ్జెట్‌ను జోడించండి"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"పూర్తయింది"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"విడ్జెట్‌లను జోడించండి"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"మీ టాబ్లెట్‌ను అన్‌లాక్ చేయకుండానే మీకు ఇష్టమైన యాప్ విడ్జెట్‌లకు క్విక్ యాక్సెస్‌ను పొందండి."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"లాక్ స్క్రీన్‌లో ఏదైనా విడ్జెట్‌ను అనుమతించాలా?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"సెట్టింగ్‌లను తెరవండి"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"వర్క్ యాప్స్ అన్‌పాజ్ చేయాలా?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"ఈ పరికరాన్ని మీ తల్లి/తండ్రి మేనేజ్ చేస్తున్నారు. మీ తల్లి/తండ్రి, మీరు ఉపయోగించే యాప్‌లు, మీ లొకేషన్, అలాగే మీ పరికర వినియోగ వ్యవధి వంటి సమాచారాన్ని చూడగలరు, మేనేజ్ చేయగలరు."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent ద్వారా అన్‌లాక్ చేయబడింది"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"చాలాసార్లు ప్రామాణీకరించడానికి ప్రయత్నించినందున పరికరం లాక్ అయింది"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"ప్రామాణీకరణ విఫలమైంది\nపరికరం లాక్ అయింది"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"ధ్వని సెట్టింగ్‌లు"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"మీడియాకు ఆటోమేటిక్ క్యాప్షన్‌లు"</string>
@@ -598,7 +607,7 @@
     <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"నాయిస్ కంట్రోల్"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"స్పేషియల్ ఆడియో"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"ఆఫ్ చేయండి"</string>
-    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ఆరంభించండి"</string>
+    <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"ఫిక్స్‌డ్"</string>
     <string name="volume_panel_spatial_audio_tracking" msgid="5711115234001762974">"హెడ్ ట్రాకింగ్"</string>
     <string name="volume_ringer_change" msgid="3574969197796055532">"రింగర్ మోడ్‌ను మార్చడానికి ట్యాప్ చేయండి"</string>
     <string name="volume_ringer_hint_mute" msgid="4263821214125126614">"మ్యూట్ చేయి"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"RHSకు ప్రస్తుత యాప్‌తో స్ప్లిట్ స్క్రీన్‌ను ఎంటర్ చేయండి"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"LHSకు ప్రస్తుత యాప్‌తో స్ప్లిట్ స్క్రీన్‌ను ఎంటర్ చేయండి"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"స్ప్లిట్ స్క్రీన్‌ను ఫుల్ స్క్రీన్‌కు మార్చండి"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"స్ప్లిట్ స్క్రీన్ ఉపయోగిస్తున్నప్పుడు కుడి లేదా పైన యాప్‌నకు మారండి"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"స్ప్లిట్ స్క్రీన్ ఉపయోగిస్తున్నప్పుడు ఎడమ లేదా పైన యాప్‌నకు మారండి"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"స్ప్లిట్ స్క్రీన్ సమయంలో: ఒక దాన్నుండి మరో దానికి యాప్ రీప్లేస్ చేయండి"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ఇన్‌పుట్"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"తర్వాత భాషకు స్విచ్ అవ్వండి"</string>
@@ -1240,7 +1247,7 @@
     <string name="home_quick_affordance_unavailable_configure_the_app" msgid="604424593994493281">"• కనీసం ఒక పరికరం లేదా పరికర ప్యానెల్ అందుబాటులో ఉండాలి"</string>
     <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"నోట్‌టేకింగ్ షార్ట్‌కట్‌ను ఉపయోగించడానికి ఆటోమేటిక్ సెట్టింగ్ నోట్స్ యాప్‌ను ఎంచుకోండి"</string>
     <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"యాప్‌ను ఎంచుకోండి"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"షార్ట్‌కట్‌ను తాకి, నొక్కి ఉంచు"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"షార్ట్‌కట్‌ను నొక్కి, పట్టుకోండి"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"రద్దు చేయండి"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"ఇప్పుడే స్క్రీన్‌లను మార్చండి"</string>
     <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"ఫోన్‌ను అన్‌ఫోల్డ్ చేయండి"</string>
@@ -1261,7 +1268,7 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"వర్క్ ప్రొఫైల్‌కు మారండి"</string>
     <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"ఆఫీస్ ఫోన్ యాప్‌ను ఇన్‌స్టాల్ చేయండి"</string>
     <string name="call_from_work_profile_close" msgid="5830072964434474143">"రద్దు చేయండి"</string>
-    <string name="lock_screen_settings" msgid="6152703934761402399">"లాక్ స్క్రీన్‌ను అనుకూలీకరించండి"</string>
+    <string name="lock_screen_settings" msgid="6152703934761402399">"లాక్ స్క్రీన్ అనుకూలంగా మార్చండి"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"లాక్ స్క్రీన్‌ను అనుకూలంగా మార్చుకోవడానికి అన్‌లాక్ చేయండి"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"Wi-Fi అందుబాటులో లేదు"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"కెమెరా బ్లాక్ చేయబడింది"</string>
diff --git a/packages/SystemUI/res/values-te/tiles_states_strings.xml b/packages/SystemUI/res/values-te/tiles_states_strings.xml
index 370aeb0..a1ee29f 100644
--- a/packages/SystemUI/res/values-te/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-te/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"ఆఫ్‌లో ఉంది"</item>
     <item msgid="5137565285664080143">"ఆన్‌లో ఉంది"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 90074372..e8d376d 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"การจับภาพหน้าจอถูกบล็อกโดยผู้ดูแลระบบไอทีของคุณ"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"แก้ไข"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"แก้ไขภาพหน้าจอ"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"แชร์"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"แชร์ภาพหน้าจอ"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"จับภาพได้มากขึ้น"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"ปิดภาพหน้าจอ"</string>
@@ -146,12 +145,13 @@
     <string name="accessibility_phone_button" msgid="4256353121703100427">"โทรศัพท์"</string>
     <string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ตัวช่วยเสียง"</string>
     <string name="accessibility_wallet_button" msgid="1458258783460555507">"Wallet"</string>
-    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"เครื่องมือสแกนคิวอาร์โค้ด"</string>
+    <string name="accessibility_qr_code_scanner_button" msgid="7521277927692910795">"แอปสแกนคิวอาร์โค้ด"</string>
     <string name="accessibility_unlock_button" msgid="3613812140816244310">"ปลดล็อกแล้ว"</string>
     <string name="accessibility_lock_icon" msgid="661492842417875775">"อุปกรณ์ถูกล็อก"</string>
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"กำลังสแกนใบหน้า"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"ส่ง"</string>
     <string name="cancel" msgid="1089011503403416730">"ยกเลิก"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"โลโก้แอป"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"ยืนยัน"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"ลองอีกครั้ง"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"แตะเพื่อยกเลิกการตรวจสอบสิทธิ์"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"จดจำใบหน้าได้ กดไอคอนปลดล็อกเพื่อดำเนินการต่อ"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"ตรวจสอบสิทธิ์แล้ว"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"ยกเลิกการตรวจสอบสิทธิ์"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"ตัวเลือกเพิ่มเติม"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"ใช้ PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"ใช้รูปแบบ"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"ใช้รหัสผ่าน"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"มาตรฐาน"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"ปานกลาง"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"สูง"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"เลิกบล็อกไมโครโฟนของอุปกรณ์ใช่ไหม"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"เลิกบล็อกกล้องของอุปกรณ์ใช่ไหม"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"เลิกบล็อกกล้องและไมโครโฟนของอุปกรณ์ใช่ไหม"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"นำออก"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"เพิ่มวิดเจ็ต"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"เสร็จสิ้น"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"เพิ่มวิดเจ็ต"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"เข้าถึงวิดเจ็ตแอปโปรดได้อย่างรวดเร็วโดยไม่ต้องปลดล็อกแท็บเล็ต"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"อนุญาตวิดเจ็ตบนหน้าจอล็อกไหม"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"เปิดการตั้งค่า"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"ยกเลิกการหยุดแอปงานชั่วคราวไหม"</string>
@@ -610,7 +621,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"ปิดเสียง%s"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"เปิดเสียง%s"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"กำลังเล่น <xliff:g id="LABEL">%s</xliff:g> ใน"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"เสียงจะเล่นต่อไป"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"เสียงจะเล่นต่อใน"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"ตัวรับสัญญาณ UI ระบบ"</string>
     <string name="status_bar" msgid="4357390266055077437">"แถบสถานะ"</string>
     <string name="demo_mode" msgid="263484519766901593">"โหมดสาธิต UI ของระบบ"</string>
@@ -626,7 +637,7 @@
     <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"ปลดล็อกเพื่อใช้"</string>
     <string name="wallet_error_generic" msgid="257704570182963611">"เกิดปัญหาในการดึงข้อมูลบัตรของคุณ โปรดลองอีกครั้งในภายหลัง"</string>
     <string name="wallet_lockscreen_settings_label" msgid="3539105300870383570">"การตั้งค่าหน้าจอล็อก"</string>
-    <string name="qr_code_scanner_title" msgid="1938155688725760702">"เครื่องมือสแกนคิวอาร์โค้ด"</string>
+    <string name="qr_code_scanner_title" msgid="1938155688725760702">"แอปสแกนคิวอาร์โค้ด"</string>
     <string name="qr_code_scanner_updating_secondary_label" msgid="8344598017007876352">"กำลังอัปเดต"</string>
     <string name="status_bar_work" msgid="5238641949837091056">"โปรไฟล์งาน"</string>
     <string name="status_bar_airplane" msgid="4848702508684541009">"โหมดบนเครื่องบิน"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"เข้าสู่โหมดแยกหน้าจอโดยแอปปัจจุบันอยู่ด้านขวา"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"เข้าสู่โหมดแยกหน้าจอโดยแอปปัจจุบันอยู่ด้านซ้าย"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"เปลี่ยนจากโหมดแยกหน้าจอเป็นเต็มหน้าจอ"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"เปลี่ยนไปใช้แอปทางด้านขวาหรือด้านล่างขณะใช้โหมดแยกหน้าจอ"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"เปลี่ยนไปใช้แอปทางด้านซ้ายหรือด้านบนขณะใช้โหมดแยกหน้าจอ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ระหว่างใช้โหมดแยกหน้าจอ: เปลี่ยนแอปหนึ่งเป็นอีกแอปหนึ่ง"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"อินพุต"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"เปลี่ยนเป็นภาษาถัดไป"</string>
@@ -1238,7 +1247,7 @@
     <string name="home_quick_affordance_unavailable_configure_the_app" msgid="604424593994493281">"• มีอุปกรณ์หรือแผงอุปกรณ์พร้อมใช้งานอย่างน้อย 1 รายการ"</string>
     <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"เลือกแอปโน้ตเริ่มต้นเพื่อใช้ทางลัดการจดบันทึก"</string>
     <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"เลือกแอป"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"แตะแป้นพิมพ์ลัดค้างไว้"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"แตะทางลัดค้างไว้"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"ยกเลิก"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"สลับหน้าจอเลย"</string>
     <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"กางโทรศัพท์ออก"</string>
diff --git a/packages/SystemUI/res/values-th/tiles_states_strings.xml b/packages/SystemUI/res/values-th/tiles_states_strings.xml
index acaf9f0..d6351ce 100644
--- a/packages/SystemUI/res/values-th/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-th/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"ปิด"</item>
     <item msgid="5137565285664080143">"เปิด"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 1ecd905..54bb74b 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Na-block ng iyong IT admin ang pagkuha ng mga screenshot"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"I-edit"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"I-edit ang screenshot"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Ibahagi"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Ibahagi ang screenshot"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Mag-capture pa"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"I-dismiss ang screenshot"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Sina-scan ang mukha"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Ipadala"</string>
     <string name="cancel" msgid="1089011503403416730">"Kanselahin"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Logo ng app"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Kumpirmahin"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Subukang muli"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"I-tap para kanselahin ang pag-authenticate"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Nakilala ang mukha. Pindutin ang unlock para magpatuloy."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Na-authenticate"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Kanselahin ang Pag-authenticate"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Higit Pang Opsyon"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Gumamit ng PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Gumamit ng pattern"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Gumamit ng password"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standard"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Katamtaman"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Mataas"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Mga hearing device"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"I-unblock ang mikropono ng device?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"I-unblock ang camera ng device?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"I-unblock ang camera at mikropono ng device?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Alisin"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Magdagdag ng widget"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Tapos na"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Magdagdag ng mga widget"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Makakuha ng mabilis na access sa paborito mong mga widget ng app nang hindi ina-unlock ang iyong tablet."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Payagan ang anumang widget sa lock screen?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Buksan ang mga setting"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"I-unpause ang mga work app?"</string>
@@ -464,7 +474,7 @@
     <string name="media_projection_sys_service_dialog_warning" msgid="2443872865267330320">"Ang serbisyong nagbibigay ng function na ito ay magkakaroon ng access sa lahat ng impormasyong nakikita sa iyong screen o pine-play mula sa device mo habang nagre-record o nagka-cast. Kasama rito ang impormasyong tulad ng mga password, detalye ng pagbabayad, larawan, mensahe, at audio na pine-play mo."</string>
     <string name="screen_share_permission_dialog_option_entire_screen" msgid="3131200488455089620">"Buong screen"</string>
     <string name="screen_share_permission_dialog_option_single_app" msgid="4350961814397220929">"Isang app"</string>
-    <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"Ibahagi o i-record ang isang app"</string>
+    <string name="screen_share_permission_app_selector_title" msgid="1404878013670347899">"I-share o i-record ang isang app"</string>
     <string name="media_projection_entry_app_permission_dialog_title" msgid="9155535851866407199">"Simulang mag-record o mag-cast gamit ang <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>?"</string>
     <string name="media_projection_entry_app_permission_dialog_warning_entire_screen" msgid="8736391633234144237">"Kapag nagbabahagi, nagre-record, o nagka-cast ka, may access ang <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sa kahit anong nakikita sa iyong screen o pine-play sa device mo. Kaya mag-ingat sa mga bagay-bagay tulad ng mga password, detalye ng pagbabayad, mensahe, larawan, at audio at video."</string>
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="5211695779082563959">"Kapag nagbabahagi, nagre-record, o nagka-cast ka ng app, may access ang <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sa kahit anong ipinapakita o pine-play sa app na iyon. Kaya mag-ingat sa mga bagay-bagay tulad ng mga password, detalye ng pagbabayad, mensahe, larawan, at audio at video."</string>
@@ -763,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Lumipat sa split screen nang nasa RHS ang kasalukuyang app"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Lumipat sa split screen nang nasa LHS ang kasalukuyang app"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Lumipat sa full screen mula sa split screen"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Lumipat sa app sa kanan o ibaba habang ginagamit ang split screen"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Lumipat sa app sa kaliwa o itaas habang ginagamit ang split screen"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Habang nasa split screen: magpalit-palit ng app"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Input"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Lumipat sa susunod na wika"</string>
diff --git a/packages/SystemUI/res/values-tl/tiles_states_strings.xml b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
index 6de62df..fe2827f 100644
--- a/packages/SystemUI/res/values-tl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"Naka-off"</item>
     <item msgid="5137565285664080143">"Naka-on"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"Hindi available"</item>
+    <item msgid="3079622119444911877">"Naka-off"</item>
+    <item msgid="3028994095749238254">"Naka-on"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 7d10bb8..5364c83 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -59,7 +59,7 @@
     <string name="hdmi_cec_set_menu_language_description" msgid="8176716678074126619">"Başka bir cihaz tarafından sistem dilinin değiştirilmesi istendi"</string>
     <string name="hdmi_cec_set_menu_language_accept" msgid="2513689457281009578">"Dili değiştir"</string>
     <string name="hdmi_cec_set_menu_language_decline" msgid="7650721096558646011">"Mevcut dili koru"</string>
-    <string name="share_wifi_button_text" msgid="1285273973812029240">"Kablosuz ağı paylaşın"</string>
+    <string name="share_wifi_button_text" msgid="1285273973812029240">"Kablosuz ağı paylaş"</string>
     <string name="wifi_debugging_title" msgid="7300007687492186076">"Bu ağda kablosuz hata ayıklamaya izin verilsin mi?"</string>
     <string name="wifi_debugging_message" msgid="5461204211731802995">"Ağ Adı (SSID)\n<xliff:g id="SSID_0">%1$s</xliff:g>\n\nKablosuz Adresi (BSSID)\n<xliff:g id="BSSID_1">%2$s</xliff:g>"</string>
     <string name="wifi_debugging_always" msgid="2968383799517975155">"Bu ağda her zaman izin ver"</string>
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"BT yöneticiniz ekran görüntüsü almayı engelledi"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Düzenle"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Ekran görüntüsünü düzenle"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Paylaş"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Ekranı paylaş"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Alanı genişlet"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Ekran görüntüsünü kapat"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Yüz taranıyor"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Gönder"</string>
     <string name="cancel" msgid="1089011503403416730">"İptal"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Uygulama logosu"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Onayla"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Tekrar dene"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Kimlik doğrulama işlemini iptal etmek için dokunun"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Yüzünüz tanındı. Kilit açma simgesine basın."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kimliği Doğrulandı"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Kimlik doğrulamayı iptal et"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Diğer Seçenekler"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN kullan"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Deseni kullan"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Şifre kullan"</string>
@@ -265,7 +266,7 @@
     <string name="quick_settings_bluetooth_label" msgid="7018763367142041481">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_detail_empty_text" msgid="5760239584390514322">"Kullanılabilir eşlenmiş cihaz yok"</string>
     <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"Cihaz bağlamak veya cihazın bağlantısını kesmek için dokunun"</string>
-    <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Yeni cihaz eşleme"</string>
+    <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"Yeni cihaz eşle"</string>
     <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"Tümünü göster"</string>
     <string name="turn_on_bluetooth" msgid="5681370462180289071">"Bluetooth\'u kullan"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"Bağlandı"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standart"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Orta"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Yüksek"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"İşitme cihazları"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Cihaz mikrofonunun engellemesi kaldırılsın mı?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Cihaz kamerasının engellemesi kaldırılsın mı?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Cihaz kamerası ile mikrofonunun engellemesi kaldırılsın mı?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Kaldır"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Widget ekle"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Bitti"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Widget ekleme"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Tabletinizin kilidini açmadan favori uygulama widget\'larınıza hızlıca erişin."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Kilit ekranında tüm widget\'lara izin verilsin mi?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Ayarları açın"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"İş uygulamaları devam ettirilsin mi?"</string>
@@ -540,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Bu cihaz ebeveyniniz tarafından yönetiliyor. Kullandığınız uygulamalar, konumunuz ve ekran başında kalma süreniz gibi bilgiler ebeveyniniz tarafından görülüp yönetilebilir."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent tarafından kilit açık tutuldu"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Cihaz kilitlendi. Çok fazla sayıda kimlik doğrulama denemesi yapıldı."</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Cihaz kilitli\nKimlik doğrulama yapılamadı"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Ses ayarları"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Otomatik medya altyazısı"</string>
@@ -765,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Mevcut uygulamayı sağ tarafa alarak bölünmüş ekrana geç"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Mevcut uygulamayı sol tarafa alarak bölünmüş ekrana geç"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Bölünmüş ekrandan tam ekrana geç"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bölünmüş ekran kullanırken sağdaki veya alttaki uygulamaya geçiş yapın"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bölünmüş ekran kullanırken soldaki veya üstteki uygulamaya geçiş yapın"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Bölünmüş ekran etkinken: Bir uygulamayı başkasıyla değiştir"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Giriş"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Sonraki dile geç"</string>
diff --git a/packages/SystemUI/res/values-tr/tiles_states_strings.xml b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
index 0c086f8..1ed106f 100644
--- a/packages/SystemUI/res/values-tr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"Kapalı"</item>
     <item msgid="5137565285664080143">"Açık"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"Yok"</item>
+    <item msgid="3079622119444911877">"Kapalı"</item>
+    <item msgid="3028994095749238254">"Açık"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index b52d25e..da1dfa4 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Системний адміністратор заблокував можливість робити знімки екрана"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Редагувати"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Редагувати знімок екрана"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Поділитися"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Поділитися знімком екрана"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Включити більше деталей"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Закрити знімок екрана"</string>
@@ -111,9 +110,9 @@
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"Почати записування"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"Записувати звук"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"Звук із пристрою"</string>
-    <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Звук із пристрою, зокрема музика, виклики та сигнали дзвінка"</string>
+    <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"Звук із пристрою, зокрема музика, виклики й сигнали дзвінка"</string>
     <string name="screenrecord_mic_label" msgid="2111264835791332350">"Мікрофон"</string>
-    <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Звук із пристрою та мікрофона"</string>
+    <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"Звук із пристрою і мікрофона"</string>
     <string name="screenrecord_continue" msgid="4055347133700593164">"Почати"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"Запис екрана"</string>
     <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"Запис екрана та звуку"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Сканування обличчя"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Надіслати"</string>
     <string name="cancel" msgid="1089011503403416730">"Скасувати"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Логотип додатка"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Підтвердити"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Повторити спробу"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Натисніть, щоб скасувати автентифікацію"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Обличчя розпізнано. Натисніть значок розблокування."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Автентифіковано"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Скасувати автентифікацію"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Інші опції"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Ввести PIN-код"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Намалювати ключ"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Ввести пароль"</string>
@@ -362,12 +363,20 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Стандартний"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Середній"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Високий"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Надати доступ до мікрофона?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Надати доступ до камери пристрою?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Надати доступ до камери й мікрофона?"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Усі додатки та сервіси, яким дозволено користуватися вашим мікрофоном, отримають доступ."</string>
-    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Усі додатки та сервіси, яким дозволено користуватися вашою камерою, отримають доступ."</string>
-    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Усі додатки та сервіси, яким дозволено користуватися вашою камерою чи мікрофоном, отримають доступ."</string>
+    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Усі додатки й сервіси, яким дозволено користуватися вашим мікрофоном, отримають доступ."</string>
+    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Усі додатки й сервіси, яким дозволено користуватися вашою камерою, отримають доступ."</string>
+    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Усі додатки й сервіси, яким дозволено користуватися вашою камерою чи мікрофоном, отримають доступ."</string>
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Мікрофон заблоковано"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Камеру заблоковано"</string>
     <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"Мікрофон і камеру заблоковано"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Видалити"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Додати віджет"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Готово"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Додати віджети"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Отримуйте швидкий доступ до віджетів улюблених додатків, не розблоковуючи планшет."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Дозволити використовувати будь-який віджет на заблокованому екрані?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Відкрити налаштування"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Увімкнути робочі додатки?"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Цим пристроєм керують твої батьки. Вони можуть бачити та контролювати, якими додатками ти користуєшся, де перебуваєш і скільки часу проводиш за пристроєм."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Розблоковує довірчий агент"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Пристрій заблоковано. Забагато спроб автентифікації."</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Пристрій заблоковано\nПомилка автентифікації"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Налаштування звуку"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Автоматичні субтитри (медіа)"</string>
@@ -667,10 +676,10 @@
     <string name="notification_channel_summary_automatic_silenced" msgid="7403004439649872047">"&lt;b&gt;Статус&lt;/b&gt;: знижено до \"Без звуку\""</string>
     <string name="notification_channel_summary_automatic_promoted" msgid="1301710305149590426">"&lt;b&gt;Статус&lt;/b&gt;: пріоритет підвищено"</string>
     <string name="notification_channel_summary_automatic_demoted" msgid="1831303964660807700">"&lt;b&gt;Статус&lt;/b&gt;: пріоритет знижено"</string>
-    <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані"</string>
-    <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, показується у вигляді спливаючої підказки"</string>
-    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, показується навіть у режимі \"Не турбувати\""</string>
-    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"З’являється вгорі сповіщень про розмови та як зображення профілю на заблокованому екрані, відображається як спливаючий чат, перериває режим \"Не турбувати\""</string>
+    <string name="notification_channel_summary_priority_baseline" msgid="46674690072551234">"З’являється вгорі сповіщень про розмови і як зображення профілю на заблокованому екрані"</string>
+    <string name="notification_channel_summary_priority_bubble" msgid="1275413109619074576">"З’являється вгорі сповіщень про розмови і як зображення профілю на заблокованому екрані, показується у вигляді спливаючої підказки"</string>
+    <string name="notification_channel_summary_priority_dnd" msgid="6665395023264154361">"З’являється вгорі сповіщень про розмови і як зображення профілю на заблокованому екрані, показується навіть у режимі \"Не турбувати\""</string>
+    <string name="notification_channel_summary_priority_all" msgid="7151752959650048285">"З’являється вгорі сповіщень про розмови і як зображення профілю на заблокованому екрані, відображається як спливаючий чат, перериває режим \"Не турбувати\""</string>
     <string name="notification_priority_title" msgid="2079708866333537093">"Пріоритет"</string>
     <string name="no_shortcut" msgid="8257177117568230126">"<xliff:g id="APP_NAME">%1$s</xliff:g> не підтримує функції розмов"</string>
     <string name="notification_unblockable_desc" msgid="2073030886006190804">"Ці сповіщення не можна змінити."</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Розділити екран із поточним додатком праворуч"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Розділити екран із поточним додатком ліворуч"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Перейти з розділення екрана на весь екран"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Під час розділення екрана перемикатися на додаток праворуч або внизу"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Під час розділення екрана перемикатися на додаток ліворуч або вгорі"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Під час розділення екрана: замінити додаток іншим"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Метод введення"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Вибрати наступну мову"</string>
diff --git a/packages/SystemUI/res/values-uk/tiles_states_strings.xml b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
index fd3fb08..be779eb 100644
--- a/packages/SystemUI/res/values-uk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"Вимкнено"</item>
     <item msgid="5137565285664080143">"Увімкнено"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 69ab8df..fa4bd02 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"‏IT منتظم نے اسکرین شاٹس لینا مسدود کر دیا ہے"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"ترمیم کریں"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"اسکرین شاٹ میں ترمیم کریں"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"اشتراک کریں"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"اسکرین شاٹ کا اشتراک کریں"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"مزید کیپچر کریں"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"اسکرین شاٹ برخاست کریں"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"اسکیننگ چہرہ"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"بھیجیں"</string>
     <string name="cancel" msgid="1089011503403416730">"منسوخ کريں"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"ایپ لوگو"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"تصدیق کریں"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"دوبارہ کوشش کریں"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"تصدیق کو منسوخ کرنے کے لیے تھپتھپائیں"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"چہرے کی شناخت ہو گئی۔ جاری رکھنے کیلئے انلاک آئیکن دبائیں۔"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"تصدیق کردہ"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"تصدیق کو منسوخ کریں"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"مزید اختیارات"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"‏PIN استعمال کریں"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"پیٹرن کا استعمال کریں"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"پاس ورڈ استعمال کریں"</string>
@@ -267,7 +268,7 @@
     <string name="quick_settings_bluetooth_tile_subtitle" msgid="212752719010829550">"کسی آلے کو منسلک یا غیر منسلک کرنے کے لیے تھپتھپائیں"</string>
     <string name="pair_new_bluetooth_devices" msgid="4601767620843349645">"نئے آلے کا جوڑا بنائیں"</string>
     <string name="see_all_bluetooth_devices" msgid="1761596816620200433">"سبھی دیکھیں"</string>
-    <string name="turn_on_bluetooth" msgid="5681370462180289071">"استعمال کریں"</string>
+    <string name="turn_on_bluetooth" msgid="5681370462180289071">"بلوٹوتھ استعمال کریں"</string>
     <string name="quick_settings_bluetooth_device_connected" msgid="7884777006729260996">"منسلک ہے"</string>
     <string name="quick_settings_bluetooth_device_saved" msgid="7549938728928069477">"محفوظ ہے"</string>
     <string name="accessibility_quick_settings_bluetooth_device_tap_to_disconnect" msgid="415980329093277342">"غیر منسلک کریں"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"معیاری"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"متوسط"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"زیادہ"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"سماعت کے آلات"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"آلے کا مائیکروفون غیر مسدود کریں؟"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"آلے کا کیمرا غیر مسدود کریں؟"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"آلے کا کیمرا اور مائیکروفون غیر مسدود کریں؟"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"ہٹائیں"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"ویجیٹ شامل کریں"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"ہو گیا"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"ویجٹس شامل کریں"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"اپنے ٹیبلیٹ کو غیر مقفل کیے بغیر اپنے پسندیدہ ایپ ویجیٹس تک فوری رسائی حاصل کریں۔"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"مقفل اسکرین پر کسی ویجیٹ کی اجازت دیں؟"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"ترتیبات کھولیں"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"ورک ایپس کو غیر موقوف کریں؟"</string>
@@ -540,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"یہ آلہ آپ کے والدین کے زیر انتظام ہے۔ آپ کے والدین آپ کی استعمال والی ایپس، آپ کا مقام اور آپ کے اسکرین کے وقت جیسی معلومات کو دیکھ اور اس کا نظم کر سکتے ہیں۔"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"ٹرسٹ ایجنٹ نے غیر مقفل رکھا ہے"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"آلہ مقفل ہو گیا، تصدیق کی کافی زیادہ کوششیں کی گئیں"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"آلہ مقفل ہو گیا\nتصدیق ناکام ہو گئی"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>۔ <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"صوتی ترتیبات"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"خودکار طور پر میڈیا پر کیپشن لگائیں"</string>
@@ -612,7 +620,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"‏%s خاموش کریں"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"‏%s غیر خاموش کریں"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"<xliff:g id="LABEL">%s</xliff:g> پر چل رہی ہے"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"آڈیو چلتی رہے گی"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"آڈیو اس پر چلے گی"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"‏سسٹم UI ٹیونر"</string>
     <string name="status_bar" msgid="4357390266055077437">"اسٹیٹس بار"</string>
     <string name="demo_mode" msgid="263484519766901593">"‏سسٹم UI ڈیمو موڈ"</string>
@@ -765,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"موجودہ ایپ کے ساتھ دائیں جانب اسپلٹ اسکرین انٹر کریں"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"موجودہ ایپ کے ساتھ بائیں جانب اسپلٹ اسکرین انٹر کریں"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"اسپلٹ اسکرین سے پوری سکرین پر سوئچ کریں"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"اسپلٹ اسکرین کا استعمال کرتے ہوئے دائیں یا نیچے ایپ پر سوئچ کریں"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"اسپلٹ اسکرین کا استعمال کرتے ہوئے بائیں یا اوپر ایپ پر سوئچ کریں"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"اسپلٹ اسکرین کے دوران: ایک ایپ کو دوسرے سے تبدیل کریں"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"ان پٹ"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"اگلی زبان پر سوئچ کریں"</string>
diff --git a/packages/SystemUI/res/values-ur/tiles_states_strings.xml b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
index 4957e59..ebbc30e 100644
--- a/packages/SystemUI/res/values-ur/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"آف ہے"</item>
     <item msgid="5137565285664080143">"آن ہے"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"دستیاب نہیں ہے"</item>
+    <item msgid="3079622119444911877">"آف ہے"</item>
+    <item msgid="3028994095749238254">"آن ہے"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 1fab322..195b044 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Skrinshot olishni AT administratori taqiqlagan"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Tahrirlash"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Skrinshotni tahrirlash"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Ulashish"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Skrinshot yuborish"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Skrinshot sohasini kengaytirish"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Skrinshotni yopish"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Yuzni skanerlash"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Yuborish"</string>
     <string name="cancel" msgid="1089011503403416730">"Bekor qilish"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Ilova logotipi"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"OK"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Qayta urinish"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Tekshiruvni bekor qilish uchun bosing"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Yuz aniqlandi. Davom etish uchun ochish belgisini bosing."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Tasdiqlandi"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Autentifikatsiyani bekor qilish"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Boshqa parametrlar"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"PIN kod kiritish"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Grafik kalitdan foydalanish"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Paroldan foydalanish"</string>
@@ -362,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Standart"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Oʻrtacha"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Yuqori"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Eshitish qurilmalari"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Qurilma mikrofoni blokdan chiqarilsinmi?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Qurilma kamerasi blokdan chiqarilsinmi?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Qurilma kamerasi va mikrofoni blokdan chiqarilsinmi?"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Olib tashlash"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Vidjet kiritish"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Tayyor"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Vidjetlar qoʻshish"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Planshetingiz qulflangan boʻlsa ham sevimli ilova vidjetlariga tezkor kira olasiz"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Ekran qulfida istalgan vidjet chiqsinmi?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Sozlamalarni ochish"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Ishga oid ilovalar qaytarilsinmi?"</string>
@@ -540,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Bu – ota-onangiz tomonidan boshqariladigan qurilma. Ota-onangiz siz foydalangan ilovalar, joylashuvingiz va qurilmadan foydalanish vaqti kabi axborotlarni koʻrishi va boshqarishi mumkin."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"TrustAgent tomonidan ochilgan"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Qurilma qulflandi. Juda koʻp marta hisob tekshiruvi uchun urinildi"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Qurilma qulflandi\nHisob tekshiruvi amalga oshmadi"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Tovush sozlamalari"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Avtomatik taglavha yaratish"</string>
@@ -623,7 +631,7 @@
     <string name="wallet_title" msgid="5369767670735827105">"Wallet"</string>
     <string name="wallet_empty_state_label" msgid="7776761245237530394">"Telefonda tezroq va xavfsizroq xarid qilish uchun sozlang"</string>
     <string name="wallet_app_button_label" msgid="7123784239111190992">"Hammasi"</string>
-    <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Ochish uchun ustiga bosing"</string>
+    <string name="wallet_secondary_label_no_card" msgid="8488069304491125713">"Ochish uchun bosing"</string>
     <string name="wallet_secondary_label_updating" msgid="5726130686114928551">"Yangilanmoqda"</string>
     <string name="wallet_secondary_label_device_locked" msgid="5175862019125370506">"Foydalanish uchun qulfdan chiqarish"</string>
     <string name="wallet_error_generic" msgid="257704570182963611">"Bildirgilarni yuklashda xatolik yuz berdi, keyinroq qaytadan urining"</string>
@@ -765,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Oʻng tomondagi ajratilgan ekran rejimiga kirish"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Chap tomondagi ajratilgan ekran rejimiga kirish"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Ajratilgan ekran rejimidan butun ekranga almashtirish"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Ajratilgan ekranda oʻngdagi yoki pastdagi ilovaga almashish"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Ajratilgan ekranda chapdagi yoki yuqoridagi ilovaga almashish"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ajratilgan rejimda ilovalarni oʻzaro almashtirish"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Kiritish"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Keyingi tilga almashtirish"</string>
@@ -1240,7 +1246,7 @@
     <string name="home_quick_affordance_unavailable_configure_the_app" msgid="604424593994493281">"• Kamida bitta qurilma yoki qurilma paneli mavjud"</string>
     <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Qayd yozish yorligʻidan foydalanish uchun birlamchi qayd ilovasini tanlang"</string>
     <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Ilovani tanlang"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Bosib turish yorligʻi"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Yorliqni bosib turing"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Bekor qilish"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Ekranlarni hozir almashtirish"</string>
     <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Telefonni yoying"</string>
diff --git a/packages/SystemUI/res/values-uz/tiles_states_strings.xml b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
index 670c56c..2ae81123 100644
--- a/packages/SystemUI/res/values-uz/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"Oʻchiq"</item>
     <item msgid="5137565285664080143">"Yoniq"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"Ishlamayapti"</item>
+    <item msgid="3079622119444911877">"Oʻchiq"</item>
+    <item msgid="3028994095749238254">"Yoniq"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 3ddb4db..469430b 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"Quản trị viên CNTT chặn tính năng chụp ảnh màn hình"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"Chỉnh sửa"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"Chỉnh sửa ảnh chụp màn hình"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"Chia sẻ"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"Chia sẻ ảnh chụp màn hình"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"Chụp thêm"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"Đóng ảnh chụp màn hình"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Quét tìm khuôn mặt"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Gửi"</string>
     <string name="cancel" msgid="1089011503403416730">"Hủy"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Biểu trưng của ứng dụng"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Xác nhận"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Thử lại"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Nhấn để hủy quá trình xác thực"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Đã nhận diện khuôn mặt. Nhấn biểu tượng mở khoá để tiếp tục."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Đã xác thực"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Huỷ quy trình xác thực"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Tuỳ chọn khác"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Dùng mã PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Dùng hình mở khóa"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Dùng mật khẩu"</string>
@@ -362,11 +363,18 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Chuẩn"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Vừa"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Cao"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Thiết bị trợ thính"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Bỏ chặn micrô của thiết bị?"</string>
-    <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Bỏ chặn máy ảnh của thiết bị?"</string>
+    <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Bỏ chặn camera của thiết bị?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Bỏ chặn máy ảnh và micrô của thiết bị?"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Sau khi được bỏ chặn, mọi ứng dụng và dịch vụ có quyền sẽ có thể sử dụng micrô của bạn."</string>
-    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Sau khi được bỏ chặn, mọi ứng dụng và dịch vụ có quyền sẽ có thể sử dụng máy ảnh của bạn."</string>
+    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"Sau khi được bỏ chặn, mọi ứng dụng và dịch vụ có quyền sẽ có thể sử dụng micrô trên thiết bị của bạn."</string>
+    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"Sau khi được bỏ chặn, mọi ứng dụng và dịch vụ có quyền sẽ có thể sử dụng camera trên thiết bị của bạn."</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"Thao tác này sẽ bỏ chặn quyền truy cập cho mọi ứng dụng và dịch vụ được phép sử dụng máy ảnh hoặc micrô của bạn."</string>
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"Micrô bị chặn"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"Máy ảnh bị chặn"</string>
@@ -439,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Xoá"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Thêm tiện ích"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Xong"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Thêm tiện ích"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Truy cập nhanh vào các tiện ích ứng dụng bạn yêu thích mà không cần mở khoá máy tính bảng."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Cho phép mọi tiện ích trên màn hình khoá?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Mở phần Cài đặt"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Tiếp tục dùng ứng dụng công việc?"</string>
@@ -540,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Thiết bị này do cha mẹ bạn quản lý. Cha mẹ có thể có thể xem và quản lý những thông tin như ứng dụng bạn dùng, vị trí của bạn và thời gian bạn sử dụng thiết bị."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Luôn được TrustAgent mở khóa"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Thiết bị đã bị khoá do quá nhiều lần thử xác thực"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Thiết bị đã bị khoá\nKhông xác thực được"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Cài đặt âm thanh"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Tự động tạo phụ đề cho nội dung nghe nhìn"</string>
@@ -577,7 +585,7 @@
     <string name="stream_voice_call" msgid="7468348170702375660">"Gọi"</string>
     <string name="stream_system" msgid="7663148785370565134">"Hệ thống"</string>
     <string name="stream_ring" msgid="7550670036738697526">"Chuông"</string>
-    <string name="stream_music" msgid="2188224742361847580">"Phương tiện"</string>
+    <string name="stream_music" msgid="2188224742361847580">"Nội dung nghe nhìn"</string>
     <string name="stream_alarm" msgid="16058075093011694">"Báo thức"</string>
     <string name="stream_notification" msgid="7930294049046243939">"Thông báo"</string>
     <string name="stream_bluetooth_sco" msgid="6234562365528664331">"Bluetooth"</string>
@@ -588,8 +596,8 @@
     <string name="volume_ringer_status_silent" msgid="3691324657849880883">"Tắt tiếng"</string>
     <string name="media_device_cast" msgid="4786241789687569892">"Truyền"</string>
     <string name="stream_notification_unavailable" msgid="4313854556205836435">"Không hoạt động vì chuông bị tắt"</string>
-    <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Không làm được vì chế độ Không làm phiền đang bật"</string>
-    <string name="stream_media_unavailable" msgid="6823020894438959853">"Không làm được vì chế độ Không làm phiền đang bật"</string>
+    <string name="stream_alarm_unavailable" msgid="4059817189292197839">"Bị tắt vì đang bật chế độ Không làm phiền"</string>
+    <string name="stream_media_unavailable" msgid="6823020894438959853">"Bị tắt vì đang bật chế độ Không làm phiền"</string>
     <string name="volume_stream_content_description_unmute" msgid="7729576371406792977">"%1$s. Nhấn để bật tiếng."</string>
     <string name="volume_stream_content_description_vibrate" msgid="4858111994183089761">"%1$s. Nhấn để đặt chế độ rung. Bạn có thể tắt tiếng dịch vụ trợ năng."</string>
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s. Nhấn để tắt tiếng. Bạn có thể tắt tiếng dịch vụ trợ năng."</string>
@@ -612,7 +620,7 @@
     <string name="volume_panel_hint_mute" msgid="6962563028495243738">"tắt tiếng %s"</string>
     <string name="volume_panel_hint_unmute" msgid="7489063242934477382">"bật tiếng %s"</string>
     <string name="media_output_label_title" msgid="872824698593182505">"Đang phát <xliff:g id="LABEL">%s</xliff:g> trên"</string>
-    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Âm thanh sẽ phát ra"</string>
+    <string name="media_output_title_without_playing" msgid="3825663683169305013">"Âm thanh sẽ phát trên"</string>
     <string name="system_ui_tuner" msgid="1471348823289954729">"Bộ điều hướng giao diện người dùng hệ thống"</string>
     <string name="status_bar" msgid="4357390266055077437">"Thanh trạng thái"</string>
     <string name="demo_mode" msgid="263484519766901593">"Chế độ thử nghiệm giao diện người dùng hệ thống"</string>
@@ -765,10 +773,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"Vào chế độ chia đôi màn hình, ứng dụng hiện tại ở màn hình bên phải"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"Vào chế độ chia đôi màn hình, ứng dụng hiện tại ở màn hình bên trái"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"Chuyển từ chế độ chia đôi màn hình sang chế độ toàn màn hình"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Chuyển sang ứng dụng bên phải hoặc ở dưới khi đang chia đôi màn hình"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Chuyển sang ứng dụng bên trái hoặc ở trên khi đang chia đôi màn hình"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Trong chế độ chia đôi màn hình: thay một ứng dụng bằng ứng dụng khác"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"Đầu vào"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"Chuyển sang ngôn ngữ tiếp theo"</string>
@@ -1240,7 +1246,7 @@
     <string name="home_quick_affordance_unavailable_configure_the_app" msgid="604424593994493281">"• Ít nhất phải có một thiết bị hoặc bảng điều khiển thiết bị"</string>
     <string name="notes_app_quick_affordance_unavailable_explanation" msgid="4796955161600178530">"Chọn một ứng dụng ghi chú mặc định để dùng lối tắt ghi chú"</string>
     <string name="keyguard_affordance_enablement_dialog_notes_app_action" msgid="6821710209675089470">"Chọn ứng dụng"</string>
-    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Chạm và giữ phím tắt"</string>
+    <string name="keyguard_affordance_press_too_short" msgid="8145437175134998864">"Chạm và giữ lối tắt"</string>
     <string name="rear_display_bottom_sheet_cancel" msgid="3461468855493357248">"Huỷ"</string>
     <string name="rear_display_bottom_sheet_confirm" msgid="1507591562761552899">"Chuyển đổi màn hình ngay"</string>
     <string name="rear_display_folded_bottom_sheet_title" msgid="3930008746560711990">"Mở điện thoại"</string>
diff --git a/packages/SystemUI/res/values-vi/tiles_states_strings.xml b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
index 4df2d91..d9d8af1 100644
--- a/packages/SystemUI/res/values-vi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"Đang tắt"</item>
     <item msgid="5137565285664080143">"Đang bật"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"Không có"</item>
+    <item msgid="3079622119444911877">"Đang tắt"</item>
+    <item msgid="3028994095749238254">"Đang bật"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index b98643e..6765d1e 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"您的 IT 管理员已禁止截取屏幕截图"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"编辑"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"编辑屏幕截图"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"分享"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"分享屏幕截图"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"截取更多内容"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"关闭屏幕截图"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"正在扫描面孔"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"发送"</string>
     <string name="cancel" msgid="1089011503403416730">"取消"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"应用徽标"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"确认"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"重试"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"点按即可取消身份验证"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"识别出面孔。按下解锁图标即可继续。"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"已经过身份验证"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"取消身份验证"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"更多选项"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"使用 PIN 码"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"使用图案"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"使用密码"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"标准"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"中"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"高"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解锁设备麦克风吗?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要解锁设备摄像头吗?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"要解锁设备摄像头和麦克风吗?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"移除"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"添加微件"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"完成"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"添加微件"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"无需解锁平板电脑,即可快速使用您喜爱的应用微件。"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"允许在锁屏状态下显示任何微件?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"打开设置"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"是否为工作应用解除暂停状态?"</string>
@@ -491,7 +502,7 @@
     <string name="notification_section_header_gentle" msgid="6804099527336337197">"静音"</string>
     <string name="notification_section_header_alerting" msgid="5581175033680477651">"通知"</string>
     <string name="notification_section_header_conversations" msgid="821834744538345661">"对话"</string>
-    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"清除所有无声通知"</string>
+    <string name="accessibility_notification_section_header_gentle_clear_all" msgid="6490207897764933919">"清除所有静音通知"</string>
     <string name="dnd_suppressing_shade_text" msgid="5588252250634464042">"勿扰模式暂停的通知"</string>
     <string name="media_projection_action_text" msgid="3634906766918186440">"立即开始"</string>
     <string name="empty_shade_text" msgid="8935967157319717412">"没有通知"</string>
@@ -540,10 +551,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"此设备由您的家长管理。您的家长可以查看和管理相关信息,例如您使用的应用、您的位置信息和设备使用时间。"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"由 TrustAgent 保持解锁状态"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"尝试验证身份的次数过多,设备已锁定"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"设备已锁定\n未能验证身份"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>(<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>)"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"声音设置"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"自动生成媒体字幕"</string>
@@ -595,7 +604,7 @@
     <string name="volume_stream_content_description_mute" msgid="4079046784917920984">"%1$s。点按即可设为静音,但可能会同时将无障碍服务设为静音。"</string>
     <string name="volume_stream_content_description_vibrate_a11y" msgid="2742330052979397471">"%1$s。点按即可设为振动。"</string>
     <string name="volume_stream_content_description_mute_a11y" msgid="5743548478357238156">"%1$s。点按即可设为静音。"</string>
-    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"噪声控制"</string>
+    <string name="volume_panel_noise_control_title" msgid="7413949943872304474">"降噪"</string>
     <string name="volume_panel_spatial_audio_title" msgid="3367048857932040660">"空间音频"</string>
     <string name="volume_panel_spatial_audio_off" msgid="4177490084606772989">"关闭"</string>
     <string name="volume_panel_spatial_audio_fixed" msgid="3136080137827746046">"固定"</string>
@@ -765,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"进入分屏模式,当前应用显示于右侧"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"进入分屏模式,当前应用显示于左侧"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"从分屏模式切换为全屏"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分屏模式时,切换到右侧或下方的应用"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分屏模式时,切换到左侧或上方的应用"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"在分屏期间:将一个应用替换为另一个应用"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"输入"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"切换到下一种语言"</string>
@@ -1166,7 +1173,7 @@
     <string name="mobile_data_connection_active" msgid="944490013299018227">"已连接"</string>
     <string name="mobile_data_temp_connection_active" msgid="4590222725908806824">"已暂时连接"</string>
     <string name="mobile_data_poor_connection" msgid="819617772268371434">"连接状况不佳"</string>
-    <string name="mobile_data_off_summary" msgid="3663995422004150567">"系统将不会自动连接到移动数据网络"</string>
+    <string name="mobile_data_off_summary" msgid="3663995422004150567">"不会自动连接到移动数据网络"</string>
     <string name="mobile_data_no_connection" msgid="1713872434869947377">"无网络连接"</string>
     <string name="non_carrier_network_unavailable" msgid="770049357024492372">"没有其他可用网络"</string>
     <string name="all_network_unavailable" msgid="4112774339909373349">"没有可用网络"</string>
@@ -1261,7 +1268,7 @@
     <string name="call_from_work_profile_action" msgid="2937701298133010724">"切换到工作资料"</string>
     <string name="install_dialer_on_work_profile_action" msgid="2014659711597862506">"安装工作电话应用"</string>
     <string name="call_from_work_profile_close" msgid="5830072964434474143">"取消"</string>
-    <string name="lock_screen_settings" msgid="6152703934761402399">"自定义锁屏状态"</string>
+    <string name="lock_screen_settings" msgid="6152703934761402399">"自定义锁屏"</string>
     <string name="keyguard_unlock_to_customize_ls" msgid="2068542308086253819">"解锁以自定义锁定屏幕"</string>
     <string name="wifi_unavailable_dream_overlay_content_description" msgid="2024166212194640100">"没有 WLAN 连接"</string>
     <string name="camera_blocked_dream_overlay_content_description" msgid="4074759493559418130">"已禁用摄像头"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
index 08a1551..a9a377a 100644
--- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"已关闭"</item>
     <item msgid="5137565285664080143">"已开启"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 9080ff5..d4891d5 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"你的 IT 管理員已禁止擷取螢幕截圖"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"編輯"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"編輯螢幕截圖"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"分享"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"分享螢幕截圖"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"擷取更大範圍的螢幕內容"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"關閉螢幕截圖"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"掃瞄緊面孔"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"傳送"</string>
     <string name="cancel" msgid="1089011503403416730">"取消"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"應用程式標誌"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"確認"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"請再試一次"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"輕按即可取消驗證"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"已識別面孔。按解鎖圖示即可繼續。"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"驗證咗"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"取消驗證"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"更多選項"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"使用 PIN"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"使用圖案"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"使用密碼"</string>
@@ -362,6 +363,14 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"標準"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"中"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"高"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解除封鎖裝置麥克風嗎?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要解除封鎖裝置相機嗎?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"要解除封鎖裝置相機和麥克風嗎?"</string>
@@ -439,6 +448,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"移除"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"新增小工具"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"完成"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"新增小工具"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"無需解鎖平板電腦,就能快速使用最愛的應用程式小工具。"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"要允許在上鎖畫面上顯示任何小工具嗎?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"開啟設定"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"要取消暫停工作應用程式嗎?"</string>
@@ -540,7 +551,7 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"此裝置由你的家長管理。家長可以查看及管理裝置上的資料,例如你使用的應用程式、位置和裝置使用時間。"</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"由信任的代理保持解鎖狀態"</string>
-    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"驗證錯誤次數過多,裝置已鎖定"</string>
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"嘗試驗證次數過多,裝置已鎖定"</string>
     <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"裝置已鎖定\n驗證失敗"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"音效設定"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"進入分割螢幕模式,並將目前的應用程式顯示在右側"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"進入分割螢幕模式,並將目前的應用程式顯示在左側"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"將分割螢幕切換為全螢幕"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分割螢幕時,切換至右邊或下方的應用程式"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分割螢幕時,切換至左邊或上方的應用程式"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"使用分割螢幕期間:更換應用程式"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"輸入"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"切換至下一個語言"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
index e29d230..f0ccd9e 100644
--- a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"關閉"</item>
     <item msgid="5137565285664080143">"開啟"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 9c0c376..bc59988 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -86,8 +86,7 @@
     <string name="screenshot_blocked_by_admin" msgid="5486757604822795797">"你的 IT 管理員已禁止擷取螢幕畫面"</string>
     <string name="screenshot_edit_label" msgid="8754981973544133050">"編輯"</string>
     <string name="screenshot_edit_description" msgid="3333092254706788906">"編輯螢幕截圖"</string>
-    <!-- no translation found for screenshot_share_label (1653061117238861559) -->
-    <skip />
+    <string name="screenshot_share_label" msgid="1653061117238861559">"分享"</string>
     <string name="screenshot_share_description" msgid="2861628935812656612">"分享螢幕截圖"</string>
     <string name="screenshot_scroll_label" msgid="2930198809899329367">"擴大螢幕截圖範圍"</string>
     <string name="screenshot_dismiss_description" msgid="4702341245899508786">"關閉螢幕截圖"</string>
@@ -105,19 +104,19 @@
     <string name="screenrecord_title" msgid="4257171601439507792">"螢幕錄影器"</string>
     <string name="screenrecord_background_processing_label" msgid="7244617554884238898">"處理螢幕錄影內容"</string>
     <string name="screenrecord_channel_description" msgid="4147077128486138351">"持續顯示螢幕畫面錄製工作階段通知"</string>
-    <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"要開始錄製嗎?"</string>
-    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"當你錄製內容時,Android 可存取畫面上顯示的任何資訊或裝置播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string>
-    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"當你錄製應用程式內容時,Android 可存取應用程式中顯示的任何資訊或播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string>
+    <string name="screenrecord_permission_dialog_title" msgid="303380743267672953">"要開始錄影嗎?"</string>
+    <string name="screenrecord_permission_dialog_warning_entire_screen" msgid="4152602778470789965">"你在錄影時,Android 可存取畫面上的所有資訊或裝置播放的所有內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音等內容。"</string>
+    <string name="screenrecord_permission_dialog_warning_single_app" msgid="6818309727772146138">"當你錄製應用程式畫面時,Android 可存取應用程式中顯示或播放的所有內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音等內容。"</string>
     <string name="screenrecord_permission_dialog_continue" msgid="5811122652514424967">"開始錄影"</string>
     <string name="screenrecord_audio_label" msgid="6183558856175159629">"錄音"</string>
     <string name="screenrecord_device_audio_label" msgid="9016927171280567791">"裝置音訊"</string>
-    <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"裝置所播放的音效,例如音樂、通話和鈴聲等等"</string>
+    <string name="screenrecord_device_audio_description" msgid="4922694220572186193">"來自裝置的音訊,例如音樂、通話和鈴聲等等"</string>
     <string name="screenrecord_mic_label" msgid="2111264835791332350">"麥克風"</string>
     <string name="screenrecord_device_audio_and_mic_label" msgid="1831323771978646841">"裝置音訊和麥克風"</string>
     <string name="screenrecord_continue" msgid="4055347133700593164">"開始"</string>
     <string name="screenrecord_ongoing_screen_only" msgid="4459670242451527727">"正在錄製螢幕畫面"</string>
     <string name="screenrecord_ongoing_screen_and_audio" msgid="5351133763125180920">"錄製螢幕畫面和音訊"</string>
-    <string name="screenrecord_taps_label" msgid="1595690528298857649">"顯示輕觸螢幕的位置"</string>
+    <string name="screenrecord_taps_label" msgid="1595690528298857649">"顯示在螢幕上點按的位置"</string>
     <string name="screenrecord_stop_label" msgid="72699670052087989">"停止"</string>
     <string name="screenrecord_share_label" msgid="5025590804030086930">"分享"</string>
     <string name="screenrecord_save_title" msgid="1886652605520893850">"已儲存螢幕錄影檔"</string>
@@ -152,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"掃描臉孔"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"傳送"</string>
     <string name="cancel" msgid="1089011503403416730">"取消"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"應用程式標誌"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"確認"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"再試一次"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"輕觸即可取消驗證"</string>
@@ -166,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"臉孔辨識完成,按下「解鎖」圖示即可繼續操作。"</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"已通過驗證"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"取消驗證"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"更多選項"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"使用 PIN 碼"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"使用解鎖圖案"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"使用密碼"</string>
@@ -362,12 +363,20 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"標準"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"中"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"高"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要將裝置麥克風解除封鎖嗎?"</string>
-    <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要將裝置相機解除封鎖嗎?"</string>
+    <!-- no translation found for quick_settings_hearing_devices_label (7277170419679404129) -->
+    <skip />
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
+    <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解除封鎖裝置麥克風嗎?"</string>
+    <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要解除封鎖裝置相機嗎?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"要將裝置的相機和麥克風解除封鎖嗎?"</string>
-    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"這麼做可允許所有應用程式和服務使用麥克風。"</string>
-    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"這麼做可允許所有應用程式和服務使用相機。"</string>
-    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"這麼做可允許所有應用程式和服務使用相機或麥克風。"</string>
+    <string name="sensor_privacy_start_use_mic_dialog_content" msgid="1624701280680913717">"執行後,具備麥克風存取權的所有應用程式和服務,都將可使用麥克風。"</string>
+    <string name="sensor_privacy_start_use_camera_dialog_content" msgid="4704948062372435963">"執行後,具備相機存取權的所有應用程式和服務,都將可使用相機。"</string>
+    <string name="sensor_privacy_start_use_mic_camera_dialog_content" msgid="3577642558418404919">"執行後,具備相機或麥克風存取權的所有應用程式和服務,都將可使用這兩項功能。"</string>
     <string name="sensor_privacy_start_use_mic_blocked_dialog_title" msgid="2640140287496469689">"無法使用麥克風"</string>
     <string name="sensor_privacy_start_use_camera_blocked_dialog_title" msgid="7398084286822440384">"無法使用攝影機"</string>
     <string name="sensor_privacy_start_use_mic_camera_blocked_dialog_title" msgid="195236134743281973">"無法使用麥克風和相機"</string>
@@ -439,13 +448,15 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"移除"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"新增小工具"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"完成"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"新增小工具"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"快速使用喜愛的應用程式小工具,不必解鎖平板電腦。"</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"要允許在螢幕鎖定畫面上顯示任何小工具嗎?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"開啟設定"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"要解除工作應用程式的暫停狀態嗎?"</string>
     <string name="work_mode_turn_on" msgid="907813741770247267">"取消暫停"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="5330448341251092660">"切換使用者"</string>
     <string name="accessibility_multi_user_list_switcher" msgid="8574105376229857407">"下拉式選單"</string>
-    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會遭到刪除。"</string>
+    <string name="guest_exit_guest_dialog_message" msgid="8183450985628495709">"這個工作階段中的所有應用程式和資料都會刪除。"</string>
     <string name="guest_wipe_session_title" msgid="7147965814683990944">"訪客你好,歡迎回來!"</string>
     <string name="guest_wipe_session_message" msgid="3393823610257065457">"你要繼續這個工作階段嗎?"</string>
     <string name="guest_wipe_session_wipe" msgid="8056836584445473309">"重新開始"</string>
@@ -471,8 +482,8 @@
     <string name="media_projection_entry_app_permission_dialog_continue" msgid="295463518195075840">"開始"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」已停用此選項"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="8860150223172993547">"要開始投放嗎?"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"當你投放內容時,Android 可存取畫面上顯示的任何資訊或裝置播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string>
-    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"當你投放應用程式內容時,Android 可存取應用程式中顯示的任何資訊或播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_entire_screen" msgid="1986212276016817231">"投放時,Android 可存取畫面上顯示的任何資訊或裝置播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音等內容。"</string>
+    <string name="media_projection_entry_cast_permission_dialog_warning_single_app" msgid="9900961380294292">"當你投放應用程式時,Android 可存取應用程式顯示的任何資訊或播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音等內容。"</string>
     <string name="media_projection_entry_cast_permission_dialog_continue" msgid="7209890669948870042">"開始投放"</string>
     <string name="media_projection_entry_generic_permission_dialog_title" msgid="4519802931547483628">"要開始分享嗎?"</string>
     <string name="media_projection_entry_generic_permission_dialog_warning_entire_screen" msgid="5407906851409410209">"當你分享、錄製或投放內容時,Android 將可存取畫面上顯示的任何資訊或裝置播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string>
@@ -763,10 +774,8 @@
     <string name="system_multitasking_rhs" msgid="2454557648974553729">"進入分割畫面模式,並將目前的應用程式顯示於右側"</string>
     <string name="system_multitasking_lhs" msgid="3516599774920979402">"進入分割畫面模式,並將目前的應用程式顯示於左側"</string>
     <string name="system_multitasking_full_screen" msgid="336048080383640562">"從分割畫面切換到完整畫面"</string>
-    <!-- no translation found for system_multitasking_splitscreen_focus_rhs (3838578650313318508) -->
-    <skip />
-    <!-- no translation found for system_multitasking_splitscreen_focus_lhs (3164261844398662518) -->
-    <skip />
+    <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分割畫面時,切換到右邊或上方的應用程式"</string>
+    <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分割畫面時,切換到左邊或上方的應用程式"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"使用分割畫面期間:更換應用程式"</string>
     <string name="keyboard_shortcut_group_input" msgid="6888282716546625610">"輸入"</string>
     <string name="input_switch_input_language_next" msgid="3782155659868227855">"切換到下一個語言"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
index 85e1796..2c474f6 100644
--- a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
@@ -186,4 +186,7 @@
     <item msgid="2478289035899842865">"關閉"</item>
     <item msgid="5137565285664080143">"開啟"</item>
   </string-array>
+    <!-- no translation found for tile_states_hearing_devices:0 (1235334096484287173) -->
+    <!-- no translation found for tile_states_hearing_devices:1 (3079622119444911877) -->
+    <!-- no translation found for tile_states_hearing_devices:2 (3028994095749238254) -->
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 8b03cba..780fe94 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -151,6 +151,7 @@
     <string name="accessibility_scanning_face" msgid="3093828357921541387">"Ukuskena ubuso"</string>
     <string name="accessibility_send_smart_reply" msgid="8885032190442015141">"Thumela"</string>
     <string name="cancel" msgid="1089011503403416730">"Khansela"</string>
+    <string name="biometric_dialog_logo" msgid="7681107853070774595">"Ilogo ye-app"</string>
     <string name="biometric_dialog_confirm" msgid="2005978443007344895">"Qinisekisa"</string>
     <string name="biometric_dialog_try_again" msgid="8575345628117768844">"Zama futhi"</string>
     <string name="biometric_dialog_empty_space_description" msgid="3330555462071453396">"Thepha ukuze ukhansele ukufakazela ubuqiniso"</string>
@@ -165,6 +166,7 @@
     <string name="biometric_dialog_tap_confirm_with_face_alt_3" msgid="2192670471930606539">"Ubuso buyaziwa. Cindezela isithonjana sokuvula ukuze uqhubeke."</string>
     <string name="biometric_dialog_authenticated" msgid="7337147327545272484">"Kugunyaziwe"</string>
     <string name="biometric_dialog_cancel_authentication" msgid="981316588773442637">"Khansela Ukuqinisekisa"</string>
+    <string name="biometric_dialog_content_view_more_options_button" msgid="2663810393874865475">"Okukhethwayo Okwengeziwe"</string>
     <string name="biometric_dialog_use_pin" msgid="8385294115283000709">"Sebenzisa iphinikhodi"</string>
     <string name="biometric_dialog_use_pattern" msgid="2315593393167211194">"Sebenzisa iphethini"</string>
     <string name="biometric_dialog_use_password" msgid="3445033859393474779">"Sebenzisa iphasiwedi"</string>
@@ -361,6 +363,13 @@
     <string name="quick_settings_contrast_standard" msgid="2538227821968061832">"Okujwayelekile"</string>
     <string name="quick_settings_contrast_medium" msgid="5158352575583902566">"Okuphakathi"</string>
     <string name="quick_settings_contrast_high" msgid="656049259587494499">"Phezulu"</string>
+    <string name="quick_settings_hearing_devices_label" msgid="7277170419679404129">"Izinsizakuzwa"</string>
+    <!-- no translation found for quick_settings_hearing_devices_dialog_title (9004774017688484981) -->
+    <skip />
+    <!-- no translation found for quick_settings_pair_hearing_devices (5987105102207447322) -->
+    <skip />
+    <!-- no translation found for accessibility_hearing_device_pair_new_device (8440082580186130090) -->
+    <skip />
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vulela imakrofoni yedivayisi?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vulela ikhamera yedivayisi?"</string>
     <string name="sensor_privacy_start_use_mic_camera_dialog_title" msgid="4316471859905020023">"Vulela ikhamera yedivayisi nemakrofoni?"</string>
@@ -438,6 +447,8 @@
     <string name="button_to_remove_widget" msgid="3948204829181214098">"Susa"</string>
     <string name="hub_mode_add_widget_button_text" msgid="4831464661209971729">"Engeza iwijethi"</string>
     <string name="hub_mode_editing_exit_button_text" msgid="3704686734192264771">"Kwenziwe"</string>
+    <string name="label_for_button_in_empty_state_cta" msgid="7314975555382055823">"Faka iwijethi"</string>
+    <string name="title_for_empty_state_cta" msgid="6161654421223450530">"Thola ukufinyelela okusheshayo kumawijethi e-app akho owathandayo ngaphandle kokuvula ithebhulethi yakho."</string>
     <string name="dialog_title_to_allow_any_widget" msgid="1004820948962675644">"Vumela noma iyiphi iwijethi ekukhiyeni isikrini?"</string>
     <string name="button_text_to_open_settings" msgid="1987729256950941628">"Vula amasethingi"</string>
     <string name="work_mode_off_title" msgid="5794818421357835873">"Susa ukumisa ama-app omsebenzi?"</string>
@@ -539,10 +550,8 @@
     <string name="monitoring_description_parental_controls" msgid="8184693528917051626">"Le divayisi iphethwe ngumzali wakho. Umzali wakho angabona futhi aphathe ulwazi olunjengezinhlelo zokusebenza ozisebenzisayo, indawo yakho, kanye nesikhathi sesikrini."</string>
     <string name="legacy_vpn_name" msgid="4174223520162559145">"I-VPN"</string>
     <string name="keyguard_indication_trust_unlocked" msgid="7395154975733744547">"Igcinwa ivuliwe ngo-TrustAgent"</string>
-    <!-- no translation found for kg_prompt_after_adaptive_auth_lock (2587481497846342760) -->
-    <skip />
-    <!-- no translation found for keyguard_indication_after_adaptive_auth_lock (2323400645470712787) -->
-    <skip />
+    <string name="kg_prompt_after_adaptive_auth_lock" msgid="2587481497846342760">"Idivayisi ibikhiyiwe, imizamo eminingi kakhulu yokufakazela ubuqiniso"</string>
+    <string name="keyguard_indication_after_adaptive_auth_lock" msgid="2323400645470712787">"Idivayisi ikhiyiwe\nUkufakazela ubuqiniso kwehlulekile"</string>
     <string name="zen_mode_and_condition" msgid="5043165189511223718">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
     <string name="accessibility_volume_settings" msgid="1458961116951564784">"Izilungiselelo zomsindo"</string>
     <string name="volume_odi_captions_tip" msgid="8825655463280990941">"Yenza amagama-ngcazo ngokuzenzakalela emidiya"</string>
diff --git a/packages/SystemUI/res/values-zu/tiles_states_strings.xml b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
index 5c5a67c..a795ee8 100644
--- a/packages/SystemUI/res/values-zu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
@@ -186,4 +186,9 @@
     <item msgid="2478289035899842865">"Valiwe"</item>
     <item msgid="5137565285664080143">"Vuliwe"</item>
   </string-array>
+  <string-array name="tile_states_hearing_devices">
+    <item msgid="1235334096484287173">"Ayitholakali"</item>
+    <item msgid="3079622119444911877">"Kuvaliwe"</item>
+    <item msgid="3028994095749238254">"Kuvuliwe"</item>
+  </string-array>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index d2efccd..b0b5482 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -164,8 +164,9 @@
     so the width of the icon should be 13.0sp * (12.0 / 20.0) -->
     <dimen name="status_bar_battery_icon_width">7.8sp</dimen>
 
-    <dimen name="status_bar_battery_unified_icon_width">24sp</dimen>
-    <dimen name="status_bar_battery_unified_icon_height">14sp</dimen>
+    <!-- Original canvas is 24x14. These dimens reflect that ratio, with 12sp height instead  -->
+    <dimen name="status_bar_battery_unified_icon_width">20.6sp</dimen>
+    <dimen name="status_bar_battery_unified_icon_height">12sp</dimen>
 
     <!-- The battery icon is 13sp tall, but the other system icons are 15sp tall (see
          @*android:dimen/status_bar_system_icon_size) with some top and bottom padding embedded in
@@ -977,6 +978,7 @@
     <dimen name="assist_disclosure_shadow_thickness">1.5dp</dimen>
 
     <!-- Keyboard shortcuts helper -->
+    <dimen name="ksh_container_horizontal_margin">32dp</dimen>
     <dimen name="ksh_layout_width">@dimen/match_parent</dimen>
     <dimen name="ksh_item_text_size">14sp</dimen>
     <dimen name="ksh_item_padding">0dp</dimen>
@@ -984,6 +986,11 @@
     <dimen name="ksh_icon_scaled_size">18dp</dimen>
     <dimen name="ksh_key_view_padding_vertical">4dp</dimen>
     <dimen name="ksh_key_view_padding_horizontal">12dp</dimen>
+    <dimen name="ksh_button_corner_radius">12dp</dimen>
+    <dimen name="ksh_dialog_top_corner_radius">28dp</dimen>
+    <dimen name="ksh_search_box_corner_radius">100dp</dimen>
+    <dimen name="ksh_app_item_minimum_height">64dp</dimen>
+    <dimen name="ksh_category_separator_margin">16dp</dimen>
 
     <!-- The size of corner radius of the arrow in the onboarding toast. -->
     <dimen name="recents_onboarding_toast_arrow_corner_radius">2dp</dimen>
@@ -1084,7 +1091,7 @@
     <dimen name="remote_input_history_extra_height">60dp</dimen>
 
     <!-- Biometric Dialog values -->
-    <dimen name="biometric_dialog_face_icon_size">64dp</dimen>
+    <dimen name="biometric_dialog_face_icon_size">54dp</dimen>
     <dimen name="biometric_dialog_fingerprint_icon_width">80dp</dimen>
     <dimen name="biometric_dialog_fingerprint_icon_height">80dp</dimen>
     <dimen name="biometric_dialog_button_negative_max_width">160dp</dimen>
@@ -1102,6 +1109,22 @@
     <dimen name="biometric_dialog_width">240dp</dimen>
     <dimen name="biometric_dialog_height">240dp</dimen>
 
+    <!-- Dimensions for biometric prompt panel padding -->
+    <dimen name="biometric_prompt_small_horizontal_guideline_padding">344dp</dimen>
+    <dimen name="biometric_prompt_udfps_horizontal_guideline_padding">114dp</dimen>
+    <dimen name="biometric_prompt_udfps_mid_guideline_padding">409dp</dimen>
+    <dimen name="biometric_prompt_medium_horizontal_guideline_padding">640dp</dimen>
+    <dimen name="biometric_prompt_medium_mid_guideline_padding">330dp</dimen>
+
+    <!-- Dimensions for biometric prompt icon padding -->
+    <dimen name="biometric_prompt_portrait_small_bottom_padding">60dp</dimen>
+    <dimen name="biometric_prompt_portrait_medium_bottom_padding">160dp</dimen>
+    <dimen name="biometric_prompt_portrait_large_screen_bottom_padding">176dp</dimen>
+    <dimen name="biometric_prompt_landscape_small_bottom_padding">192dp</dimen>
+    <dimen name="biometric_prompt_landscape_small_horizontal_padding">145dp</dimen>
+    <dimen name="biometric_prompt_landscape_medium_bottom_padding">148dp</dimen>
+    <dimen name="biometric_prompt_landscape_medium_horizontal_padding">125dp</dimen>
+
     <!-- Dimensions for biometric prompt custom content view. -->
     <dimen name="biometric_prompt_logo_size">32dp</dimen>
     <dimen name="biometric_prompt_content_corner_radius">28dp</dimen>
@@ -1866,6 +1889,10 @@
         .2
     </item>
 
+    <item name="dream_overlay_bouncer_min_region_screen_percentage" format="float" type="dimen">
+        .05
+    </item>
+
     <!-- The padding applied to the dream overlay container -->
     <dimen name="dream_overlay_container_padding_start">0dp</dimen>
     <dimen name="dream_overlay_container_padding_end">0dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index b0d98e7..44cbdbc 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -899,8 +899,15 @@
     <!-- QuickSettings: Contrast tile description: high [CHAR LIMIT=NONE] -->
     <string name="quick_settings_contrast_high">High</string>
 
+    <!-- Hearing devices -->
     <!-- QuickSettings: Hearing devices [CHAR LIMIT=NONE] -->
     <string name="quick_settings_hearing_devices_label">Hearing devices</string>
+    <!-- QuickSettings: Quick Settings Hearing devices dialog title [CHAR LIMIT=30] -->
+    <string name="quick_settings_hearing_devices_dialog_title">Hearing devices</string>
+    <!-- QuickSettings: Hearing devices dialog pair new device [CHAR LIMIT=NONE]-->
+    <string name="quick_settings_pair_hearing_devices">Pair new device</string>
+    <!-- QuickSettings: Content description of the hearing devices dialog pair new device [CHAR LIMIT=NONE] -->
+    <string name="accessibility_hearing_device_pair_new_device">Click to pair new device</string>
 
     <!--- Title of dialog triggered if the microphone is disabled but an app tried to access it. [CHAR LIMIT=150] -->
     <string name="sensor_privacy_start_use_mic_dialog_title">Unblock device microphone?</string>
@@ -1964,7 +1971,7 @@
     <!-- Content description for the clear search button in shortcut search list. [CHAR LIMIT=NONE] -->
     <string name="keyboard_shortcut_clear_text">Clear search query</string>
     <!-- The title for keyboard shortcut search list [CHAR LIMIT=25] -->
-    <string name="keyboard_shortcut_search_list_title">Shortcuts</string>
+    <string name="keyboard_shortcut_search_list_title">Keyboard Shortcuts</string>
     <!-- The hint for keyboard shortcut search list [CHAR LIMIT=25] -->
     <string name="keyboard_shortcut_search_list_hint">Search shortcuts</string>
     <!-- The description for no shortcuts results [CHAR LIMIT=25] -->
@@ -2016,12 +2023,12 @@
     <!-- User visible title for the keyboard shortcut that pulls up Notes app for quick memo. [CHAR LIMIT=70] -->
     <string name="group_system_quick_memo">Take a note</string>
 
-    <!-- User visible title for the system multitasking keyboard shortcuts list. [CHAR LIMIT=70] -->
-    <string name="keyboard_shortcut_group_system_multitasking">System multitasking</string>
-    <!-- User visible title for the keyboard shortcut that enters split screen with current app to RHS [CHAR LIMIT=70] -->
-    <string name="system_multitasking_rhs">Enter split screen with current app to RHS</string>
-    <!-- User visible title for the keyboard shortcut that enters split screen with current app to LHS [CHAR LIMIT=70] -->
-    <string name="system_multitasking_lhs">Enter split screen with current app to LHS</string>
+    <!-- User visible title for the multitasking keyboard shortcuts list. [CHAR LIMIT=70] -->
+    <string name="keyboard_shortcut_group_system_multitasking">Multitasking</string>
+    <!-- User visible title for the keyboard shortcut that enters split screen with current app on the right [CHAR LIMIT=70] -->
+    <string name="system_multitasking_rhs">Use split screen with current app on the right</string>
+    <!-- User visible title for the keyboard shortcut that enters split screen with current app on the left [CHAR LIMIT=70] -->
+    <string name="system_multitasking_lhs">Use split screen with current app on the left</string>
     <!-- User visible title for the keyboard shortcut that switches from split screen to full screen [CHAR LIMIT=70] -->
     <string name="system_multitasking_full_screen">Switch from split screen to full screen</string>
     <!-- User visible title for the keyboard shortcut that switches to app on right or below while using split screen [CHAR LIMIT=70] -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 6462d02..9da4f79 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -224,6 +224,7 @@
     <style name="TextAppearance.AuthCredential.ContentViewListItem" parent="TextAppearance.Material3.BodySmall">
         <item name="android:textColor">?androidprv:attr/materialColorOnSurfaceVariant</item>
         <item name="android:paddingTop">@dimen/biometric_prompt_content_list_item_padding_top</item>
+        <item name="android:breakStrategy">high_quality</item>
     </style>
 
     <style name="TextAppearance.AuthCredential.Indicator" parent="TextAppearance.Material3.BodyMedium">
@@ -365,6 +366,21 @@
         <item name="android:layout_height">wrap_content</item>
     </style>
 
+    <style name="KeyboardShortcutHelper" parent="@android:style/Theme.DeviceDefault.Settings">
+        <!-- Needed to be able to use BottomSheetDragHandleView -->
+        <item name="android:windowActionBar">false</item>
+        <item name="bottomSheetDragHandleStyle">@style/KeyboardShortcutHelper.BottomSheet.DragHandle</item>
+    </style>
+
+    <style name="KeyboardShortcutHelper.BottomSheet.DragHandle" parent="Widget.Material3.BottomSheet.DragHandle">
+        <item name="tint">?androidprv:attr/materialColorOutlineVariant</item>
+    </style>
+
+    <style name="KeyboardShortcutHelper.BottomSheetDialogAnimation">
+        <item name="android:windowEnterAnimation">@anim/slide_in_up</item>
+        <item name="android:windowExitAnimation">@anim/slide_out_down</item>
+    </style>
+
     <style name="BrightnessDialogContainer" parent="@style/BaseBrightnessDialogContainer" />
 
     <style name="Animation" />
@@ -1597,14 +1613,15 @@
         <item name="android:layout_marginEnd">12dp</item>
         <item name="android:paddingLeft">24dp</item>
         <item name="android:paddingRight">24dp</item>
-        <item name="android:minHeight">40dp</item>
+        <item name="android:minHeight">36dp</item>
+        <item name="android:minWidth">120dp</item>
         <item name="android:stateListAnimator">@*android:anim/flat_button_state_list_anim_material</item>
         <item name="android:pointerIcon">arrow</item>
     </style>
 
     <style name="ShortcutHorizontalDivider">
-        <item name="android:layout_width">120dp</item>
-        <item name="android:layout_height">1dp</item>
+        <item name="android:layout_width">132dp</item>
+        <item name="android:layout_height">2dp</item>
         <item name="android:layout_gravity">center_horizontal</item>
         <item name="android:background">?android:attr/dividerHorizontal</item>
     </style>
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
index 42ba05c..fbe1399 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -58,7 +58,7 @@
         "SystemUIUnfoldLib",
         "SystemUISharedLib-Keyguard",
         "WindowManager-Shell-shared",
-        "tracinglib-platform",
+        "//frameworks/libs/systemui:tracinglib-platform",
         "androidx.dynamicanimation_dynamicanimation",
         "androidx.concurrent_concurrent-futures",
         "androidx.lifecycle_lifecycle-runtime-ktx",
@@ -68,7 +68,7 @@
         "kotlinx_coroutines",
         "dagger2",
         "jsr330",
-        "com_android_systemui_shared_flags_lib",
+        "//frameworks/libs/systemui:com_android_systemui_shared_flags_lib",
     ],
     resource_dirs: [
         "res",
diff --git a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/UdfpsUtils.java b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/UdfpsUtils.java
index 9574fba..829dc4f 100644
--- a/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/UdfpsUtils.java
+++ b/packages/SystemUI/shared/biometrics/src/com/android/systemui/biometrics/UdfpsUtils.java
@@ -54,8 +54,9 @@
     }
 
     /**
-     * Gets the touch in native coordinates. Map the touch to portrait mode if the device is in
-     * landscape mode.
+     * Gets the touch in native coordinates.
+     *
+     * Maps the touch to portrait mode if the device is in landscape mode.
      *
      * @param idx                The pointer identifier.
      * @param event              The MotionEvent object containing full information about the event.
@@ -64,35 +65,87 @@
      */
     public Point getTouchInNativeCoordinates(int idx, MotionEvent event,
             UdfpsOverlayParams udfpsOverlayParams) {
-        Point portraitTouch = getPortraitTouch(idx, event, udfpsOverlayParams);
+        return getTouchInNativeCoordinates(idx, event, udfpsOverlayParams, true);
+    }
+
+    /**
+     * Gets the touch in native coordinates.
+     *
+     * Optionally map the touch to portrait mode if the device is in landscape mode.
+     *
+     * @param idx                The pointer identifier.
+     * @param event              The MotionEvent object containing full information about the event.
+     * @param udfpsOverlayParams The [UdfpsOverlayParams] used.
+     * @param rotateToPortrait   Whether to rotate the touch to portrait orientation.
+     * @return The mapped touch event.
+     */
+    public Point getTouchInNativeCoordinates(int idx, MotionEvent event,
+            UdfpsOverlayParams udfpsOverlayParams, boolean rotateToPortrait) {
+        Point touch;
+        if (rotateToPortrait) {
+            touch = getPortraitTouch(idx, event, udfpsOverlayParams);
+        } else {
+            touch = new Point((int) event.getRawX(idx), (int) event.getRawY(idx));
+        }
 
         // Scale the coordinates to native resolution.
         float scale = udfpsOverlayParams.getScaleFactor();
-        portraitTouch.x = (int) (portraitTouch.x / scale);
-        portraitTouch.y = (int) (portraitTouch.y / scale);
-        return portraitTouch;
+        touch.x = (int) (touch.x / scale);
+        touch.y = (int) (touch.y / scale);
+        return touch;
     }
 
     /**
      * @param idx                The pointer identifier.
      * @param event              The MotionEvent object containing full information about the event.
      * @param udfpsOverlayParams The [UdfpsOverlayParams] used.
-     * @return Whether the touch event is within sensor area.
+     * @return Whether the touch event (that needs to be rotated to portrait) is within sensor area.
      */
     public boolean isWithinSensorArea(int idx, MotionEvent event,
             UdfpsOverlayParams udfpsOverlayParams) {
-        Point portraitTouch = getPortraitTouch(idx, event, udfpsOverlayParams);
-        return udfpsOverlayParams.getSensorBounds().contains(portraitTouch.x, portraitTouch.y);
+        return isWithinSensorArea(idx, event, udfpsOverlayParams, true);
+    }
+
+    /**
+     * @param idx                The pointer identifier.
+     * @param event              The MotionEvent object containing full information about the event.
+     * @param udfpsOverlayParams The [UdfpsOverlayParams] used.
+     * @param rotateTouchToPortrait Whether to rotate the touch coordinates to portrait.
+     * @return Whether the touch event is within sensor area.
+     */
+    public boolean isWithinSensorArea(int idx, MotionEvent event,
+            UdfpsOverlayParams udfpsOverlayParams, boolean rotateTouchToPortrait) {
+        Point touch;
+        if (rotateTouchToPortrait) {
+            touch = getPortraitTouch(idx, event, udfpsOverlayParams);
+        } else {
+            touch = new Point((int) event.getRawX(idx), (int) event.getRawY(idx));
+        }
+        return udfpsOverlayParams.getSensorBounds().contains(touch.x, touch.y);
+    }
+
+    /**
+     * This function computes the angle of touch relative to the sensor, rotated to portrait,
+     * and maps the angle to a list of help messages which are announced if accessibility is
+     * enabled.
+     *
+     * @return announcement string
+     */
+    public String onTouchOutsideOfSensorArea(boolean touchExplorationEnabled, Context context,
+            int scaledTouchX, int scaledTouchY, UdfpsOverlayParams udfpsOverlayParams) {
+        return onTouchOutsideOfSensorArea(touchExplorationEnabled, context, scaledTouchX,
+                scaledTouchY, udfpsOverlayParams, true);
     }
 
     /**
      * This function computes the angle of touch relative to the sensor and maps the angle to a list
      * of help messages which are announced if accessibility is enabled.
      *
-     * @return Whether the announcing string is null
+     * @return announcement string
      */
     public String onTouchOutsideOfSensorArea(boolean touchExplorationEnabled, Context context,
-            int scaledTouchX, int scaledTouchY, UdfpsOverlayParams udfpsOverlayParams) {
+            int scaledTouchX, int scaledTouchY, UdfpsOverlayParams udfpsOverlayParams,
+            boolean touchRotatedToPortrait) {
         if (!touchExplorationEnabled) {
             return null;
         }
@@ -116,7 +169,8 @@
                         scaledTouchY,
                         scaledSensorX,
                         scaledSensorY,
-                        udfpsOverlayParams.getRotation()
+                        udfpsOverlayParams.getRotation(),
+                        touchRotatedToPortrait
                 );
         Log.v(TAG, "Announcing touch outside : $theStr");
         return theStr;
@@ -132,7 +186,7 @@
      * touchHints[1] = "Move Fingerprint down" And so on.
      */
     private String onTouchOutsideOfSensorAreaImpl(String[] touchHints, float touchX,
-            float touchY, float sensorX, float sensorY, int rotation) {
+            float touchY, float sensorX, float sensorY, int rotation, boolean rotatedToPortrait) {
         float xRelativeToSensor = touchX - sensorX;
         // Touch coordinates are with respect to the upper left corner, so reverse
         // this calculation
@@ -153,13 +207,16 @@
         int index = (int) ((degrees + halfBucketDegrees) % 360 / degreesPerBucket);
         index %= touchHints.length;
 
-        // A rotation of 90 degrees corresponds to increasing the index by 1.
-        if (rotation == Surface.ROTATION_90) {
-            index = (index + 1) % touchHints.length;
+        if (rotatedToPortrait) {
+            // A rotation of 90 degrees corresponds to increasing the index by 1.
+            if (rotation == Surface.ROTATION_90) {
+                index = (index + 1) % touchHints.length;
+            }
+            if (rotation == Surface.ROTATION_270) {
+                index = (index + 3) % touchHints.length;
+            }
         }
-        if (rotation == Surface.ROTATION_270) {
-            index = (index + 3) % touchHints.length;
-        }
+
         return touchHints[index];
     }
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
index 4632914..dcc1440 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/ISystemUiProxy.aidl
@@ -155,5 +155,10 @@
      */
     oneway void animateNavBarLongPress(boolean isTouchDown, boolean shrink, long durationMs) = 54;
 
-    // Next id = 55
+    /**
+     * Set the override value for home button long press duration in ms and slop multiplier.
+     */
+    oneway void setOverrideHomeButtonLongPress(long duration, float slopMultiplier) = 55;
+
+    // Next id = 56
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java
index d6a5477..3250a0c 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InteractionJankMonitorWrapper.java
@@ -85,4 +85,10 @@
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return;
         InteractionJankMonitor.getInstance().cancel(cujType);
     }
+
+    /** Return true if currently instrumenting a trace session. */
+    public static boolean isInstrumenting(@Cuj.CujType int cujType) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return false;
+        return InteractionJankMonitor.getInstance().isInstrumenting(cujType);
+    }
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
index 7af9917..d0d5caf 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
@@ -32,6 +32,8 @@
 import dagger.Provides
 import java.util.concurrent.Executor
 import javax.inject.Singleton
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.android.asCoroutineDispatcher
 
 /**
  * Dagger module with system-only dependencies for the unfold animation. The code that is used to
@@ -78,6 +80,13 @@
         @Provides
         @UnfoldBg
         @Singleton
+        fun unfoldBgDispatcher(@UnfoldBg handler: Handler): CoroutineDispatcher {
+            return handler.asCoroutineDispatcher("@UnfoldBg Dispatcher")
+        }
+
+        @Provides
+        @UnfoldBg
+        @Singleton
         fun provideBgLooper(): Looper {
             return HandlerThread("UnfoldBg", Process.THREAD_PRIORITY_FOREGROUND)
                 .apply { start() }
diff --git a/packages/SystemUI/src-debug/com/android/systemui/util/Compile.java b/packages/SystemUI/src-debug/com/android/systemui/util/Compile.java
deleted file mode 100644
index dc804ca..0000000
--- a/packages/SystemUI/src-debug/com/android/systemui/util/Compile.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.util;
-
-/** Constants that vary by compilation configuration. */
-public class Compile {
-    /** Whether SystemUI was compiled in debug mode, and supports debug features */
-    public static final boolean IS_DEBUG = true;
-}
diff --git a/packages/SystemUI/src-release/com/android/systemui/util/Compile.java b/packages/SystemUI/src-release/com/android/systemui/util/Compile.java
deleted file mode 100644
index 8a63763..0000000
--- a/packages/SystemUI/src-release/com/android/systemui/util/Compile.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.util;
-
-/** Constants that vary by compilation configuration. */
-public class Compile {
-    /** Whether SystemUI was compiled in debug mode, and supports debug features */
-    public static final boolean IS_DEBUG = false;
-}
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index 48271de..70182c1 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -31,6 +31,7 @@
 import androidx.annotation.VisibleForTesting
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.customization.R
 import com.android.systemui.dagger.qualifiers.Background
@@ -65,6 +66,7 @@
 import java.util.TimeZone
 import java.util.concurrent.Executor
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.DisposableHandle
 import kotlinx.coroutines.Job
@@ -72,7 +74,6 @@
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.merge
-import kotlinx.coroutines.launch
 
 /**
  * Controller for a Clock provided by the registry and used on the keyguard. Instantiated by
@@ -90,6 +91,7 @@
     @DisplaySpecific private val resources: Resources,
     private val context: Context,
     @Main private val mainExecutor: DelayableExecutor,
+    @Main private val mainImmediateDispatcher: CoroutineDispatcher,
     @Background private val bgExecutor: Executor,
     private val clockBuffers: ClockMessageBuffers,
     private val featureFlags: FeatureFlagsClassic,
@@ -424,7 +426,7 @@
         keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback)
         zenModeController.addCallback(zenModeCallback)
         disposableHandle =
-            parent.repeatWhenAttached {
+            parent.repeatWhenAttached(mainImmediateDispatcher) {
                 repeatOnLifecycle(Lifecycle.State.CREATED) {
                     listenForDozing(this)
                     if (MigrateClocksToBlueprint.isEnabled) {
@@ -529,18 +531,22 @@
 
     @VisibleForTesting
     internal fun listenForDozeAmount(scope: CoroutineScope): Job {
-        return scope.launch { keyguardInteractor.dozeAmount.collect { handleDoze(it) } }
+        return scope.launch("$TAG#listenForDozeAmount") {
+            keyguardInteractor.dozeAmount.collect { handleDoze(it) }
+        }
     }
 
     @VisibleForTesting
     internal fun listenForDozeAmountTransition(scope: CoroutineScope): Job {
-        return scope.launch {
+        return scope.launch("$TAG#listenForDozeAmountTransition") {
             merge(
                     keyguardTransitionInteractor.aodToLockscreenTransition.map { step ->
                         step.copy(value = 1f - step.value)
                     },
                     keyguardTransitionInteractor.lockscreenToAodTransition,
-                )
+                ).filter {
+                    it.transitionState != TransitionState.FINISHED
+                }
                 .collect { handleDoze(it.value) }
         }
     }
@@ -550,7 +556,7 @@
      */
     @VisibleForTesting
     internal fun listenForAnyStateToAodTransition(scope: CoroutineScope): Job {
-        return scope.launch {
+        return scope.launch("$TAG#listenForAnyStateToAodTransition") {
             keyguardTransitionInteractor
                 .transitionStepsToState(AOD)
                 .filter { it.transitionState == TransitionState.STARTED }
@@ -561,7 +567,7 @@
 
     @VisibleForTesting
     internal fun listenForDozing(scope: CoroutineScope): Job {
-        return scope.launch {
+        return scope.launch("$TAG#listenForDozing") {
             combine(
                     keyguardInteractor.dozeAmount,
                     keyguardInteractor.isDozing,
@@ -626,7 +632,7 @@
     }
 
     companion object {
-        private val TAG = ClockEventController::class.simpleName!!
-        private val DOZE_TICKRATE_THRESHOLD = 0.99f
+        private const val TAG = "ClockEventController"
+        private const val DOZE_TICKRATE_THRESHOLD = 0.99f
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/EmptyLockIconViewController.kt b/packages/SystemUI/src/com/android/keyguard/EmptyLockIconViewController.kt
new file mode 100644
index 0000000..b792db3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/EmptyLockIconViewController.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard
+
+import android.view.MotionEvent
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyguard.ui.view.KeyguardRootView
+import com.android.systemui.res.R
+import dagger.Lazy
+import javax.inject.Inject
+
+/**
+ * Lock icon view logic now lives in DeviceEntryIconViewBinder and ViewModels. Icon is positioned in
+ * [com.android.systemui.keyguard.ui.view.layout.sections.DefaultDeviceEntrySection].
+ *
+ * This class is to bridge the gap between the logic when the DeviceEntryUdfpsRefactor is enabled
+ * and the KeyguardBottomAreaRefactor is NOT enabled. This class can and should be removed when both
+ * flags are enabled.
+ */
+@SysUISingleton
+class EmptyLockIconViewController
+@Inject
+constructor(
+    private val keyguardRootView: Lazy<KeyguardRootView>,
+) : LockIconViewController {
+    private val deviceEntryIconViewId = R.id.device_entry_icon_view
+    override fun setLockIconView(lockIconView: LockIconView) {
+        // no-op
+    }
+
+    override fun getTop(): Float {
+        return keyguardRootView.get().getViewById(deviceEntryIconViewId)?.top?.toFloat() ?: 0f
+    }
+
+    override fun getBottom(): Float {
+        return keyguardRootView.get().getViewById(deviceEntryIconViewId)?.bottom?.toFloat() ?: 0f
+    }
+
+    override fun dozeTimeTick() {
+        // no-op
+    }
+
+    override fun setAlpha(alpha: Float) {
+        // no-op
+    }
+
+    override fun willHandleTouchWhileDozing(event: MotionEvent): Boolean {
+        return false
+    }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 5b8eb9d..790a843 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -250,7 +250,6 @@
             mLargeClockFrame = mView.findViewById(R.id.lockscreen_clock_view_large);
         }
 
-
         if (!mOnlyClock) {
             mDumpManager.unregisterDumpable(getClass().getSimpleName()); // unregister previous
             mDumpManager.registerDumpable(getClass().getSimpleName(), this);
@@ -282,7 +281,9 @@
     protected void onViewAttached() {
         mClockRegistry.registerClockChangeListener(mClockChangedListener);
         setClock(mClockRegistry.createCurrentClock());
-        mClockEventController.registerListeners(mView);
+        if (!MigrateClocksToBlueprint.isEnabled()) {
+            mClockEventController.registerListeners(mView);
+        }
         mKeyguardSmallClockTopMargin =
                 mView.getResources().getDimensionPixelSize(R.dimen.keyguard_clock_top_margin);
         mKeyguardLargeClockTopMargin =
@@ -365,7 +366,9 @@
     @Override
     protected void onViewDetached() {
         mClockRegistry.unregisterClockChangeListener(mClockChangedListener);
-        mClockEventController.unregisterListeners();
+        if (!MigrateClocksToBlueprint.isEnabled()) {
+            mClockEventController.unregisterListeners();
+        }
         setClock(null);
 
         mBgExecutor.execute(() -> {
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java
similarity index 99%
rename from packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
rename to packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java
index 985f6c8..4e5df35 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LegacyLockIconViewController.java
@@ -98,7 +98,7 @@
  * icon will show a set distance from the bottom of the device.
  */
 @SysUISingleton
-public class LockIconViewController implements Dumpable {
+public class LegacyLockIconViewController implements Dumpable, LockIconViewController {
     private static final String TAG = "LockIconViewController";
     private static final float sDefaultDensity =
             (float) DisplayMetrics.DENSITY_DEVICE_STABLE / (float) DisplayMetrics.DENSITY_DEFAULT;
@@ -189,7 +189,7 @@
             };
 
     @Inject
-    public LockIconViewController(
+    public LegacyLockIconViewController(
             @NonNull StatusBarStateController statusBarStateController,
             @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor,
             @NonNull KeyguardViewController keyguardViewController,
@@ -262,6 +262,7 @@
 
     /** Sets the LockIconView to the controller and rebinds any that depend on it. */
     @SuppressLint("ClickableViewAccessibility")
+    @Override
     public void setLockIconView(LockIconView lockIconView) {
         mView = lockIconView;
         mView.setAccessibilityDelegate(mAccessibilityDelegate);
@@ -344,10 +345,12 @@
         }
     }
 
+    @Override
     public float getTop() {
         return mView.getLocationTop();
     }
 
+    @Override
     public float getBottom() {
         return mView.getLocationBottom();
     }
@@ -499,6 +502,7 @@
     }
 
     /** Every minute, update the aod icon's burn in offset */
+    @Override
     public void dozeTimeTick() {
         updateBurnInOffsets();
     }
@@ -774,6 +778,7 @@
     /**
      * Set the alpha of this view.
      */
+    @Override
     public void setAlpha(float alpha) {
         mView.setAlpha(alpha);
     }
@@ -823,6 +828,7 @@
     /**
      * Whether the lock icon will handle a touch while dozing.
      */
+    @Override
     public boolean willHandleTouchWhileDozing(MotionEvent event) {
         // is in lock icon area
         mView.getHitRect(mSensorTouchLocation);
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.kt
similarity index 63%
copy from tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
copy to packages/SystemUI/src/com/android/keyguard/LockIconViewController.kt
index 4e64ab0..10d5a0c 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.kt
@@ -14,15 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.keyguard
 
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
+import android.view.MotionEvent
 
-import java.util.List;
-
-public interface AslMarshallable {
-
-    /** Creates the on-device DOM element from the AslMarshallable Java Object. */
-    List<Element> toOdDomElements(Document doc);
+/** Controls the [LockIconView]. */
+interface LockIconViewController {
+    fun setLockIconView(lockIconView: LockIconView)
+    fun getTop(): Float
+    fun getBottom(): Float
+    fun dozeTimeTick()
+    fun setAlpha(alpha: Float)
+    fun willHandleTouchWhileDozing(event: MotionEvent): Boolean
 }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index ea8fe59..fb88f0e 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -300,7 +300,7 @@
 
                 Class<?> cls = entry.getKey();
                 Dependencies dep = cls.getAnnotation(Dependencies.class);
-                Class<? extends CoreStartable>[] deps = (dep == null ? null : dep.value());
+                Class<?>[] deps = (dep == null ? null : dep.value());
                 if (deps == null || startedStartables.containsAll(Arrays.asList(deps))) {
                     String clsName = cls.getName();
                     int i = serviceIndex;  // Copied to make lambda happy.
@@ -324,7 +324,7 @@
                 Map.Entry<Class<?>, Provider<CoreStartable>> entry = nextQueue.removeFirst();
                 Class<?> cls = entry.getKey();
                 Dependencies dep = cls.getAnnotation(Dependencies.class);
-                Class<? extends CoreStartable>[] deps = (dep == null ? null : dep.value());
+                Class<?>[] deps = (dep == null ? null : dep.value());
                 StringJoiner stringJoiner = new StringJoiner(", ");
                 for (int i = 0; deps != null && i < deps.length; i++) {
                     if (!startedStartables.contains(deps[i])) {
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index b26be0c..0cc3be2 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -99,9 +99,10 @@
         if (Build.IS_DEBUGGABLE) {
             // b/71353150 - looking for leaked binder proxies
             BinderInternal.nSetBinderProxyCountEnabled(true);
-            BinderInternal.nSetBinderProxyCountWatermarks(1000,900);
+            BinderInternal.nSetBinderProxyCountWatermarks(
+                    /* high= */ 1000, /* low= */ 900, /* warning= */ 950);
             BinderInternal.setBinderProxyCountCallback(
-                    new BinderInternal.BinderProxyLimitListener() {
+                    new BinderInternal.BinderProxyCountEventListener() {
                         @Override
                         public void onLimitReached(int uid) {
                             Slog.w(SystemUIApplication.TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSizePrefs.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSizePrefs.java
index 4d7ad264..a401f2a 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSizePrefs.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationSizePrefs.java
@@ -23,7 +23,7 @@
 /**
  * Class to handle SharedPreference for window magnification size.
  */
-public final class WindowMagnificationSizePrefs {
+final class WindowMagnificationSizePrefs {
 
     private static final String WINDOW_MAGNIFICATION_PREFERENCES =
             "window_magnification_preferences";
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java
index 0538e7d..1018f70 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java
@@ -21,8 +21,8 @@
 import static android.provider.Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY;
 import static android.provider.Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE;
 import static android.provider.Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
 
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
 import static com.android.systemui.accessibility.floatingmenu.MenuFadeEffectInfoKt.DEFAULT_FADE_EFFECT_IS_ENABLED;
 import static com.android.systemui.accessibility.floatingmenu.MenuFadeEffectInfoKt.DEFAULT_OPACITY_VALUE;
@@ -182,7 +182,7 @@
     }
 
     void loadMenuTargetFeatures(OnInfoReady<List<AccessibilityTarget>> callback) {
-        callback.onReady(getTargets(mContext, ACCESSIBILITY_BUTTON));
+        callback.onReady(getTargets(mContext, SOFTWARE));
     }
 
     void loadMenuSizeType(OnInfoReady<Integer> callback) {
@@ -223,7 +223,7 @@
 
     private void onTargetFeaturesChanged() {
         mSettingsContentsCallback.onTargetFeaturesChanged(
-                getTargets(mContext, ACCESSIBILITY_BUTTON));
+                getTargets(mContext, SOFTWARE));
     }
 
     private Position getStartPosition() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
index 1f5a0bf..be75e10 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
@@ -36,7 +36,6 @@
 import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.internal.accessibility.dialog.AccessibilityTarget;
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.modules.expresslog.Counter;
 import com.android.systemui.Flags;
 import com.android.systemui.util.settings.SecureSettings;
@@ -418,18 +417,11 @@
         onPositionChanged();
     }
 
-    void incrementTexMetricForAllTargets(String metric) {
+    void incrementTexMetric(String metric) {
         if (!Flags.floatingMenuDragToEdit()) {
             return;
         }
-        for (AccessibilityTarget target : mTargetFeatures) {
-            incrementTexMetric(metric, target.getUid());
-        }
-    }
-
-    @VisibleForTesting
-    void incrementTexMetric(String metric, int uid) {
-        Counter.logIncrementWithUid(metric, uid);
+        Counter.logIncrement(metric);
     }
 
     private InstantInsetLayerDrawable getContainerViewInsetLayer() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
index 85bf784..6dce1bb 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
@@ -17,13 +17,13 @@
 package com.android.systemui.accessibility.floatingmenu;
 
 import static android.view.WindowInsets.Type.ime;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
 
 import static androidx.core.view.WindowInsetsCompat.Type;
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_BUTTON_COMPONENT_NAME;
 import static com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType.INVISIBLE_TOGGLE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
 import static com.android.internal.accessibility.util.AccessibilityUtils.getAccessibilityServiceFragmentType;
 import static com.android.internal.accessibility.util.AccessibilityUtils.setAccessibilityServiceState;
 import static com.android.systemui.accessibility.floatingmenu.MenuMessageView.Index;
@@ -105,14 +105,14 @@
      *
      * <p>Defined in frameworks/proto_logging/stats/express/catalog/accessibility.cfg.
      */
-    static final String TEX_METRIC_DISMISS = "accessibility.value_fab_shortcut_action_dismiss";
+    static final String TEX_METRIC_DISMISS = "accessibility.value_fab_shortcut_dismiss";
 
     /**
      * Counter indicating the FAB was dragged to the Edit action button.
      *
      * <p>Defined in frameworks/proto_logging/stats/express/catalog/accessibility.cfg.
      */
-    static final String TEX_METRIC_EDIT = "accessibility.value_fab_shortcut_action_edit";
+    static final String TEX_METRIC_EDIT = "accessibility.value_fab_shortcut_edit";
 
     private final WindowManager mWindowManager;
     private final MenuView mMenuView;
@@ -175,8 +175,8 @@
                 mAccessibilityManager.enableShortcutsForTargets(
                         /* enable= */ false,
                         ShortcutConstants.UserShortcutType.SOFTWARE,
-                        new ArraySet<>(mAccessibilityManager.getAccessibilityShortcutTargets(
-                                ACCESSIBILITY_BUTTON)),
+                        new ArraySet<>(
+                                mAccessibilityManager.getAccessibilityShortcutTargets(SOFTWARE)),
                         mSecureSettings.getRealUserHandle(UserHandle.USER_CURRENT)
                 );
             } else {
@@ -185,8 +185,7 @@
                         UserHandle.USER_CURRENT);
 
                 final List<ComponentName> hardwareKeyShortcutComponents =
-                        mAccessibilityManager.getAccessibilityShortcutTargets(
-                                        ACCESSIBILITY_SHORTCUT_KEY)
+                        mAccessibilityManager.getAccessibilityShortcutTargets(HARDWARE)
                                 .stream()
                                 .map(ComponentName::unflattenFromString)
                                 .toList();
@@ -492,11 +491,11 @@
             } else {
                 hideMenuAndShowMessage();
             }
-            mMenuView.incrementTexMetricForAllTargets(TEX_METRIC_DISMISS);
+            mMenuView.incrementTexMetric(TEX_METRIC_DISMISS);
         } else if (id == R.id.action_edit
                 && Flags.floatingMenuDragToEdit()) {
             gotoEditScreen();
-            mMenuView.incrementTexMetricForAllTargets(TEX_METRIC_EDIT);
+            mMenuView.incrementTexMetric(TEX_METRIC_EDIT);
         }
         mDismissView.hide();
         mDragToInteractView.hide();
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
new file mode 100644
index 0000000..96eb4b3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility.hearingaid;
+
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+
+import static java.util.Collections.emptyList;
+
+import android.content.Context;
+import android.content.Intent;
+import android.media.AudioManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.provider.Settings;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.Visibility;
+import android.widget.Button;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.settingslib.bluetooth.BluetoothCallback;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.systemui.accessibility.hearingaid.HearingDevicesListAdapter.HearingDeviceItemCallback;
+import com.android.systemui.animation.DialogTransitionAnimator;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.qs.tiles.dialog.bluetooth.ActiveHearingDeviceItemFactory;
+import com.android.systemui.qs.tiles.dialog.bluetooth.AvailableHearingDeviceItemFactory;
+import com.android.systemui.qs.tiles.dialog.bluetooth.ConnectedDeviceItemFactory;
+import com.android.systemui.qs.tiles.dialog.bluetooth.DeviceItem;
+import com.android.systemui.qs.tiles.dialog.bluetooth.DeviceItemFactory;
+import com.android.systemui.qs.tiles.dialog.bluetooth.SavedHearingDeviceItemFactory;
+import com.android.systemui.res.R;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+
+import dagger.assisted.Assisted;
+import dagger.assisted.AssistedFactory;
+import dagger.assisted.AssistedInject;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * Dialog for showing hearing devices controls.
+ */
+public class HearingDevicesDialogDelegate implements SystemUIDialog.Delegate,
+        HearingDeviceItemCallback, BluetoothCallback {
+
+    @VisibleForTesting
+    static final String ACTION_BLUETOOTH_DEVICE_DETAILS =
+            "com.android.settings.BLUETOOTH_DEVICE_DETAIL_SETTINGS";
+    private static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args";
+    private static final String KEY_BLUETOOTH_ADDRESS = "device_address";
+    private final SystemUIDialog.Factory mSystemUIDialogFactory;
+    private final DialogTransitionAnimator mDialogTransitionAnimator;
+    private final ActivityStarter mActivityStarter;
+    private final boolean mShowPairNewDevice;
+    private final LocalBluetoothManager mLocalBluetoothManager;
+    private final Handler mMainHandler;
+    private final AudioManager mAudioManager;
+
+    private HearingDevicesListAdapter mDeviceListAdapter;
+    private SystemUIDialog mDialog;
+    private RecyclerView mDeviceList;
+    private Button mPairButton;
+    private final List<DeviceItemFactory> mHearingDeviceItemFactoryList = List.of(
+            new ActiveHearingDeviceItemFactory(),
+            new AvailableHearingDeviceItemFactory(),
+            // TODO(b/331305850): setHearingAidInfo() for connected but not connect to profile
+            // hearing device only called from
+            // settings/bluetooth/DeviceListPreferenceFragment#handleLeScanResult, so we don't know
+            // it is connected but not yet connect to profile hearing device in systemui.
+            // Show all connected but not connect to profile bluetooth device for now.
+            new ConnectedDeviceItemFactory(),
+            new SavedHearingDeviceItemFactory()
+    );
+
+    /** Factory to create a {@link HearingDevicesDialogDelegate} dialog instance. */
+    @AssistedFactory
+    public interface Factory {
+        /** Create a {@link HearingDevicesDialogDelegate} instance */
+        HearingDevicesDialogDelegate create(
+                boolean showPairNewDevice);
+    }
+
+    @AssistedInject
+    public HearingDevicesDialogDelegate(
+            @Assisted boolean showPairNewDevice,
+            SystemUIDialog.Factory systemUIDialogFactory,
+            ActivityStarter activityStarter,
+            DialogTransitionAnimator dialogTransitionAnimator,
+            @Nullable LocalBluetoothManager localBluetoothManager,
+            @Main Handler handler,
+            AudioManager audioManager) {
+        mShowPairNewDevice = showPairNewDevice;
+        mSystemUIDialogFactory = systemUIDialogFactory;
+        mActivityStarter = activityStarter;
+        mDialogTransitionAnimator = dialogTransitionAnimator;
+        mLocalBluetoothManager = localBluetoothManager;
+        mMainHandler = handler;
+        mAudioManager = audioManager;
+    }
+
+    @Override
+    public SystemUIDialog createDialog() {
+        SystemUIDialog dialog = mSystemUIDialogFactory.create(this);
+        dismissDialogIfExists();
+        mDialog = dialog;
+
+        return dialog;
+    }
+
+    @Override
+    public void onDeviceItemGearClicked(@NonNull  DeviceItem deviceItem, @NonNull View view) {
+        dismissDialogIfExists();
+        Intent intent = new Intent(ACTION_BLUETOOTH_DEVICE_DETAILS);
+        Bundle bundle = new Bundle();
+        bundle.putString(KEY_BLUETOOTH_ADDRESS, deviceItem.getCachedBluetoothDevice().getAddress());
+        intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, bundle);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        mActivityStarter.postStartActivityDismissingKeyguard(intent, /* delay= */ 0,
+                mDialogTransitionAnimator.createActivityTransitionController(view));
+    }
+
+    @Override
+    public void onDeviceItemOnClicked(@NonNull  DeviceItem deviceItem, @NonNull View view) {
+        CachedBluetoothDevice cachedBluetoothDevice = deviceItem.getCachedBluetoothDevice();
+        switch (deviceItem.getType()) {
+            case ACTIVE_MEDIA_BLUETOOTH_DEVICE, CONNECTED_BLUETOOTH_DEVICE ->
+                    cachedBluetoothDevice.disconnect();
+            case AVAILABLE_MEDIA_BLUETOOTH_DEVICE -> cachedBluetoothDevice.setActive();
+            case SAVED_BLUETOOTH_DEVICE -> cachedBluetoothDevice.connect();
+        }
+    }
+
+    @Override
+    public void onActiveDeviceChanged(@Nullable CachedBluetoothDevice activeDevice,
+            int bluetoothProfile) {
+        mMainHandler.post(() -> mDeviceListAdapter.refreshDeviceItemList(getHearingDevicesList()));
+    }
+
+    @Override
+    public void onProfileConnectionStateChanged(@NonNull CachedBluetoothDevice cachedDevice,
+            int state, int bluetoothProfile) {
+        mMainHandler.post(() -> mDeviceListAdapter.refreshDeviceItemList(getHearingDevicesList()));
+    }
+
+    @Override
+    public void onAclConnectionStateChanged(@NonNull CachedBluetoothDevice cachedDevice,
+            int state) {
+        mMainHandler.post(() -> mDeviceListAdapter.refreshDeviceItemList(getHearingDevicesList()));
+    }
+
+    @Override
+    public void beforeCreate(@NonNull SystemUIDialog dialog, @Nullable Bundle savedInstanceState) {
+        dialog.setTitle(R.string.quick_settings_hearing_devices_dialog_title);
+        dialog.setView(LayoutInflater.from(dialog.getContext()).inflate(
+                R.layout.hearing_devices_tile_dialog, null));
+        dialog.setPositiveButton(
+                R.string.quick_settings_done,
+                /* onClick = */ null,
+                /* dismissOnClick = */ true
+        );
+    }
+
+    @Override
+    public void onCreate(@NonNull SystemUIDialog dialog, @Nullable Bundle savedInstanceState) {
+        mPairButton = dialog.requireViewById(R.id.pair_new_device_button);
+        mDeviceList = dialog.requireViewById(R.id.device_list);
+
+        setupDeviceListView(dialog);
+        setupPairNewDeviceButton(dialog, mShowPairNewDevice ? VISIBLE : GONE);
+    }
+
+    @Override
+    public void onStart(@NonNull SystemUIDialog dialog) {
+        if (mLocalBluetoothManager == null) {
+            return;
+        }
+        mLocalBluetoothManager.getEventManager().registerCallback(this);
+    }
+
+    @Override
+    public void onStop(@NonNull SystemUIDialog dialog) {
+        if (mLocalBluetoothManager == null) {
+            return;
+        }
+        mLocalBluetoothManager.getEventManager().unregisterCallback(this);
+    }
+
+    private void setupDeviceListView(SystemUIDialog dialog) {
+        mDeviceList.setLayoutManager(new LinearLayoutManager(dialog.getContext()));
+        mDeviceListAdapter = new HearingDevicesListAdapter(getHearingDevicesList(), this);
+        mDeviceList.setAdapter(mDeviceListAdapter);
+    }
+
+    private void setupPairNewDeviceButton(SystemUIDialog dialog, @Visibility int visibility) {
+        if (visibility == VISIBLE) {
+            mPairButton.setOnClickListener(v -> {
+                dismissDialogIfExists();
+                final Intent intent = new Intent(Settings.ACTION_HEARING_DEVICE_PAIRING_SETTINGS);
+                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+                mActivityStarter.postStartActivityDismissingKeyguard(intent, /* delay= */ 0,
+                        mDialogTransitionAnimator.createActivityTransitionController(dialog));
+            });
+        } else {
+            mPairButton.setVisibility(GONE);
+        }
+    }
+
+    private List<DeviceItem> getHearingDevicesList() {
+        if (mLocalBluetoothManager == null
+                || !mLocalBluetoothManager.getBluetoothAdapter().isEnabled()) {
+            return emptyList();
+        }
+
+        return mLocalBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy().stream()
+                .map(this::createHearingDeviceItem)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+    }
+
+    private DeviceItem createHearingDeviceItem(CachedBluetoothDevice cachedDevice) {
+        final Context context = mDialog.getContext();
+        if (cachedDevice == null) {
+            return null;
+        }
+        for (DeviceItemFactory itemFactory : mHearingDeviceItemFactoryList) {
+            if (itemFactory.isFilterMatched(context, cachedDevice, mAudioManager)) {
+                return itemFactory.create(context, cachedDevice);
+            }
+        }
+        return null;
+    }
+
+    private void dismissDialogIfExists() {
+        if (mDialog != null) {
+            mDialog.dismiss();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogManager.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogManager.java
new file mode 100644
index 0000000..623b40f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogManager.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility.hearingaid;
+
+import android.bluetooth.BluetoothDevice;
+import android.util.Log;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.jank.InteractionJankMonitor;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.systemui.animation.DialogCuj;
+import com.android.systemui.animation.DialogTransitionAnimator;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+
+import javax.inject.Inject;
+
+/**
+ * Factory to create {@link HearingDevicesDialogDelegate} objects and manage its lifecycle.
+ */
+@SysUISingleton
+public class HearingDevicesDialogManager {
+
+    private static final boolean DEBUG = true;
+    private static final String TAG = "HearingDevicesDialogManager";
+    private static final String INTERACTION_JANK_TAG = "hearing_devices_tile";
+    private SystemUIDialog mDialog;
+    private final DialogTransitionAnimator mDialogTransitionAnimator;
+    private final HearingDevicesDialogDelegate.Factory mDialogFactory;
+    private final LocalBluetoothManager mLocalBluetoothManager;
+
+    @Inject
+    public HearingDevicesDialogManager(
+            DialogTransitionAnimator dialogTransitionAnimator,
+            HearingDevicesDialogDelegate.Factory dialogFactory,
+            @Nullable LocalBluetoothManager localBluetoothManager) {
+        mDialogTransitionAnimator = dialogTransitionAnimator;
+        mDialogFactory = dialogFactory;
+        mLocalBluetoothManager = localBluetoothManager;
+    }
+
+    /**
+     * Shows the dialog.
+     *
+     * @param view The view from which the dialog is shown.
+     */
+    public void showDialog(View view) {
+        if (mDialog != null) {
+            if (DEBUG) {
+                Log.d(TAG, "HearingDevicesDialog already showing. Destroy it first.");
+            }
+            destroyDialog();
+        }
+
+        mDialog = mDialogFactory.create(!isAnyBondedHearingDevice()).createDialog();
+
+        if (view != null) {
+            mDialogTransitionAnimator.showFromView(mDialog, view,
+                    new DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
+                            INTERACTION_JANK_TAG), /* animateBackgroundBoundsChange= */ true);
+        } else {
+            mDialog.show();
+        }
+    }
+
+    private void destroyDialog() {
+        mDialog.dismiss();
+        mDialog = null;
+    }
+
+    private boolean isAnyBondedHearingDevice() {
+        if (mLocalBluetoothManager == null) {
+            return false;
+        }
+        if (!mLocalBluetoothManager.getBluetoothAdapter().isEnabled()) {
+            return false;
+        }
+
+        return mLocalBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy().stream()
+                .anyMatch(device -> device.isHearingAidDevice()
+                        && device.getBondState() != BluetoothDevice.BOND_NONE);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogReceiver.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogReceiver.java
new file mode 100644
index 0000000..6a34d19
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogReceiver.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility.hearingaid;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+import com.android.systemui.Flags;
+
+import javax.inject.Inject;
+
+/**
+ * BroadcastReceiver for handling hearing devices dialog intent.
+ *
+ * <p> This is not exported. Need to call from framework and use SYSTEM user to send the intent.
+ */
+public class HearingDevicesDialogReceiver extends BroadcastReceiver {
+    public static String ACTION = "com.android.systemui.action.LAUNCH_HEARING_DEVICES_DIALOG";
+
+    private final HearingDevicesDialogManager mDialogManager;
+    @Inject
+    public HearingDevicesDialogReceiver(
+            HearingDevicesDialogManager hearingDevicesDialogManager) {
+        mDialogManager = hearingDevicesDialogManager;
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        if (!Flags.hearingAidsQsTileDialog()) {
+            return;
+        }
+
+        if (ACTION.equals(intent.getAction())) {
+            mDialogManager.showDialog(/* view= */ null);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java
new file mode 100644
index 0000000..695d04f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapter.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility.hearingaid;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.systemui.qs.tiles.dialog.bluetooth.DeviceItem;
+import com.android.systemui.res.R;
+
+import kotlin.Pair;
+
+import java.util.List;
+
+/**
+ * Adapter for showing hearing device item list {@link DeviceItem}.
+ */
+public class HearingDevicesListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
+    private final List<DeviceItem> mItemList;
+    private final HearingDeviceItemCallback mCallback;
+
+    public HearingDevicesListAdapter(List<DeviceItem> itemList,
+            HearingDeviceItemCallback callback) {
+        mItemList = itemList;
+        mCallback = callback;
+    }
+
+    @NonNull
+    @Override
+    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) {
+        View view = LayoutInflater.from(viewGroup.getContext()).inflate(
+                R.layout.bluetooth_device_item, viewGroup, false);
+        return new DeviceItemViewHolder(view, viewGroup.getContext());
+    }
+
+    @Override
+    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
+        DeviceItem item = mItemList.get(position);
+        ((DeviceItemViewHolder) viewHolder).bindView(item, mCallback);
+    }
+
+    @Override
+    public int getItemCount() {
+        return mItemList.size();
+    }
+
+    /**
+     * Updates items in the adapter.
+     *
+     * @param itemList bluetooth device item list
+     */
+    public void refreshDeviceItemList(List<DeviceItem> itemList) {
+        mItemList.clear();
+        mItemList.addAll(itemList);
+        notifyDataSetChanged();
+    }
+
+    /**
+     * Interface to provide callbacks when click on the device item in hearing device quick
+     * settings tile.
+     */
+    public interface HearingDeviceItemCallback {
+        /**
+         * Called when gear view in device item is clicked.
+         *
+         * @param deviceItem bluetooth device item
+         * @param view       the view that was clicked
+         */
+        void onDeviceItemGearClicked(@NonNull DeviceItem deviceItem, @NonNull View view);
+
+        /**
+         * Called when device item is clicked.
+         *
+         * @param deviceItem bluetooth device item
+         * @param view       the view that was clicked
+         */
+        void onDeviceItemOnClicked(@NonNull DeviceItem deviceItem, @NonNull View view);
+    }
+
+    private static class DeviceItemViewHolder extends RecyclerView.ViewHolder {
+        private final Context mContext;
+        private final View mContainer;
+        private final TextView mNameView;
+        private final TextView mSummaryView;
+        private final ImageView mIconView;
+        private final View mGearView;
+
+        DeviceItemViewHolder(@NonNull View itemView, Context context) {
+            super(itemView);
+            mContext = context;
+            mContainer = itemView.requireViewById(R.id.bluetooth_device_row);
+            mNameView = itemView.requireViewById(R.id.bluetooth_device_name);
+            mSummaryView = itemView.requireViewById(R.id.bluetooth_device_summary);
+            mIconView = itemView.requireViewById(R.id.bluetooth_device_icon);
+            mGearView = itemView.requireViewById(R.id.gear_icon);
+        }
+
+        public void bindView(DeviceItem item, HearingDeviceItemCallback callback) {
+            mContainer.setEnabled(item.isEnabled());
+            mContainer.setOnClickListener(view -> callback.onDeviceItemOnClicked(item, view));
+            Integer backgroundResId = item.getBackground();
+            if (backgroundResId != null) {
+                mContainer.setBackground(mContext.getDrawable(item.getBackground()));
+            }
+            mNameView.setText(item.getDeviceName());
+            mSummaryView.setText(item.getConnectionSummary());
+            Pair<Drawable, String> iconPair = item.getIconWithDescription();
+            if (iconPair != null) {
+                mIconView.setImageDrawable(iconPair.getFirst());
+                mIconView.setContentDescription(iconPair.getSecond());
+            }
+            mGearView.setOnClickListener(view -> callback.onDeviceItemGearClicked(item, view));
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
index 8ca083f..5df7fc9 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
@@ -243,12 +243,6 @@
         }
 
         // Authentication failed.
-
-        if (tryAutoConfirm) {
-            // Auto-confirm is active, the failed attempt should have no side-effects.
-            return AuthenticationResult.FAILED
-        }
-
         repository.reportAuthenticationAttempt(isSuccessful = false)
 
         if (authenticationResult.lockoutDurationMs > 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt b/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt
index 6721c5d..a667de2 100644
--- a/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt
@@ -27,10 +27,15 @@
 import android.os.ParcelFileDescriptor
 import android.os.UserHandle
 import android.util.Log
+import com.android.app.tracing.traceSection
+import com.android.systemui.Flags.communalHub
+import com.android.systemui.backup.BackupHelper.Companion.ACTION_RESTORE_FINISHED
+import com.android.systemui.communal.domain.backup.CommunalPrefsBackupHelper
 import com.android.systemui.controls.controller.AuxiliaryPersistenceWrapper
 import com.android.systemui.controls.controller.ControlsFavoritePersistenceWrapper
 import com.android.systemui.keyguard.domain.backup.KeyguardQuickAffordanceBackupHelper
 import com.android.systemui.people.widget.PeopleBackupHelper
+import com.android.systemui.res.R
 import com.android.systemui.settings.UserFileManagerImpl
 
 /**
@@ -52,6 +57,8 @@
         private const val PEOPLE_TILES_BACKUP_KEY = "systemui.people.shared_preferences"
         private const val KEYGUARD_QUICK_AFFORDANCES_BACKUP_KEY =
             "systemui.keyguard.quickaffordance.shared_preferences"
+        private const val COMMUNAL_PREFS_BACKUP_KEY =
+            "systemui.communal.shared_preferences"
         val controlsDataLock = Any()
         const val ACTION_RESTORE_FINISHED = "com.android.systemui.backup.RESTORE_FINISHED"
         const val PERMISSION_SELF = "com.android.systemui.permission.SELF"
@@ -74,6 +81,15 @@
                 userId = userHandle.identifier,
             ),
         )
+        if (communalEnabled()) {
+            addHelper(
+                COMMUNAL_PREFS_BACKUP_KEY,
+                CommunalPrefsBackupHelper(
+                    context = this,
+                    userId = userHandle.identifier,
+                )
+            )
+        }
     }
 
     override fun onRestoreFinished() {
@@ -99,6 +115,10 @@
         }
     }
 
+    private fun communalEnabled(): Boolean {
+        return resources.getBoolean(R.bool.config_communalServiceEnabled) && communalHub()
+    }
+
     /**
      * Helper class for restoring files ONLY if they are not present.
      *
@@ -119,14 +139,22 @@
     ) : FileBackupHelper(context, *fileNamesAndPostProcess.keys.toTypedArray()) {
 
         override fun restoreEntity(data: BackupDataInputStream) {
+            Log.d(TAG, "Starting restore for ${data.key} for user ${context.userId}")
             val file = Environment.buildPath(context.filesDir, data.key)
             if (file.exists()) {
                 Log.w(TAG, "File " + data.key + " already exists. Skipping restore.")
                 return
             }
             synchronized(lock) {
-                super.restoreEntity(data)
-                fileNamesAndPostProcess.get(data.key)?.invoke()
+                traceSection("File restore: ${data.key}") {
+                    super.restoreEntity(data)
+                }
+                Log.d(TAG, "Finishing restore for ${data.key} for user ${context.userId}. " +
+                        "Starting postProcess.")
+                traceSection("Postprocess: ${data.key}") {
+                    fileNamesAndPostProcess.get(data.key)?.invoke()
+                }
+                Log.d(TAG, "Finishing postprocess for ${data.key} for user ${context.userId}.")
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
index 01c2cc4..5c53234 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
@@ -27,6 +27,7 @@
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -52,6 +53,7 @@
 import com.android.systemui.battery.unified.BatteryColors;
 import com.android.systemui.battery.unified.BatteryDrawableState;
 import com.android.systemui.battery.unified.BatteryLayersDrawable;
+import com.android.systemui.battery.unified.ColorProfile;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
 import com.android.systemui.res.R;
@@ -252,7 +254,7 @@
                     new BatteryDrawableState(
                             level,
                             mUnifiedBatteryState.getShowPercent(),
-                            level <= 20,
+                            getCurrentColorProfile(),
                             attr
                     );
 
@@ -261,6 +263,7 @@
     }
 
     // Potentially reloads any attribution. Should not be called if the state hasn't changed
+    @SuppressLint("UseCompatLoadingForDrawables")
     private Drawable getBatteryAttribution(boolean isCharging) {
         if (!newStatusBarIcons()) return null;
 
@@ -281,6 +284,30 @@
         return attr;
     }
 
+    /** Calculate the appropriate color for the current state */
+    private ColorProfile getCurrentColorProfile() {
+        return getColorProfile(
+                mPowerSaveEnabled,
+                mIsBatteryDefender && mDisplayShieldEnabled,
+                mPluggedIn,
+                mLevel <= 20);
+    }
+
+    /** pure function to compute the correct color profile for our battery icon */
+    private ColorProfile getColorProfile(
+            boolean isPowerSave,
+            boolean isBatteryDefender,
+            boolean isCharging,
+            boolean isLowBattery
+    ) {
+        if (isCharging)  return ColorProfile.Active;
+        if (isPowerSave) return ColorProfile.Warning;
+        if (isBatteryDefender) return ColorProfile.None;
+        if (isLowBattery) return ColorProfile.Error;
+
+        return ColorProfile.None;
+    }
+
     void onPowerSaveChanged(boolean isPowerSave) {
         if (isPowerSave == mPowerSaveEnabled) {
             return;
@@ -293,7 +320,7 @@
                     new BatteryDrawableState(
                             mUnifiedBatteryState.getLevel(),
                             mUnifiedBatteryState.getShowPercent(),
-                            mUnifiedBatteryState.getShowErrorState(),
+                            getCurrentColorProfile(),
                             getBatteryAttribution(isCharging())
                     )
             );
@@ -318,7 +345,7 @@
                     new BatteryDrawableState(
                             mUnifiedBatteryState.getLevel(),
                             mUnifiedBatteryState.getShowPercent(),
-                            mUnifiedBatteryState.getShowErrorState(),
+                            getCurrentColorProfile(),
                             getBatteryAttribution(isCharging())
                     )
             );
@@ -334,7 +361,7 @@
                         new BatteryDrawableState(
                                 mUnifiedBatteryState.getLevel(),
                                 mUnifiedBatteryState.getShowPercent(),
-                                mUnifiedBatteryState.getShowErrorState(),
+                                getCurrentColorProfile(),
                                 getBatteryAttribution(isCharging())
                         )
                 );
@@ -522,7 +549,7 @@
                 new BatteryDrawableState(
                         mUnifiedBatteryState.getLevel(),
                         shouldShow,
-                        mUnifiedBatteryState.getShowErrorState(),
+                        mUnifiedBatteryState.getColor(),
                         mUnifiedBatteryState.getAttribution()
                 )
         );
@@ -755,6 +782,9 @@
         pw.println("    mPluggedIn: " + mPluggedIn);
         pw.println("    mLevel: " + mLevel);
         pw.println("    mMode: " + mShowPercentMode);
+        if (newStatusBarIcons()) {
+            pw.println("    mUnifiedBatteryState: " + mUnifiedBatteryState);
+        }
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryDrawableState.kt b/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryDrawableState.kt
index e172cad..9f594fe 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryDrawableState.kt
+++ b/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryDrawableState.kt
@@ -20,6 +20,21 @@
 import android.graphics.drawable.Drawable
 
 /**
+ * States that might set a color profile (e.g., red for low battery) and are mutually exclusive.
+ * This enum allows us to address which colors we want to use based on their function.
+ */
+enum class ColorProfile {
+    // Grayscale is the default color
+    None,
+    // Green for e.g., charging
+    Active,
+    // Yellow for e.g., battery saver
+    Warning,
+    // Red for e.g., low battery
+    Error,
+}
+
+/**
  * Encapsulates all drawing information needed by BatteryMeterDrawable to render properly. Rendered
  * state will be equivalent to the most recent state passed in.
  */
@@ -28,12 +43,9 @@
     val level: Int,
     /** Whether or not to render the percent as a foreground text layer */
     val showPercent: Boolean,
-    /**
-     * In an error state, the drawable will use the error colors and removes the third layer. If
-     * [showPercent] is false, then the fill will be rendered in the foreground error color. Else
-     * the fill is not rendered.
-     */
-    val showErrorState: Boolean,
+
+    /** Set the [ColorProfile] to get the appropriate fill colors */
+    val color: ColorProfile = ColorProfile.None,
 
     /**
      * An attribution is a drawable that shows either alongside the percent, or centered in the
@@ -59,7 +71,6 @@
             BatteryDrawableState(
                 level = 50,
                 showPercent = false,
-                showErrorState = false,
                 attribution = null,
             )
     }
@@ -82,12 +93,14 @@
      */
     val fillOnly: Int
 
-    /** Error colors are used for low battery states typically */
-    val errorForeground: Int
-    val errorBackground: Int
+    /** Used when charging */
+    val activeFill: Int
 
-    /** Currently unused */
-    val warnBackground: Int
+    /** Warning color is used for battery saver mode */
+    val warnFill: Int
+
+    /** Error colors are used for low battery states typically */
+    val errorFill: Int
 
     /** Color scheme appropriate for light mode (dark icons) */
     data object LightThemeColors : BatteryColors {
@@ -95,18 +108,17 @@
         // 22% alpha white
         override val bg: Int = Color.valueOf(1f, 1f, 1f, 0.22f).toArgb()
 
+        // GM Gray 500
+        override val fill = Color.parseColor("#9AA0A6")
         // GM Gray 600
-        override val fill = Color.parseColor("#80868B")
-        // GM Gray 700
-        override val fillOnly = Color.parseColor("#5F6368")
+        override val fillOnly = Color.parseColor("#80868B")
 
-        // GM Red 600
-        override val errorForeground = Color.parseColor("#D93025")
-        // GM Red 100
-        override val errorBackground = Color.parseColor("#FAD2CF")
-
+        // GM Green 500
+        override val activeFill = Color.parseColor("#34A853")
         // GM Yellow 500
-        override val warnBackground = Color.parseColor("#FBBC04")
+        override val warnFill = Color.parseColor("#FBBC04")
+        // GM Red 500
+        override val errorFill = Color.parseColor("#EA4335")
     }
 
     /** Color scheme appropriate for dark mode (light icons) */
@@ -120,12 +132,12 @@
         // GM Gray 400
         override val fillOnly = Color.parseColor("#BDC1C6")
 
-        // GM Red 600
-        override val errorForeground = Color.parseColor("#D93025")
-        // GM Red 200
-        override val errorBackground = Color.parseColor("#F6AEA9")
-        // GM Yellow
-        override val warnBackground = Color.parseColor("#FBBC04")
+        // GM Green 700
+        override val activeFill = Color.parseColor("#188038")
+        // GM Yellow 700
+        override val warnFill = Color.parseColor("#F29900")
+        // GM Red 700
+        override val errorFill = Color.parseColor("#C5221F")
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryFillDrawable.kt b/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryFillDrawable.kt
index e1ae498..63ff6cb 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryFillDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryFillDrawable.kt
@@ -44,6 +44,29 @@
     private var scaledLeftOffset = 0f
     private var scaledRightInset = 0f
 
+    /** Scale this to the viewport so we fill correctly! */
+    private val fillRectNotScaled = RectF()
+    private var leftInsetNotScaled = 0f
+    private var rightInsetNotScaled = 0f
+
+    /**
+     * Configure how much space between the battery frame (drawn at 1.5dp stroke width) and the
+     * inner fill. This is accomplished by tracing the exact same path as the frame, but using
+     * [BlendMode.CLEAR] as the blend mode.
+     *
+     * This value also affects the overall width of the fill, so it requires us to re-draw
+     * everything
+     */
+    var fillInsetAmount = -1f
+        set(value) {
+            if (field != value) {
+                field = value
+                updateInsets()
+                updateScale()
+                invalidateSelf()
+            }
+        }
+
     // Drawable.level cannot be overloaded
     var batteryLevel = 0
         set(value) {
@@ -87,15 +110,32 @@
         updateScale()
     }
 
+    /**
+     * To support dynamic insets, we have to keep mutable references to the left/right unscaled
+     * insets, as well as the fill rect.
+     */
+    private fun updateInsets() {
+        leftInsetNotScaled = LeftFillOffsetExcludingPadding + fillInsetAmount
+        rightInsetNotScaled = RightFillInsetExcludingPadding + fillInsetAmount
+
+        fillRectNotScaled.set(
+            leftInsetNotScaled,
+            0f,
+            Metrics.ViewportWidth - rightInsetNotScaled,
+            Metrics.ViewportHeight
+        )
+    }
+
     private fun updateScale() {
         framePath.transform(/* matrix = */ scaleMatrix, /* dst = */ scaledPath)
-        scaleMatrix.mapRect(/* dst = */ scaledFillRect, /* src = */ FillRect)
+        scaleMatrix.mapRect(/* dst = */ scaledFillRect, /* src = */ fillRectNotScaled)
 
-        scaledLeftOffset = LeftFillOffset * hScale
-        scaledRightInset = RightFillInset * hScale
+        scaledLeftOffset = leftInsetNotScaled * hScale
+        scaledRightInset = rightInsetNotScaled * hScale
 
-        // Ensure 0.5dp space between the frame stroke and the fill
-        clearPaint.strokeWidth = 2.5f * hScale
+        // stroke width = 1.5 (same as the outer frame) + 2x fillInsetAmount, since N px of padding
+        // requires the entire stroke to be 2N px wider
+        clearPaint.strokeWidth = (1.5f + 2 * fillInsetAmount) * hScale
     }
 
     override fun draw(canvas: Canvas) {
@@ -157,23 +197,13 @@
     override fun setAlpha(alpha: Int) {}
 
     companion object {
-        // 4f =
+        // 3.5f =
         //       2.75 (left-most edge of the frame path)
         //     + 0.75 (1/2 of the stroke width)
-        //     + 0.5  (padding between stroke and fill edge)
-        private const val LeftFillOffset = 4f
+        private const val LeftFillOffsetExcludingPadding = 3.5f
 
-        // 2, calculated the same way, but from the right edge (without the battery cap), which
+        // 1.5, calculated the same way, but from the right edge (without the battery cap), which
         // consumes 2 units of width.
-        private const val RightFillInset = 2f
-
-        /** Scale this to the viewport so we fill correctly! */
-        private val FillRect =
-            RectF(
-                LeftFillOffset,
-                0f,
-                Metrics.ViewportWidth - RightFillInset,
-                Metrics.ViewportHeight
-            )
+        private const val RightFillInsetExcludingPadding = 1.5f
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryLayersDrawable.kt b/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryLayersDrawable.kt
index 706b9ec..a179c35 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryLayersDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/battery/unified/BatteryLayersDrawable.kt
@@ -56,9 +56,6 @@
  *          - The internal space is divided into 12x10 and 6x6 rectangles
  *          - The attribution is aligned left
  *          - The percent text is scaled based on the number of characters (1,2, or 3) in the string
- *
- * When [BatteryDrawableState.showErrorState] is true, we will only show either the percent text OR
- * the battery fill, in order to maximize contrast when using the error colors.
  */
 @Suppress("RtlHardcoded")
 class BatteryLayersDrawable(
@@ -91,7 +88,7 @@
     var colors: BatteryColors = BatteryColors.LightThemeColors
         set(value) {
             field = value
-            updateColors(batteryState.showErrorState, value)
+            updateColorProfile(batteryState.hasForegroundContent(), batteryState.color, value)
         }
 
     init {
@@ -101,53 +98,66 @@
     }
 
     private fun handleUpdateState(old: BatteryDrawableState, new: BatteryDrawableState) {
-        if (new.showErrorState != old.showErrorState) {
-            updateColors(new.showErrorState, colors)
-        }
-
         if (new.level != old.level) {
             fill.batteryLevel = new.level
             textOnly.batteryLevel = new.level
             spaceSharingText.batteryLevel = new.level
         }
 
+        val shouldUpdateColors =
+            new.color != old.color ||
+                new.attribution != attribution.drawable ||
+                new.hasForegroundContent() != old.hasForegroundContent()
+
         if (new.attribution != null && new.attribution != attribution.drawable) {
             attribution.drawable = new.attribution
-            updateColors(new.showErrorState, colors)
         }
 
         if (new.hasForegroundContent() != old.hasForegroundContent()) {
-            setFillColor(new.hasForegroundContent(), new.showErrorState, colors)
+            setFillInsets(new.hasForegroundContent())
+        }
+
+        // Finally, update colors last if any of the above conditions were met, so that everything
+        // is properly tinted
+        if (shouldUpdateColors) {
+            updateColorProfile(new.hasForegroundContent(), new.color, colors)
         }
     }
 
-    /** In error states, we don't draw fill unless there is no foreground content (e.g., percent) */
-    private fun updateColors(showErrorState: Boolean, colorInfo: BatteryColors) {
-        frameBg.setTint(if (showErrorState) colorInfo.errorBackground else colorInfo.bg)
-        frame.setTint(colorInfo.fg)
-        attribution.setTint(if (showErrorState) colorInfo.errorForeground else colorInfo.fg)
-        textOnly.setTint(if (showErrorState) colorInfo.errorForeground else colorInfo.fg)
-        spaceSharingText.setTint(if (showErrorState) colorInfo.errorForeground else colorInfo.fg)
-        setFillColor(batteryState.hasForegroundContent(), showErrorState, colorInfo)
-    }
-
-    /**
-     * If there is a foreground layer, then we draw the fill with the low opacity
-     * [BatteryColors.fill] color. Otherwise, if there is no other foreground layer, we will use
-     * either the error or fillOnly colors for more contrast
-     */
-    private fun setFillColor(
+    private fun updateColorProfile(
         hasFg: Boolean,
-        error: Boolean,
+        color: ColorProfile,
         colorInfo: BatteryColors,
     ) {
-        if (hasFg) {
-            fill.fillColor = colorInfo.fill
-        } else {
-            fill.fillColor = if (error) colorInfo.errorForeground else colorInfo.fillOnly
+        frame.setTint(colorInfo.fg)
+        frameBg.setTint(colorInfo.bg)
+        textOnly.setTint(colorInfo.fg)
+        spaceSharingText.setTint(colorInfo.fg)
+        attribution.setTint(colorInfo.fg)
+
+        when (color) {
+            ColorProfile.None -> {
+                fill.fillColor = if (hasFg) colorInfo.fill else colorInfo.fillOnly
+            }
+            ColorProfile.Active -> {
+                fill.fillColor = colorInfo.activeFill
+            }
+            ColorProfile.Warning -> {
+                fill.fillColor = colorInfo.warnFill
+            }
+            ColorProfile.Error -> {
+                fill.fillColor = colorInfo.errorFill
+            }
         }
     }
 
+    private fun setFillInsets(
+        hasFg: Boolean,
+    ) {
+        // Extra padding around the fill if there is nothing in the foreground
+        fill.fillInsetAmount = if (hasFg) 0f else 1.5f
+    }
+
     override fun onBoundsChange(bounds: Rect) {
         super.onBoundsChange(bounds)
 
@@ -200,10 +210,9 @@
         // 2. Then the frame itself
         frame.draw(canvas)
 
-        // 3. Fill it the appropriate amount if non-error state or error + no attribute
-        if (!batteryState.showErrorState || !batteryState.hasForegroundContent()) {
-            fill.draw(canvas)
-        }
+        // 3. Fill it the appropriate amount
+        fill.draw(canvas)
+
         // 4. Decide what goes inside
         if (batteryState.showPercent && batteryState.attribution != null) {
             // 4a. percent & attribution. Implies space-sharing
@@ -309,6 +318,7 @@
          *
          * See [BatteryDrawableState] for how to set the properties of the resulting class
          */
+        @Suppress("UseCompatLoadingForDrawables")
         fun newBatteryDrawable(
             context: Context,
             initialState: BatteryDrawableState = BatteryDrawableState.DefaultInitialState,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 2c3ebe9..b25c3da 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -400,14 +400,22 @@
         if (!mOverlayParams.equals(overlayParams)) {
             mOverlayParams = overlayParams;
 
-            final boolean wasShowingAlternateBouncer = mAlternateBouncerInteractor.isVisibleState();
-
-            // When the bounds change it's always necessary to re-create the overlay's window with
-            // new LayoutParams. If the overlay needs to be shown, this will re-create and show the
-            // overlay with the updated LayoutParams. Otherwise, the overlay will remain hidden.
-            redrawOverlay();
-            if (wasShowingAlternateBouncer) {
-                mKeyguardViewManager.showBouncer(true);
+            if (DeviceEntryUdfpsRefactor.isEnabled()) {
+                if (mOverlay != null && mOverlay.getRequestReason() == REASON_AUTH_KEYGUARD) {
+                    mOverlay.updateOverlayParams(mOverlayParams);
+                } else {
+                    redrawOverlay();
+                }
+            } else {
+                final boolean wasShowingAlternateBouncer =
+                        mAlternateBouncerInteractor.isVisibleState();
+                // When the bounds change it's always to re-create the overlay's window with new
+                // LayoutParams. If the overlay needs to be shown, this will re-create and show the
+                // overlay with the updated LayoutParams. Otherwise, the overlay will remain hidden.
+                redrawOverlay();
+                if (wasShowingAlternateBouncer) {
+                    mKeyguardViewManager.showBouncer(true);
+                }
             }
         }
     }
@@ -850,7 +858,6 @@
 
         mOverlay = null;
         mOrientationListener.disable();
-
     }
 
     private void unconfigureDisplay(View view) {
@@ -859,7 +866,7 @@
         }
         if (DeviceEntryUdfpsRefactor.isEnabled()) {
             if (mUdfpsDisplayMode != null) {
-                mUdfpsDisplayMode.disable(null); // beverlt
+                mUdfpsDisplayMode.disable(null);
             }
         } else {
             if (view != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
index 16865ca..3a45db1 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
@@ -318,6 +318,15 @@
         addViewRunnable = null
     }
 
+    fun updateOverlayParams(updatedOverlayParams: UdfpsOverlayParams) {
+        DeviceEntryUdfpsRefactor.isUnexpectedlyInLegacyMode()
+        overlayParams = updatedOverlayParams
+        sensorBounds = updatedOverlayParams.sensorBounds
+        getTouchOverlay()?.let {
+            windowManager.updateViewLayout(it, coreLayoutParams.updateDimensions(null))
+        }
+    }
+
     fun inflateUdfpsAnimation(
         view: UdfpsView,
         controller: UdfpsController
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
index 5ae2ff0..3112b67 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractor.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.biometrics.domain.interactor
 
 import android.content.Context
+import android.graphics.Rect
 import android.hardware.biometrics.SensorLocationInternal
 import com.android.systemui.biometrics.data.repository.FingerprintPropertyRepository
 import com.android.systemui.biometrics.shared.model.SensorLocation
@@ -43,6 +44,7 @@
     repository: FingerprintPropertyRepository,
     configurationInteractor: ConfigurationInteractor,
     displayStateInteractor: DisplayStateInteractor,
+    udfpsOverlayInteractor: UdfpsOverlayInteractor,
 ) {
     val propertiesInitialized: StateFlow<Boolean> = repository.propertiesInitialized
     val isUdfps: StateFlow<Boolean> =
@@ -103,4 +105,13 @@
             sensorLocation.scale = scale
             sensorLocation
         }
+
+    /**
+     * Sensor location for the:
+     * - current physical display
+     * - current screen resolution
+     * - device's current orientation
+     */
+    val udfpsSensorBounds: Flow<Rect> =
+        udfpsOverlayInteractor.udfpsOverlayParams.map { it.sensorBounds }.distinctUntilChanged()
 }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt
index 88aef56..7ccac03 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricCustomizedViewBinder.kt
@@ -31,18 +31,19 @@
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup.LayoutParams.MATCH_PARENT
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
 import android.view.ViewTreeObserver
 import android.widget.Button
 import android.widget.LinearLayout
 import android.widget.Space
 import android.widget.TextView
-import androidx.lifecycle.lifecycleScope
 import com.android.settingslib.Utils
 import com.android.systemui.biometrics.ui.BiometricPromptLayout
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.res.R
 import kotlin.math.ceil
-import kotlinx.coroutines.launch
+
+private const val TAG = "BiometricCustomizedViewBinder"
 
 /** Sub-binder for [BiometricPromptLayout.customized_view_container]. */
 object BiometricCustomizedViewBinder {
@@ -52,21 +53,20 @@
         legacyCallback: Spaghetti.Callback
     ) {
         customizedViewContainer.repeatWhenAttached { containerView ->
-            lifecycleScope.launch {
-                if (contentView == null) {
-                    containerView.visibility = View.GONE
-                    return@launch
-                }
+            if (contentView == null) {
+                containerView.visibility = View.GONE
+                return@repeatWhenAttached
+            }
 
-                containerView.width { containerWidth ->
-                    if (containerWidth == 0) {
-                        return@width
-                    }
-                    (containerView as LinearLayout).addView(
-                        contentView.toView(containerView.context, containerWidth, legacyCallback)
-                    )
-                    containerView.visibility = View.VISIBLE
+            containerView.width { containerWidth ->
+                if (containerWidth == 0) {
+                    return@width
                 }
+                (containerView as LinearLayout).addView(
+                    contentView.toView(containerView.context, containerWidth, legacyCallback),
+                    LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
+                )
+                containerView.visibility = View.VISIBLE
             }
         }
     }
@@ -118,50 +118,41 @@
     containerViewWidth: Int
 ): View {
     val inflater = LayoutInflater.from(context)
-    val resources = context.resources
+    context.resources
     val contentView =
         inflater.inflateContentView(
             R.layout.biometric_prompt_vertical_list_content_layout,
             description
         )
+    val listItemsToShow = ArrayList<PromptContentItem>(listItems)
     // Show two column by default, once there is an item exceeding max lines, show single
     // item instead.
     val showTwoColumn =
-        listItems.all { !it.doesExceedMaxLinesIfTwoColumn(context, containerViewWidth) }
-    var currRowView = createNewRowLayout(inflater)
-    for (item in listItems) {
-        val itemView = item.toView(context, inflater)
-        // If this item will be in the first row (contentView only has description view) and
-        // description is empty, remove top padding of this item.
-        if (contentView.childCount == 1 && description.isNullOrEmpty()) {
-            itemView.setPadding(
-                itemView.paddingLeft,
-                0,
-                itemView.paddingRight,
-                itemView.paddingBottom
-            )
-        }
-        currRowView.addView(itemView)
-
-        // If this is the first item in the current row, add space behind it.
-        if (currRowView.childCount == 1 && showTwoColumn) {
-            currRowView.addSpaceView(
-                resources.getDimensionPixelSize(
-                    R.dimen.biometric_prompt_content_space_width_between_items
-                ),
-                MATCH_PARENT
-            )
-        }
-
-        // If there are already two items (plus the space view) in the current row, or it
-        // should be one column, start a new row
-        if (currRowView.childCount == 3 || !showTwoColumn) {
-            contentView.addView(currRowView)
-            currRowView = createNewRowLayout(inflater)
-        }
+        listItemsToShow.all { !it.doesExceedMaxLinesIfTwoColumn(context, containerViewWidth) }
+    // If should show two columns and there are more than one items, make listItems always have odd
+    // number items.
+    if (showTwoColumn && listItemsToShow.size > 1 && listItemsToShow.size % 2 == 1) {
+        listItemsToShow.add(dummyItem())
     }
-    if (currRowView.childCount > 0) {
-        contentView.addView(currRowView)
+    var currRow = createNewRowLayout(inflater)
+    for (i in 0 until listItemsToShow.size) {
+        val item = listItemsToShow[i]
+        val itemView = item.toView(context, inflater)
+        contentView.removeTopPaddingForFirstRow(description, itemView)
+
+        // If there should be two column, and there is already one item in the current row, add
+        // space between two items.
+        if (showTwoColumn && currRow.childCount == 1) {
+            currRow.addSpaceViewBetweenListItem()
+        }
+        currRow.addView(itemView)
+
+        // If there should be one column, or there are already two items (plus the space view) in
+        // the current row, or it's already the last item, start a new row
+        if (!showTwoColumn || currRow.childCount == 3 || i == listItemsToShow.size - 1) {
+            contentView.addView(currRow)
+            currRow = createNewRowLayout(inflater)
+        }
     }
     return contentView
 }
@@ -170,10 +161,6 @@
     return inflater.inflate(R.layout.biometric_prompt_content_row_layout, null) as LinearLayout
 }
 
-private fun LinearLayout.addSpaceView(width: Int, height: Int) {
-    addView(Space(context), LinearLayout.LayoutParams(width, height))
-}
-
 private fun PromptContentItem.doesExceedMaxLinesIfTwoColumn(
     context: Context,
     containerViewWidth: Int,
@@ -194,7 +181,10 @@
             val contentViewPadding =
                 resources.getDimensionPixelSize(R.dimen.biometric_prompt_content_padding_horizontal)
             val listItemPadding = getListItemPadding(resources)
-            val maxWidth = containerViewWidth / 2 - contentViewPadding - listItemPadding
+            var maxWidth = containerViewWidth / 2 - contentViewPadding - listItemPadding
+            // Reduce maxWidth a bit since paint#measureText is not accurate. See b/330909104 for
+            // more context.
+            maxWidth -= contentViewPadding / 2
 
             val paint = TextPaint()
             val attributes =
@@ -224,6 +214,7 @@
     inflater: LayoutInflater,
 ): TextView {
     val resources = context.resources
+    // Somehow xml layout params settings doesn't work, set it again here.
     val textView =
         inflater.inflate(R.layout.biometric_prompt_content_row_item_text_view, null) as TextView
     val lp = LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1f)
@@ -251,6 +242,29 @@
     return textView
 }
 
+/* [contentView] function */
+private fun LinearLayout.addSpaceViewBetweenListItem() =
+    addView(
+        Space(context),
+        LinearLayout.LayoutParams(
+            resources.getDimensionPixelSize(
+                R.dimen.biometric_prompt_content_space_width_between_items
+            ),
+            MATCH_PARENT
+        )
+    )
+
+/* [contentView] function*/
+private fun LinearLayout.removeTopPaddingForFirstRow(description: String?, itemView: TextView) {
+    // If this item will be in the first row (contentView only has description view and
+    // description is empty), remove top padding of this item.
+    if (description.isNullOrEmpty() && childCount == 1) {
+        itemView.setPadding(itemView.paddingLeft, 0, itemView.paddingRight, itemView.paddingBottom)
+    }
+}
+
+private fun dummyItem(): PromptContentItem = PromptContentItemPlainText("")
+
 private fun PromptContentItem.getListItemPadding(resources: Resources): Int {
     var listItemPadding =
         resources.getDimensionPixelSize(
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
index b2ade4f..76d46ed 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewBinder.kt
@@ -288,12 +288,14 @@
                 // set padding
                 launch {
                     viewModel.promptPadding.collect { promptPadding ->
-                        view.setPadding(
-                            promptPadding.left,
-                            promptPadding.top,
-                            promptPadding.right,
-                            promptPadding.bottom
-                        )
+                        if (!constraintBp()) {
+                            view.setPadding(
+                                promptPadding.left,
+                                promptPadding.top,
+                                promptPadding.right,
+                                promptPadding.bottom
+                            )
+                        }
                     }
                 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
index e3c0cba..f380746 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/BiometricViewSizeBinder.kt
@@ -20,7 +20,6 @@
 import android.animation.AnimatorSet
 import android.animation.ValueAnimator
 import android.graphics.Outline
-import android.graphics.Rect
 import android.transition.AutoTransition
 import android.transition.TransitionManager
 import android.util.TypedValue
@@ -47,17 +46,14 @@
 import com.android.systemui.biometrics.ui.viewmodel.PromptPosition
 import com.android.systemui.biometrics.ui.viewmodel.PromptSize
 import com.android.systemui.biometrics.ui.viewmodel.PromptViewModel
-import com.android.systemui.biometrics.ui.viewmodel.isBottom
 import com.android.systemui.biometrics.ui.viewmodel.isLarge
 import com.android.systemui.biometrics.ui.viewmodel.isLeft
 import com.android.systemui.biometrics.ui.viewmodel.isMedium
 import com.android.systemui.biometrics.ui.viewmodel.isNullOrNotSmall
-import com.android.systemui.biometrics.ui.viewmodel.isRight
 import com.android.systemui.biometrics.ui.viewmodel.isSmall
-import com.android.systemui.biometrics.ui.viewmodel.isTop
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.res.R
-import kotlin.math.min
+import kotlin.math.abs
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.launch
 
@@ -97,8 +93,6 @@
         if (constraintBp()) {
             val leftGuideline = view.requireViewById<Guideline>(R.id.leftGuideline)
             val rightGuideline = view.requireViewById<Guideline>(R.id.rightGuideline)
-            val bottomGuideline = view.requireViewById<Guideline>(R.id.bottomGuideline)
-            val topGuideline = view.requireViewById<Guideline>(R.id.topGuideline)
             val midGuideline = view.findViewById<Guideline>(R.id.midGuideline)
 
             val iconHolderView = view.requireViewById<View>(R.id.biometric_icon)
@@ -121,165 +115,12 @@
 
             val largeConstraintSet = ConstraintSet()
             largeConstraintSet.clone(mediumConstraintSet)
+            largeConstraintSet.constrainMaxWidth(R.id.panel, view.width)
 
             // TODO: Investigate better way to handle 180 rotations
             val flipConstraintSet = ConstraintSet()
-            flipConstraintSet.clone(mediumConstraintSet)
-            flipConstraintSet.connect(
-                R.id.scrollView,
-                ConstraintSet.START,
-                R.id.midGuideline,
-                ConstraintSet.START
-            )
-            flipConstraintSet.connect(
-                R.id.scrollView,
-                ConstraintSet.END,
-                R.id.rightGuideline,
-                ConstraintSet.END
-            )
-            flipConstraintSet.setHorizontalBias(R.id.biometric_icon, .2f)
-
-            // Round the panel outline
-            panelView.outlineProvider =
-                object : ViewOutlineProvider() {
-                    override fun getOutline(view: View, outline: Outline) {
-                        outline.setRoundRect(
-                            0,
-                            0,
-                            view.width,
-                            view.height + cornerRadiusPx,
-                            cornerRadiusPx.toFloat()
-                        )
-                    }
-                }
 
             view.doOnLayout {
-                val windowBounds = windowManager.maximumWindowMetrics.bounds
-                val bottomInset =
-                    windowManager.maximumWindowMetrics.windowInsets
-                        .getInsets(WindowInsets.Type.navigationBars())
-                        .bottom
-
-                // TODO: Move to viewmodel
-                fun measureBounds(position: PromptPosition) {
-                    val density = windowManager.currentWindowMetrics.density
-                    val width = min((640 * density).toInt(), windowBounds.width())
-
-                    var left = -1
-                    var right = -1
-                    var bottom = -1
-                    var mid = -1
-
-                    when {
-                        position.isTop -> {
-                            // Round bottom corners
-                            panelView.outlineProvider =
-                                object : ViewOutlineProvider() {
-                                    override fun getOutline(view: View, outline: Outline) {
-                                        outline.setRoundRect(
-                                            0,
-                                            -cornerRadiusPx,
-                                            view.width,
-                                            view.height,
-                                            cornerRadiusPx.toFloat()
-                                        )
-                                    }
-                                }
-                            left = windowBounds.centerX() - width / 2 + viewModel.promptMargin
-                            right = windowBounds.centerX() - width / 2 + viewModel.promptMargin
-                            bottom = iconHolderView.centerY() * 2 - iconHolderView.centerY() / 4
-                        }
-                        position.isBottom -> {
-                            // Round top corners
-                            panelView.outlineProvider =
-                                object : ViewOutlineProvider() {
-                                    override fun getOutline(view: View, outline: Outline) {
-                                        outline.setRoundRect(
-                                            0,
-                                            0,
-                                            view.width,
-                                            view.height + cornerRadiusPx,
-                                            cornerRadiusPx.toFloat()
-                                        )
-                                    }
-                                }
-
-                            left = windowBounds.centerX() - width / 2
-                            right = windowBounds.centerX() - width / 2
-                            bottom = if (view.isLandscape()) bottomInset else 0
-                        }
-                        position.isLeft -> {
-                            // Round right corners
-                            panelView.outlineProvider =
-                                object : ViewOutlineProvider() {
-                                    override fun getOutline(view: View, outline: Outline) {
-                                        outline.setRoundRect(
-                                            -cornerRadiusPx,
-                                            0,
-                                            view.width,
-                                            view.height,
-                                            cornerRadiusPx.toFloat()
-                                        )
-                                    }
-                                }
-
-                            left = 0
-                            mid = (windowBounds.width() * .85).toInt() / 2
-                            right = windowBounds.width() - (windowBounds.width() * .85).toInt()
-                            bottom = if (view.isLandscape()) bottomInset else 0
-                        }
-                        position.isRight -> {
-                            // Round left corners
-                            panelView.outlineProvider =
-                                object : ViewOutlineProvider() {
-                                    override fun getOutline(view: View, outline: Outline) {
-                                        outline.setRoundRect(
-                                            0,
-                                            0,
-                                            view.width + cornerRadiusPx,
-                                            view.height,
-                                            cornerRadiusPx.toFloat()
-                                        )
-                                    }
-                                }
-
-                            left = windowBounds.width() - (windowBounds.width() * .85).toInt()
-                            right = 0
-                            bottom = if (view.isLandscape()) bottomInset else 0
-                            mid = windowBounds.width() - (windowBounds.width() * .85).toInt() / 2
-                        }
-                    }
-
-                    val bounds = Rect(left, mid, right, bottom)
-                    if (bounds.shouldAdjustLeftGuideline()) {
-                        leftGuideline.setGuidelineBegin(bounds.left)
-                        smallConstraintSet.setGuidelineBegin(leftGuideline.id, bounds.left)
-                        mediumConstraintSet.setGuidelineBegin(leftGuideline.id, bounds.left)
-                    }
-                    if (bounds.shouldAdjustRightGuideline()) {
-                        rightGuideline.setGuidelineEnd(bounds.right)
-                        smallConstraintSet.setGuidelineEnd(rightGuideline.id, bounds.right)
-                        mediumConstraintSet.setGuidelineEnd(rightGuideline.id, bounds.right)
-                    }
-                    if (bounds.shouldAdjustBottomGuideline()) {
-                        bottomGuideline.setGuidelineEnd(bounds.bottom)
-                        smallConstraintSet.setGuidelineEnd(bottomGuideline.id, bounds.bottom)
-                        mediumConstraintSet.setGuidelineEnd(bottomGuideline.id, bounds.bottom)
-                    }
-
-                    if (position.isBottom) {
-                        topGuideline.setGuidelinePercent(.25f)
-                        mediumConstraintSet.setGuidelinePercent(topGuideline.id, .25f)
-                    } else {
-                        topGuideline.setGuidelinePercent(0f)
-                        mediumConstraintSet.setGuidelinePercent(topGuideline.id, 0f)
-                    }
-
-                    if (mid != -1 && midGuideline != null) {
-                        midGuideline.setGuidelineBegin(mid)
-                    }
-                }
-
                 fun setVisibilities(size: PromptSize) {
                     viewsToHideWhenSmall.forEach { it.showContentOrHide(forceHide = size.isSmall) }
                     largeConstraintSet.setVisibility(iconHolderView.id, View.GONE)
@@ -297,36 +138,151 @@
                     }
                 }
 
+                fun roundCorners(size: PromptSize, position: PromptPosition) {
+                    var left = 0
+                    var top = 0
+                    var right = 0
+                    var bottom = 0
+                    when (size) {
+                        PromptSize.SMALL,
+                        PromptSize.MEDIUM ->
+                            when (position) {
+                                PromptPosition.Right -> {
+                                    left = 0
+                                    top = 0
+                                    right = view.width + cornerRadiusPx
+                                    bottom = view.height
+                                }
+                                PromptPosition.Left -> {
+                                    left = -cornerRadiusPx
+                                    top = 0
+                                    right = view.width
+                                    bottom = view.height
+                                }
+                                PromptPosition.Top -> {
+                                    left = 0
+                                    top = -cornerRadiusPx
+                                    right = panelView.width
+                                    bottom = view.height
+                                }
+                                PromptPosition.Bottom -> {
+                                    left = 0
+                                    top = 0
+                                    right = panelView.width
+                                    bottom = view.height + cornerRadiusPx
+                                }
+                            }
+                        PromptSize.LARGE -> {
+                            left = 0
+                            top = 0
+                            right = view.width
+                            bottom = view.height
+                        }
+                    }
+
+                    // Round the panel outline
+                    panelView.outlineProvider =
+                        object : ViewOutlineProvider() {
+                            override fun getOutline(view: View, outline: Outline) {
+                                outline.setRoundRect(
+                                    left,
+                                    top,
+                                    right,
+                                    bottom,
+                                    cornerRadiusPx.toFloat()
+                                )
+                            }
+                        }
+                }
+
                 view.repeatWhenAttached {
                     var currentSize: PromptSize? = null
 
                     lifecycleScope.launch {
+                        viewModel.guidelineBounds.collect { bounds ->
+                            if (bounds.left >= 0) {
+                                mediumConstraintSet.setGuidelineBegin(leftGuideline.id, bounds.left)
+                                smallConstraintSet.setGuidelineBegin(leftGuideline.id, bounds.left)
+                            } else if (bounds.left < 0) {
+                                mediumConstraintSet.setGuidelineEnd(
+                                    leftGuideline.id,
+                                    abs(bounds.left)
+                                )
+                                smallConstraintSet.setGuidelineEnd(
+                                    leftGuideline.id,
+                                    abs(bounds.left)
+                                )
+                            }
+
+                            if (bounds.right >= 0) {
+                                mediumConstraintSet.setGuidelineEnd(rightGuideline.id, bounds.right)
+                                smallConstraintSet.setGuidelineEnd(rightGuideline.id, bounds.right)
+                            } else if (bounds.right < 0) {
+                                mediumConstraintSet.setGuidelineBegin(
+                                    rightGuideline.id,
+                                    abs(bounds.right)
+                                )
+                                smallConstraintSet.setGuidelineBegin(
+                                    rightGuideline.id,
+                                    abs(bounds.right)
+                                )
+                            }
+
+                            if (midGuideline != null) {
+                                if (bounds.bottom >= 0) {
+                                    midGuideline.setGuidelineEnd(bounds.bottom)
+                                    mediumConstraintSet.setGuidelineEnd(
+                                        midGuideline.id,
+                                        bounds.bottom
+                                    )
+                                } else if (bounds.bottom < 0) {
+                                    midGuideline.setGuidelineBegin(abs(bounds.bottom))
+                                    mediumConstraintSet.setGuidelineBegin(
+                                        midGuideline.id,
+                                        abs(bounds.bottom)
+                                    )
+                                }
+                            }
+                        }
+                    }
+
+                    lifecycleScope.launch {
                         combine(viewModel.position, viewModel.size, ::Pair).collect {
                             (position, size) ->
                             view.doOnAttach {
+                                setVisibilities(size)
+
                                 if (position.isLeft) {
-                                    flipConstraintSet.applyTo(view)
-                                } else if (position.isRight) {
-                                    mediumConstraintSet.applyTo(view)
+                                    if (size.isSmall) {
+                                        flipConstraintSet.clone(smallConstraintSet)
+                                    } else {
+                                        flipConstraintSet.clone(mediumConstraintSet)
+                                    }
+
+                                    // Move all content to other panel
+                                    flipConstraintSet.connect(
+                                        R.id.scrollView,
+                                        ConstraintSet.START,
+                                        R.id.midGuideline,
+                                        ConstraintSet.START
+                                    )
+                                    flipConstraintSet.connect(
+                                        R.id.scrollView,
+                                        ConstraintSet.END,
+                                        R.id.rightGuideline,
+                                        ConstraintSet.END
+                                    )
                                 }
 
-                                measureBounds(position)
-                                setVisibilities(size)
+                                roundCorners(size, position)
+
                                 when {
                                     size.isSmall -> {
-                                        val ratio =
-                                            if (view.isLandscape()) {
-                                                (windowBounds.height() -
-                                                        bottomInset -
-                                                        viewModel.promptMargin)
-                                                    .toFloat() / windowBounds.height()
-                                            } else {
-                                                (windowBounds.height() - viewModel.promptMargin)
-                                                    .toFloat() / windowBounds.height()
-                                            }
-                                        smallConstraintSet.setVerticalBias(iconHolderView.id, ratio)
-
-                                        smallConstraintSet.applyTo(view as ConstraintLayout?)
+                                        if (position.isLeft) {
+                                            flipConstraintSet.applyTo(view)
+                                        } else {
+                                            smallConstraintSet.applyTo(view)
+                                        }
                                     }
                                     size.isMedium && currentSize.isSmall -> {
                                         val autoTransition = AutoTransition()
@@ -338,7 +294,19 @@
                                             view,
                                             autoTransition
                                         )
-                                        mediumConstraintSet.applyTo(view)
+
+                                        if (position.isLeft) {
+                                            flipConstraintSet.applyTo(view)
+                                        } else {
+                                            mediumConstraintSet.applyTo(view)
+                                        }
+                                    }
+                                    size.isMedium -> {
+                                        if (position.isLeft) {
+                                            flipConstraintSet.applyTo(view)
+                                        } else {
+                                            mediumConstraintSet.applyTo(view)
+                                        }
                                     }
                                     size.isLarge -> {
                                         val autoTransition = AutoTransition()
@@ -551,20 +519,6 @@
         }
 }
 
-private fun View.centerX(): Int {
-    return (x + width / 2).toInt()
-}
-
-private fun View.centerY(): Int {
-    return (y + height / 2).toInt()
-}
-
-private fun Rect.shouldAdjustLeftGuideline(): Boolean = left != -1
-
-private fun Rect.shouldAdjustRightGuideline(): Boolean = right != -1
-
-private fun Rect.shouldAdjustBottomGuideline(): Boolean = bottom != -1
-
 private fun View.asVerticalAnimator(
     duration: Long,
     toY: Float,
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
index d8265c7..66b7d7a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/binder/PromptIconViewBinder.kt
@@ -37,7 +37,6 @@
 import com.android.systemui.util.kotlin.Utils.Companion.toTriple
 import com.android.systemui.util.kotlin.sample
 import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.launch
 
 /** Sub-binder for [BiometricPromptLayout.iconView]. */
@@ -127,14 +126,22 @@
                         if (constraintBp() && position != Rect()) {
                             val iconParams = iconView.layoutParams as ConstraintLayout.LayoutParams
 
-                            if (position.left != -1) {
+                            if (position.left != 0) {
                                 iconParams.endToEnd = ConstraintSet.UNSET
                                 iconParams.leftMargin = position.left
                             }
-                            if (position.top != -1) {
+                            if (position.top != 0) {
                                 iconParams.bottomToBottom = ConstraintSet.UNSET
                                 iconParams.topMargin = position.top
                             }
+                            if (position.right != 0) {
+                                iconParams.startToStart = ConstraintSet.UNSET
+                                iconParams.rightMargin = position.right
+                            }
+                            if (position.bottom != 0) {
+                                iconParams.topToTop = ConstraintSet.UNSET
+                                iconParams.bottomMargin = position.bottom
+                            }
                             iconView.layoutParams = iconParams
                         }
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
index d0c140b..8dbed5f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptIconViewModel.kt
@@ -94,25 +94,76 @@
                     params.naturalDisplayHeight,
                     rotation.ordinal
                 )
-                rotatedBounds
+                Rect(
+                    rotatedBounds.left,
+                    rotatedBounds.top,
+                    params.logicalDisplayWidth - rotatedBounds.right,
+                    params.logicalDisplayHeight - rotatedBounds.bottom
+                )
             }
             .distinctUntilChanged()
 
     val iconPosition: Flow<Rect> =
-        combine(udfpsSensorBounds, promptViewModel.size, promptViewModel.modalities) {
-            sensorBounds,
-            size,
-            modalities ->
-            // If not Udfps, icon does not change from default layout position
-            if (!modalities.hasUdfps) {
-                Rect() // Empty rect, don't offset from default position
-            } else if (size.isSmall) {
-                // When small with Udfps, only set horizontal position
-                Rect(sensorBounds.left, -1, sensorBounds.right, -1)
-            } else {
-                sensorBounds
+        combine(
+                udfpsSensorBounds,
+                promptViewModel.size,
+                promptViewModel.position,
+                promptViewModel.modalities
+            ) { sensorBounds, size, position, modalities ->
+                when (position) {
+                    PromptPosition.Bottom ->
+                        if (size.isSmall) {
+                            Rect(0, 0, 0, promptViewModel.portraitSmallBottomPadding)
+                        } else if (size.isMedium && modalities.hasUdfps) {
+                            Rect(0, 0, 0, sensorBounds.bottom)
+                        } else if (size.isMedium) {
+                            Rect(0, 0, 0, promptViewModel.portraitMediumBottomPadding)
+                        } else {
+                            // Large screen
+                            Rect(0, 0, 0, promptViewModel.portraitLargeScreenBottomPadding)
+                        }
+                    PromptPosition.Right ->
+                        if (size.isSmall || modalities.hasFaceOnly) {
+                            Rect(
+                                0,
+                                0,
+                                promptViewModel.landscapeSmallHorizontalPadding,
+                                promptViewModel.landscapeSmallBottomPadding
+                            )
+                        } else if (size.isMedium && modalities.hasUdfps) {
+                            Rect(0, 0, sensorBounds.right, sensorBounds.bottom)
+                        } else {
+                            // SFPS
+                            Rect(
+                                0,
+                                0,
+                                promptViewModel.landscapeMediumHorizontalPadding,
+                                promptViewModel.landscapeMediumBottomPadding
+                            )
+                        }
+                    PromptPosition.Left ->
+                        if (size.isSmall || modalities.hasFaceOnly) {
+                            Rect(
+                                promptViewModel.landscapeSmallHorizontalPadding,
+                                0,
+                                0,
+                                promptViewModel.landscapeSmallBottomPadding
+                            )
+                        } else if (size.isMedium && modalities.hasUdfps) {
+                            Rect(sensorBounds.left, 0, 0, sensorBounds.bottom)
+                        } else {
+                            // SFPS
+                            Rect(
+                                promptViewModel.landscapeMediumHorizontalPadding,
+                                0,
+                                0,
+                                promptViewModel.landscapeMediumBottomPadding
+                            )
+                        }
+                    PromptPosition.Top -> Rect()
+                }
             }
-        }
+            .distinctUntilChanged()
 
     /** Whether an error message is currently being shown. */
     val showingError = promptViewModel.showingError
@@ -162,10 +213,11 @@
 
     val iconSize: Flow<Pair<Int, Int>> =
         combine(
+            promptViewModel.position,
             activeAuthType,
             promptViewModel.fingerprintSensorWidth,
             promptViewModel.fingerprintSensorHeight,
-        ) { activeAuthType, fingerprintSensorWidth, fingerprintSensorHeight ->
+        ) { _, activeAuthType, fingerprintSensorWidth, fingerprintSensorHeight ->
             if (activeAuthType == AuthType.Face) {
                 Pair(promptViewModel.faceIconWidth, promptViewModel.faceIconHeight)
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
index fbd87fd..21ebff4 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/PromptViewModel.kt
@@ -86,6 +86,36 @@
     val faceIconHeight: Int =
         context.resources.getDimensionPixelSize(R.dimen.biometric_dialog_face_icon_size)
 
+    /** Padding for placing icons */
+    val portraitSmallBottomPadding =
+        context.resources.getDimensionPixelSize(
+            R.dimen.biometric_prompt_portrait_small_bottom_padding
+        )
+    val portraitMediumBottomPadding =
+        context.resources.getDimensionPixelSize(
+            R.dimen.biometric_prompt_portrait_medium_bottom_padding
+        )
+    val portraitLargeScreenBottomPadding =
+        context.resources.getDimensionPixelSize(
+            R.dimen.biometric_prompt_portrait_large_screen_bottom_padding
+        )
+    val landscapeSmallBottomPadding =
+        context.resources.getDimensionPixelSize(
+            R.dimen.biometric_prompt_landscape_small_bottom_padding
+        )
+    val landscapeSmallHorizontalPadding =
+        context.resources.getDimensionPixelSize(
+            R.dimen.biometric_prompt_landscape_small_horizontal_padding
+        )
+    val landscapeMediumBottomPadding =
+        context.resources.getDimensionPixelSize(
+            R.dimen.biometric_prompt_landscape_medium_bottom_padding
+        )
+    val landscapeMediumHorizontalPadding =
+        context.resources.getDimensionPixelSize(
+            R.dimen.biometric_prompt_landscape_medium_horizontal_padding
+        )
+
     val fingerprintSensorWidth: Flow<Int> =
         combine(modalities, udfpsOverlayInteractor.udfpsOverlayParams) { modalities, overlayParams
             ->
@@ -111,9 +141,6 @@
     /** Hint for talkback directional guidance */
     val accessibilityHint: Flow<String> = _accessibilityHint.asSharedFlow()
 
-    val promptMargin: Int =
-        context.resources.getDimensionPixelSize(R.dimen.biometric_dialog_border_padding)
-
     private val _isAuthenticating: MutableStateFlow<Boolean> = MutableStateFlow(false)
 
     /** If the user is currently authenticating (i.e. at least one biometric is scanning). */
@@ -205,6 +232,66 @@
             }
             .distinctUntilChanged()
 
+    /** Prompt panel size padding */
+    private val smallHorizontalGuidelinePadding =
+        context.resources.getDimensionPixelSize(
+            R.dimen.biometric_prompt_small_horizontal_guideline_padding
+        )
+    private val udfpsHorizontalGuidelinePadding =
+        context.resources.getDimensionPixelSize(
+            R.dimen.biometric_prompt_udfps_horizontal_guideline_padding
+        )
+    private val udfpsMidGuidelinePadding =
+        context.resources.getDimensionPixelSize(
+            R.dimen.biometric_prompt_udfps_mid_guideline_padding
+        )
+    private val mediumHorizontalGuidelinePadding =
+        context.resources.getDimensionPixelSize(
+            R.dimen.biometric_prompt_medium_horizontal_guideline_padding
+        )
+    private val mediumMidGuidelinePadding =
+        context.resources.getDimensionPixelSize(
+            R.dimen.biometric_prompt_medium_mid_guideline_padding
+        )
+
+    /**
+     * Rect for positioning prompt guidelines (left, top, right, mid)
+     *
+     * Negative values are used to signify that guideline measuring should be flipped, measuring
+     * from opposite side of the screen
+     */
+    val guidelineBounds: Flow<Rect> =
+        combine(size, position, modalities) { size, position, modalities ->
+                if (position.isBottom) {
+                    Rect(0, 0, 0, 0)
+                } else if (position.isRight) {
+                    if (size.isSmall) {
+                        Rect(-smallHorizontalGuidelinePadding, 0, 0, 0)
+                    } else if (modalities.hasUdfps) {
+                        Rect(udfpsHorizontalGuidelinePadding, 0, 0, udfpsMidGuidelinePadding)
+                    } else if (modalities.isEmpty) {
+                        // TODO: Temporary fix until no biometric landscape layout is added
+                        Rect(-mediumHorizontalGuidelinePadding, 0, 0, 6)
+                    } else {
+                        Rect(-mediumHorizontalGuidelinePadding, 0, 0, mediumMidGuidelinePadding)
+                    }
+                } else if (position.isLeft) {
+                    if (size.isSmall) {
+                        Rect(0, 0, -smallHorizontalGuidelinePadding, 0)
+                    } else if (modalities.hasUdfps) {
+                        Rect(0, 0, udfpsHorizontalGuidelinePadding, -udfpsMidGuidelinePadding)
+                    } else if (modalities.isEmpty) {
+                        // TODO: Temporary fix until no biometric landscape layout is added
+                        Rect(0, 0, -mediumHorizontalGuidelinePadding, -6)
+                    } else {
+                        Rect(0, 0, -mediumHorizontalGuidelinePadding, -mediumMidGuidelinePadding)
+                    }
+                } else {
+                    Rect()
+                }
+            }
+            .distinctUntilChanged()
+
     /**
      * If the API caller or the user's personal preferences require explicit confirmation after
      * successful authentication. Confirmation always required when in explicit flow.
@@ -424,7 +511,7 @@
             isAuthenticated,
             promptSelectorInteractor.isCredentialAllowed,
         ) { size, _, authState, credentialAllowed ->
-            size.isNotSmall && authState.isNotAuthenticated && credentialAllowed
+            size.isMedium && authState.isNotAuthenticated && credentialAllowed
         }
 
     private val history = PromptHistoryImpl()
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt
index cfda75c..b72b1f3 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModel.kt
@@ -28,6 +28,7 @@
 import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION
 import android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY
 import com.airbnb.lottie.model.KeyPath
+import com.android.systemui.Flags.constraintBp
 import com.android.systemui.biometrics.Utils
 import com.android.systemui.biometrics.domain.interactor.BiometricStatusInteractor
 import com.android.systemui.biometrics.domain.interactor.DisplayStateInteractor
@@ -155,17 +156,19 @@
             ->
             val topLeft = Point(sensorLocation.left, sensorLocation.top)
 
-            if (sensorLocation.isSensorVerticalInDefaultOrientation) {
-                if (displayRotation == DisplayRotation.ROTATION_0) {
-                    topLeft.x -= bounds!!.width()
-                } else if (displayRotation == DisplayRotation.ROTATION_270) {
-                    topLeft.y -= bounds!!.height()
-                }
-            } else {
-                if (displayRotation == DisplayRotation.ROTATION_180) {
-                    topLeft.y -= bounds!!.height()
-                } else if (displayRotation == DisplayRotation.ROTATION_270) {
-                    topLeft.x -= bounds!!.width()
+            if (!constraintBp()) {
+                if (sensorLocation.isSensorVerticalInDefaultOrientation) {
+                    if (displayRotation == DisplayRotation.ROTATION_0) {
+                        topLeft.x -= bounds!!.width()
+                    } else if (displayRotation == DisplayRotation.ROTATION_270) {
+                        topLeft.y -= bounds!!.height()
+                    }
+                } else {
+                    if (displayRotation == DisplayRotation.ROTATION_180) {
+                        topLeft.y -= bounds!!.height()
+                    } else if (displayRotation == DisplayRotation.ROTATION_270) {
+                        topLeft.x -= bounds!!.width()
+                    }
                 }
             }
             defaultOverlayViewParams.apply {
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt
index 893887f..d88b3dc 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractor.kt
@@ -45,6 +45,7 @@
 import com.android.systemui.keyguard.data.repository.TrustRepository
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.res.R
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shared.system.SysUiStatsLog
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
@@ -158,6 +159,10 @@
     /** Show the bouncer if necessary and set the relevant states. */
     @JvmOverloads
     fun show(isScrimmed: Boolean) {
+        // When the scene container framework is enabled, instead of calling this, call
+        // SceneInteractor#changeScene(Scenes.Bouncer, ...).
+        SceneContainerFlag.assertInLegacyMode()
+
         if (primaryBouncerView.delegate == null && !Flags.composeBouncer()) {
             Log.d(
                 TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
index f1a0e5e..78811a9 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
@@ -12,14 +12,15 @@
 import com.android.systemui.bouncer.ui.viewmodel.BouncerViewModel
 import com.android.systemui.bouncer.ui.viewmodel.KeyguardBouncerViewModel
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.flags.Flags.COMPOSE_BOUNCER_ENABLED
 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel
 import com.android.systemui.log.BouncerLogger
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
 import dagger.Lazy
 import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 
 /** Helper data class that allows to lazy load all the dependencies of the legacy bouncer. */
+@OptIn(ExperimentalCoroutinesApi::class)
 @SysUISingleton
 data class LegacyBouncerDependencies
 @Inject
@@ -59,7 +60,7 @@
     private val composeBouncerDependencies: Lazy<ComposeBouncerDependencies>,
 ) {
     fun bind(view: ViewGroup) {
-        if (COMPOSE_BOUNCER_ENABLED && composeBouncerFlags.isOnlyComposeBouncerEnabled()) {
+        if (composeBouncerFlags.isOnlyComposeBouncerEnabled()) {
             val deps = composeBouncerDependencies.get()
             ComposeBouncerViewBinder.bind(
                 view,
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
index 62da5c0..12cac92 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/PinBouncerViewModel.kt
@@ -99,7 +99,7 @@
             .map { if (it) ActionButtonAppearance.Hidden else ActionButtonAppearance.Shown }
             .stateIn(
                 scope = viewModelScope,
-                started = SharingStarted.Eagerly,
+                started = SharingStarted.WhileSubscribed(),
                 initialValue = ActionButtonAppearance.Hidden,
             )
 
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/dagger/ScreenBrightnessModule.kt b/packages/SystemUI/src/com/android/systemui/brightness/dagger/ScreenBrightnessModule.kt
new file mode 100644
index 0000000..2b9fc73
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/brightness/dagger/ScreenBrightnessModule.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.dagger
+
+import com.android.systemui.brightness.data.repository.BrightnessPolicyRepository
+import com.android.systemui.brightness.data.repository.BrightnessPolicyRepositoryImpl
+import com.android.systemui.brightness.data.repository.ScreenBrightnessDisplayManagerRepository
+import com.android.systemui.brightness.data.repository.ScreenBrightnessRepository
+import dagger.Binds
+import dagger.Module
+
+@Module
+interface ScreenBrightnessModule {
+
+    @Binds
+    fun bindScreenBrightnessRepository(
+        impl: ScreenBrightnessDisplayManagerRepository
+    ): ScreenBrightnessRepository
+
+    @Binds
+    fun bindPolicyRepository(impl: BrightnessPolicyRepositoryImpl): BrightnessPolicyRepository
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallableFactory.java b/packages/SystemUI/src/com/android/systemui/brightness/data/model/LinearBrightness.kt
similarity index 61%
copy from tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallableFactory.java
copy to packages/SystemUI/src/com/android/systemui/brightness/data/model/LinearBrightness.kt
index b8f9f0e..608f301 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallableFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/brightness/data/model/LinearBrightness.kt
@@ -14,16 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.systemui.brightness.data.model
 
-import com.android.asllib.util.MalformedXmlException;
-
-import org.w3c.dom.Element;
-
-import java.util.List;
-
-public interface AslMarshallableFactory<T extends AslMarshallable> {
-
-    /** Creates an {@link AslMarshallableFactory} from human-readable DOM element */
-    T createFromHrElements(List<Element> elements) throws MalformedXmlException;
+@JvmInline
+value class LinearBrightness(val floatValue: Float) {
+    fun clamp(min: LinearBrightness, max: LinearBrightness): LinearBrightness {
+        return if (floatValue < min.floatValue) {
+            min
+        } else if (floatValue > max.floatValue) {
+            max
+        } else {
+            this
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/data/repository/BrightnessPolicyRepository.kt b/packages/SystemUI/src/com/android/systemui/brightness/data/repository/BrightnessPolicyRepository.kt
new file mode 100644
index 0000000..c018ecb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/brightness/data/repository/BrightnessPolicyRepository.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.data.repository
+
+import android.content.Context
+import android.os.UserManager
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.user.data.repository.UserRepository
+import com.android.systemui.utils.PolicyRestriction
+import com.android.systemui.utils.UserRestrictionChecker
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.mapLatest
+
+/** Checks whether the current user is restricted to change the brightness ([RESTRICTION]) */
+interface BrightnessPolicyRepository {
+
+    /**
+     * Indicates whether the current user is restricted to change the brightness. As there is no way
+     * to determine when a restriction has been added/removed. This value may be fetched eagerly and
+     * not updated (unless the user changes) per flow.
+     */
+    val restrictionPolicy: Flow<PolicyRestriction>
+
+    companion object {
+        const val RESTRICTION = UserManager.DISALLOW_CONFIG_BRIGHTNESS
+    }
+}
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SysUISingleton
+class BrightnessPolicyRepositoryImpl
+@Inject
+constructor(
+    userRepository: UserRepository,
+    private val userRestrictionChecker: UserRestrictionChecker,
+    @Application private val applicationContext: Context,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+) : BrightnessPolicyRepository {
+    override val restrictionPolicy =
+        userRepository.selectedUserInfo
+            .mapLatest { user ->
+                userRestrictionChecker
+                    .checkIfRestrictionEnforced(
+                        applicationContext,
+                        BrightnessPolicyRepository.RESTRICTION,
+                        user.id
+                    )
+                    ?.let { PolicyRestriction.Restricted(it) }
+                    ?: PolicyRestriction.NoRestriction
+            }
+            .flowOn(backgroundDispatcher)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/data/repository/ScreenBrightnessRepository.kt b/packages/SystemUI/src/com/android/systemui/brightness/data/repository/ScreenBrightnessRepository.kt
new file mode 100644
index 0000000..9ed11d1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/brightness/data/repository/ScreenBrightnessRepository.kt
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.data.repository
+
+import android.annotation.SuppressLint
+import android.hardware.display.BrightnessInfo
+import android.hardware.display.DisplayManager
+import com.android.systemui.brightness.data.model.LinearBrightness
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.DisplayId
+import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.shareIn
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+/**
+ * Repository for tracking brightness in the current display.
+ *
+ * Values are in a linear space, as used by [DisplayManager].
+ */
+interface ScreenBrightnessRepository {
+    /** Current brightness as a value between [minLinearBrightness] and [maxLinearBrightness] */
+    val linearBrightness: Flow<LinearBrightness>
+
+    /** Current minimum value for the brightness */
+    val minLinearBrightness: Flow<LinearBrightness>
+
+    /** Current maximum value for the brightness */
+    val maxLinearBrightness: Flow<LinearBrightness>
+
+    /** Gets the current values for min and max brightness */
+    suspend fun getMinMaxLinearBrightness(): Pair<LinearBrightness, LinearBrightness>
+
+    /**
+     * Sets the temporary value for the brightness. This should change the display brightness but
+     * not trigger any updates.
+     */
+    fun setTemporaryBrightness(value: LinearBrightness)
+
+    /** Sets the brightness definitively. */
+    fun setBrightness(value: LinearBrightness)
+}
+
+@SuppressLint("MissingPermission")
+@SysUISingleton
+class ScreenBrightnessDisplayManagerRepository
+@Inject
+constructor(
+    @DisplayId private val displayId: Int,
+    private val displayManager: DisplayManager,
+    @Application private val applicationScope: CoroutineScope,
+    @Background private val backgroundContext: CoroutineContext,
+) : ScreenBrightnessRepository {
+
+    private val apiQueue =
+        Channel<SetBrightnessMethod>(
+            capacity = UNLIMITED,
+        )
+
+    init {
+        applicationScope.launch(backgroundContext) {
+            for (call in apiQueue) {
+                val bounds = getMinMaxLinearBrightness()
+                val value = call.value.clamp(bounds.first, bounds.second).floatValue
+                when (call) {
+                    is SetBrightnessMethod.Temporary -> {
+                        displayManager.setTemporaryBrightness(displayId, value)
+                    }
+                    is SetBrightnessMethod.Permanent -> {
+                        displayManager.setBrightness(displayId, value)
+                    }
+                }
+            }
+        }
+    }
+
+    private val brightnessInfo: StateFlow<BrightnessInfo?> =
+        conflatedCallbackFlow {
+                val listener =
+                    object : DisplayManager.DisplayListener {
+                        override fun onDisplayAdded(displayId: Int) {}
+
+                        override fun onDisplayRemoved(displayId: Int) {}
+
+                        override fun onDisplayChanged(displayId: Int) {
+                            if (
+                                displayId == this@ScreenBrightnessDisplayManagerRepository.displayId
+                            ) {
+                                trySend(Unit)
+                            }
+                        }
+                    }
+                displayManager.registerDisplayListener(
+                    listener,
+                    null,
+                    DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS,
+                )
+
+                awaitClose { displayManager.unregisterDisplayListener(listener) }
+            }
+            .onStart { emit(Unit) }
+            .map { brightnessInfoValue() }
+            .flowOn(backgroundContext)
+            .stateIn(
+                applicationScope,
+                SharingStarted.WhileSubscribed(replayExpirationMillis = 0L),
+                null,
+            )
+
+    private suspend fun brightnessInfoValue(): BrightnessInfo? {
+        return withContext(backgroundContext) {
+            displayManager.getDisplay(displayId).brightnessInfo
+        }
+    }
+
+    override val minLinearBrightness =
+        brightnessInfo
+            .filterNotNull()
+            .map { LinearBrightness(it.brightnessMinimum) }
+            .shareIn(applicationScope, SharingStarted.WhileSubscribed())
+
+    override val maxLinearBrightness =
+        brightnessInfo
+            .filterNotNull()
+            .map { LinearBrightness(it.brightnessMaximum) }
+            .shareIn(applicationScope, SharingStarted.WhileSubscribed())
+
+    override suspend fun getMinMaxLinearBrightness(): Pair<LinearBrightness, LinearBrightness> {
+        val brightnessInfo = brightnessInfo.value ?: brightnessInfoValue()
+        val min = brightnessInfo?.brightnessMinimum ?: 0f
+        val max = brightnessInfo?.brightnessMaximum ?: 1f
+        return LinearBrightness(min) to LinearBrightness(max)
+    }
+
+    override val linearBrightness =
+        brightnessInfo
+            .filterNotNull()
+            .map { LinearBrightness(it.brightness) }
+            .shareIn(applicationScope, SharingStarted.WhileSubscribed())
+
+    override fun setTemporaryBrightness(value: LinearBrightness) {
+        apiQueue.trySend(SetBrightnessMethod.Temporary(value))
+    }
+
+    override fun setBrightness(value: LinearBrightness) {
+        apiQueue.trySend(SetBrightnessMethod.Permanent(value))
+    }
+
+    private sealed interface SetBrightnessMethod {
+        val value: LinearBrightness
+        @JvmInline
+        value class Temporary(override val value: LinearBrightness) : SetBrightnessMethod
+        @JvmInline
+        value class Permanent(override val value: LinearBrightness) : SetBrightnessMethod
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/domain/interactor/BrightnessPolicyEnforcementInteractor.kt b/packages/SystemUI/src/com/android/systemui/brightness/domain/interactor/BrightnessPolicyEnforcementInteractor.kt
new file mode 100644
index 0000000..fb00edf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/brightness/domain/interactor/BrightnessPolicyEnforcementInteractor.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.domain.interactor
+
+import com.android.settingslib.RestrictedLockUtils
+import com.android.systemui.brightness.data.repository.BrightnessPolicyRepository
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.utils.PolicyRestriction
+import javax.inject.Inject
+
+/** Interactor for enforcing the policy that may disallow brightness changing. */
+@SysUISingleton
+class BrightnessPolicyEnforcementInteractor
+@Inject
+constructor(
+    brightnessPolicyRepository: BrightnessPolicyRepository,
+    private val activityStarter: ActivityStarter,
+) {
+
+    /** Brightness policy restriction for the current user. */
+    val brightnessPolicyRestriction = brightnessPolicyRepository.restrictionPolicy
+
+    /**
+     * Starts the dialog with details about the current restriction for changing brightness. Should
+     * be triggered when a restricted user tries to change the brightness.
+     */
+    fun startAdminSupportDetailsDialog(restriction: PolicyRestriction.Restricted) {
+        val intent = RestrictedLockUtils.getShowAdminSupportDetailsIntent(restriction.admin)
+        activityStarter.postStartActivityDismissingKeyguard(intent, 0)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractor.kt b/packages/SystemUI/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractor.kt
new file mode 100644
index 0000000..799a0a1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractor.kt
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.domain.interactor
+
+import com.android.settingslib.display.BrightnessUtils
+import com.android.systemui.brightness.data.model.LinearBrightness
+import com.android.systemui.brightness.data.repository.ScreenBrightnessRepository
+import com.android.systemui.brightness.shared.GammaBrightness
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+import kotlinx.coroutines.flow.combine
+
+/**
+ * Converts between [GammaBrightness] and [LinearBrightness].
+ *
+ * @see BrightnessUtils
+ */
+@SysUISingleton
+class ScreenBrightnessInteractor
+@Inject
+constructor(
+    private val screenBrightnessRepository: ScreenBrightnessRepository,
+) {
+    /** Maximum value in the Gamma space for brightness */
+    val maxGammaBrightness = GammaBrightness(BrightnessUtils.GAMMA_SPACE_MAX)
+
+    /** Minimum value in the Gamma space for brightness */
+    val minGammaBrightness = GammaBrightness(BrightnessUtils.GAMMA_SPACE_MIN)
+
+    /**
+     * Brightness in the Gamma space for the current display. It will always represent a value
+     * between [minGammaBrightness] and [maxGammaBrightness]
+     */
+    val gammaBrightness =
+        with(screenBrightnessRepository) {
+            combine(
+                linearBrightness,
+                minLinearBrightness,
+                maxLinearBrightness,
+            ) { brightness, min, max ->
+                brightness.toGammaBrightness(min, max)
+            }
+        }
+
+    /** Sets the brightness temporarily, while the user is changing it. */
+    suspend fun setTemporaryBrightness(gammaBrightness: GammaBrightness) {
+        screenBrightnessRepository.setTemporaryBrightness(
+            gammaBrightness.clamp().toLinearBrightness()
+        )
+    }
+
+    /** Sets the brightness definitely. */
+    suspend fun setBrightness(gammaBrightness: GammaBrightness) {
+        screenBrightnessRepository.setBrightness(gammaBrightness.clamp().toLinearBrightness())
+    }
+
+    private suspend fun GammaBrightness.toLinearBrightness(): LinearBrightness {
+        val bounds = screenBrightnessRepository.getMinMaxLinearBrightness()
+        return LinearBrightness(
+            BrightnessUtils.convertGammaToLinearFloat(
+                value,
+                bounds.first.floatValue,
+                bounds.second.floatValue
+            )
+        )
+    }
+
+    private fun GammaBrightness.clamp(): GammaBrightness {
+        return GammaBrightness(value.coerceIn(minGammaBrightness.value, maxGammaBrightness.value))
+    }
+
+    private fun LinearBrightness.toGammaBrightness(
+        min: LinearBrightness,
+        max: LinearBrightness,
+    ): GammaBrightness {
+        return GammaBrightness(
+            BrightnessUtils.convertLinearToGammaFloat(floatValue, min.floatValue, max.floatValue)
+        )
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java b/packages/SystemUI/src/com/android/systemui/brightness/shared/GammaBrightness.kt
similarity index 64%
copy from tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
copy to packages/SystemUI/src/com/android/systemui/brightness/shared/GammaBrightness.kt
index 4e64ab0..e20d003 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
+++ b/packages/SystemUI/src/com/android/systemui/brightness/shared/GammaBrightness.kt
@@ -14,15 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.systemui.brightness.shared
 
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
+import androidx.annotation.IntRange
+import com.android.settingslib.display.BrightnessUtils
 
-import java.util.List;
-
-public interface AslMarshallable {
-
-    /** Creates the on-device DOM element from the AslMarshallable Java Object. */
-    List<Element> toOdDomElements(Document doc);
-}
+@JvmInline
+value class GammaBrightness(
+    @IntRange(
+        from = BrightnessUtils.GAMMA_SPACE_MIN.toLong(),
+        to = BrightnessUtils.GAMMA_SPACE_MAX.toLong()
+    )
+    val value: Int
+)
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
new file mode 100644
index 0000000..c1be37a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/brightness/ui/compose/BrightnessSlider.kt
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.ui.compose
+
+import androidx.compose.animation.core.animateIntAsState
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableIntStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.unit.dp
+import com.android.compose.PlatformSlider
+import com.android.systemui.brightness.shared.GammaBrightness
+import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
+import com.android.systemui.brightness.ui.viewmodel.Drag
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.common.shared.model.Text
+import com.android.systemui.common.ui.compose.Icon
+import com.android.systemui.utils.PolicyRestriction
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+@Composable
+private fun BrightnessSlider(
+    gammaValue: Int,
+    valueRange: IntRange,
+    label: Text.Resource,
+    icon: Icon,
+    restriction: PolicyRestriction,
+    onRestrictedClick: (PolicyRestriction.Restricted) -> Unit,
+    onDrag: (Int) -> Unit,
+    onStop: (Int) -> Unit,
+    modifier: Modifier = Modifier,
+    formatter: (Int) -> String = { "$it" },
+) {
+    var value by remember(gammaValue) { mutableIntStateOf(gammaValue) }
+    val animatedValue by
+        animateIntAsState(targetValue = value, label = "BrightnessSliderAnimatedValue")
+    val floatValueRange = valueRange.first.toFloat()..valueRange.last.toFloat()
+    val isRestricted = restriction is PolicyRestriction.Restricted
+
+    PlatformSlider(
+        value = animatedValue.toFloat(),
+        valueRange = floatValueRange,
+        enabled = !isRestricted,
+        onValueChange = {
+            if (!isRestricted) {
+                value = it.toInt()
+                onDrag(value)
+            }
+        },
+        onValueChangeFinished = {
+            if (!isRestricted) {
+                onStop(value)
+            }
+        },
+        modifier =
+            modifier.clickable(
+                enabled = isRestricted,
+            ) {
+                if (restriction is PolicyRestriction.Restricted) {
+                    onRestrictedClick(restriction)
+                }
+            },
+        icon = { isDragging ->
+            if (isDragging) {
+                Text(text = formatter(value))
+            } else {
+                Icon(modifier = Modifier.size(24.dp), icon = icon)
+            }
+        },
+        label = {
+            Text(
+                text = stringResource(id = label.res),
+                style = MaterialTheme.typography.titleMedium,
+                maxLines = 1,
+            )
+        },
+    )
+}
+
+@Composable
+fun BrightnessSliderContainer(
+    viewModel: BrightnessSliderViewModel,
+    modifier: Modifier = Modifier,
+) {
+    val gamma: Int by viewModel.currentBrightness.map { it.value }.collectAsState(initial = 0)
+    val coroutineScope = rememberCoroutineScope()
+    val restriction by
+        viewModel.policyRestriction.collectAsState(initial = PolicyRestriction.NoRestriction)
+
+    BrightnessSlider(
+        gammaValue = gamma,
+        valueRange = viewModel.minBrightness.value..viewModel.maxBrightness.value,
+        label = viewModel.label,
+        icon = viewModel.icon,
+        restriction = restriction,
+        onRestrictedClick = viewModel::showPolicyRestrictionDialog,
+        onDrag = { coroutineScope.launch { viewModel.onDrag(Drag.Dragging(GammaBrightness(it))) } },
+        onStop = { coroutineScope.launch { viewModel.onDrag(Drag.Stopped(GammaBrightness(it))) } },
+        modifier = modifier.fillMaxWidth(),
+        formatter = viewModel::formatValue,
+    )
+}
diff --git a/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt
new file mode 100644
index 0000000..f0988ba
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/brightness/ui/viewmodel/BrightnessSliderViewModel.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.ui.viewmodel
+
+import com.android.systemui.brightness.domain.interactor.BrightnessPolicyEnforcementInteractor
+import com.android.systemui.brightness.domain.interactor.ScreenBrightnessInteractor
+import com.android.systemui.brightness.shared.GammaBrightness
+import com.android.systemui.common.shared.model.ContentDescription
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.common.shared.model.Text
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.res.R
+import com.android.systemui.utils.PolicyRestriction
+import javax.inject.Inject
+
+@SysUISingleton
+class BrightnessSliderViewModel
+@Inject
+constructor(
+    private val screenBrightnessInteractor: ScreenBrightnessInteractor,
+    private val brightnessPolicyEnforcementInteractor: BrightnessPolicyEnforcementInteractor,
+) {
+    val currentBrightness = screenBrightnessInteractor.gammaBrightness
+
+    val maxBrightness = screenBrightnessInteractor.maxGammaBrightness
+    val minBrightness = screenBrightnessInteractor.minGammaBrightness
+
+    val label = Text.Resource(R.string.quick_settings_brightness_dialog_title)
+
+    val icon = Icon.Resource(R.drawable.ic_brightness_full, ContentDescription.Resource(label.res))
+
+    val policyRestriction = brightnessPolicyEnforcementInteractor.brightnessPolicyRestriction
+
+    fun showPolicyRestrictionDialog(restriction: PolicyRestriction.Restricted) {
+        brightnessPolicyEnforcementInteractor.startAdminSupportDetailsDialog(restriction)
+    }
+
+    /**
+     * As a brightness slider is dragged, the corresponding events should be sent using this method.
+     */
+    suspend fun onDrag(drag: Drag) {
+        when (drag) {
+            is Drag.Dragging -> screenBrightnessInteractor.setTemporaryBrightness(drag.brightness)
+            is Drag.Stopped -> screenBrightnessInteractor.setBrightness(drag.brightness)
+        }
+    }
+
+    /**
+     * Format the current value of brightness as a percentage between the minimum and maximum gamma.
+     */
+    fun formatValue(value: Int): String {
+        val min = minBrightness.value
+        val max = maxBrightness.value
+        val coercedValue = value.coerceIn(min, max)
+        val percentage = (coercedValue - min) * 100 / (max - min)
+        // This is not finalized UI so using fixed string
+        return "$percentage%"
+    }
+}
+
+/** Represents a drag event in a brightness slider. */
+sealed interface Drag {
+    val brightness: GammaBrightness
+    @JvmInline value class Dragging(override val brightness: GammaBrightness) : Drag
+    @JvmInline value class Stopped(override val brightness: GammaBrightness) : Drag
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index 357eca3..d2caefd 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -398,6 +398,7 @@
                 || mAccessibilityManager.isTouchExplorationEnabled()
                 || mDataProvider.isA11yAction()
                 || mDataProvider.isFromTrackpad()
+                || mDataProvider.isFromKeyboard()
                 || (mFeatureFlags.isEnabled(Flags.FALSING_OFF_FOR_UNFOLDED)
                     && mDataProvider.isUnfolded());
     }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java
index a79a654..76b228d 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollector.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.classifier;
 
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 
 /**
@@ -50,6 +51,14 @@
     void onBouncerHidden();
 
     /**
+     * Call this to record a KeyEvent in the {@link com.android.systemui.plugins.FalsingManager}.
+     *
+     * This may decide to only collect certain KeyEvents and ignore others. Do not assume all
+     * KeyEvents are collected.
+     */
+    void onKeyEvent(KeyEvent ev);
+
+    /**
      * Call this to record a MotionEvent in the {@link com.android.systemui.plugins.FalsingManager}.
      *
      * Be sure to call {@link #onMotionEventComplete()} after the rest of SystemUI is done with the
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java
index d6b9a11..dcd4195 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorFake.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.classifier;
 
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 
 import javax.inject.Inject;
@@ -23,6 +24,8 @@
 /** */
 public class FalsingCollectorFake implements FalsingCollector {
 
+    public KeyEvent lastKeyEvent = null;
+
     @Override
     public void init() {
     }
@@ -70,6 +73,11 @@
     }
 
     @Override
+    public void onKeyEvent(KeyEvent ev) {
+        lastKeyEvent = ev;
+    }
+
+    @Override
     public void onTouchEvent(MotionEvent ev) {
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
index 4f4f3d0..beaa170 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
@@ -21,6 +21,7 @@
 import android.hardware.SensorManager;
 import android.hardware.biometrics.BiometricSourceType;
 import android.util.Log;
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 
 import androidx.annotation.VisibleForTesting;
@@ -49,7 +50,10 @@
 
 import dagger.Lazy;
 
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
 
 import javax.inject.Inject;
 
@@ -61,6 +65,14 @@
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     private static final long GESTURE_PROCESSING_DELAY_MS = 100;
 
+    private final Set<Integer> mAcceptedKeycodes = new HashSet<>(Arrays.asList(
+        KeyEvent.KEYCODE_ENTER,
+        KeyEvent.KEYCODE_ESCAPE,
+        KeyEvent.KEYCODE_SHIFT_LEFT,
+        KeyEvent.KEYCODE_SHIFT_RIGHT,
+        KeyEvent.KEYCODE_SPACE
+    ));
+
     private final FalsingDataProvider mFalsingDataProvider;
     private final FalsingManager mFalsingManager;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -279,6 +291,14 @@
     }
 
     @Override
+    public void onKeyEvent(KeyEvent ev) {
+        // Only collect if it is an ACTION_UP action and is allow-listed
+        if (ev.getAction() == KeyEvent.ACTION_UP && mAcceptedKeycodes.contains(ev.getKeyCode())) {
+            mFalsingDataProvider.onKeyEvent(ev);
+        }
+    }
+
+    @Override
     public void onTouchEvent(MotionEvent ev) {
         logDebug("REAL: onTouchEvent(" + ev.getActionMasked() + ")");
         if (!mKeyguardStateController.isShowing()) {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorNoOp.kt b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorNoOp.kt
index c5d8c79..b289fa4 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorNoOp.kt
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorNoOp.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.classifier
 
+import android.view.KeyEvent
 import android.view.MotionEvent
 import com.android.systemui.classifier.FalsingCollectorImpl.logDebug
 import com.android.systemui.dagger.SysUISingleton
@@ -59,6 +60,10 @@
         logDebug("NOOP: onBouncerHidden")
     }
 
+    override fun onKeyEvent(ev: KeyEvent) {
+        logDebug("NOOP: onKeyEvent(${ev.action}")
+    }
+
     override fun onTouchEvent(ev: MotionEvent) {
         logDebug("NOOP: onTouchEvent(${ev.actionMasked})")
     }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
index 809d5b2..1501701 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java
@@ -20,6 +20,7 @@
 
 import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
 import android.util.DisplayMetrics;
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.MotionEvent.PointerCoords;
 import android.view.MotionEvent.PointerProperties;
@@ -41,6 +42,7 @@
 public class FalsingDataProvider {
 
     private static final long MOTION_EVENT_AGE_MS = 1000;
+    private static final long KEY_EVENT_AGE_MS = 500;
     private static final long DROP_EVENT_THRESHOLD_MS = 50;
     private static final float THREE_HUNDRED_SIXTY_DEG = (float) (2 * Math.PI);
 
@@ -56,8 +58,10 @@
     private final List<MotionEventListener> mMotionEventListeners = new ArrayList<>();
     private final List<GestureFinalizedListener> mGestureFinalizedListeners = new ArrayList<>();
 
-    private TimeLimitedMotionEventBuffer mRecentMotionEvents =
-            new TimeLimitedMotionEventBuffer(MOTION_EVENT_AGE_MS);
+    private TimeLimitedInputEventBuffer<MotionEvent> mRecentMotionEvents =
+            new TimeLimitedInputEventBuffer<>(MOTION_EVENT_AGE_MS);
+    private final TimeLimitedInputEventBuffer<KeyEvent> mRecentKeyEvents =
+            new TimeLimitedInputEventBuffer<>(KEY_EVENT_AGE_MS);
     private List<MotionEvent> mPriorMotionEvents = new ArrayList<>();
 
     private boolean mDirty = true;
@@ -89,6 +93,10 @@
         FalsingClassifier.logInfo("width, height: " + getWidthPixels() + ", " + getHeightPixels());
     }
 
+    void onKeyEvent(KeyEvent keyEvent) {
+        mRecentKeyEvents.add(keyEvent);
+    }
+
     void onMotionEvent(MotionEvent motionEvent) {
         List<MotionEvent> motionEvents = unpackMotionEvent(motionEvent);
         FalsingClassifier.logVerbose("Unpacked into: " + motionEvents.size());
@@ -109,6 +117,10 @@
         // previous ACTION_MOVE event and when it happens, it makes some classifiers fail.
         mDropLastEvent = shouldDropEvent(motionEvent);
 
+        if (!motionEvents.isEmpty() && !mRecentKeyEvents.isEmpty()) {
+            recycleAndClearRecentKeyEvents();
+        }
+
         mRecentMotionEvents.addAll(motionEvents);
 
         FalsingClassifier.logVerbose("Size: " + mRecentMotionEvents.size());
@@ -141,7 +153,7 @@
                     mRecentMotionEvents.get(mRecentMotionEvents.size() - 1).getEventTime()));
 
             mPriorMotionEvents = mRecentMotionEvents;
-            mRecentMotionEvents = new TimeLimitedMotionEventBuffer(MOTION_EVENT_AGE_MS);
+            mRecentMotionEvents = new TimeLimitedInputEventBuffer<>(MOTION_EVENT_AGE_MS);
         }
         mDropLastEvent = false;
         mA11YAction = false;
@@ -261,6 +273,13 @@
         return mLastMotionEvent.getY() < mFirstRecentMotionEvent.getY();
     }
 
+    /**
+     * If it's a specific set of keys as collected from {@link FalsingCollector}
+     */
+    public boolean isFromKeyboard() {
+        return !mRecentKeyEvents.isEmpty();
+    }
+
     public boolean isFromTrackpad() {
         if (mRecentMotionEvents.isEmpty()) {
             return false;
@@ -318,6 +337,14 @@
         }
     }
 
+    private void recycleAndClearRecentKeyEvents() {
+        for (KeyEvent ev : mRecentKeyEvents) {
+            ev.recycle();
+        }
+
+        mRecentKeyEvents.clear();
+    }
+
     private List<MotionEvent> unpackMotionEvent(MotionEvent motionEvent) {
         List<MotionEvent> motionEvents = new ArrayList<>();
         List<PointerProperties> pointerPropertiesList = new ArrayList<>();
@@ -416,6 +443,8 @@
 
         mRecentMotionEvents.clear();
 
+        recycleAndClearRecentKeyEvents();
+
         mDirty = true;
 
         mSessionListeners.forEach(SessionListener::onSessionEnded);
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedInputEventBuffer.java b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedInputEventBuffer.java
new file mode 100644
index 0000000..7627ad1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedInputEventBuffer.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.classifier;
+
+import android.view.InputEvent;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * Maintains an ordered list of the last N milliseconds of InputEvents.
+ *
+ * This class is simply a convenience class designed to look like a simple list, but that
+ * automatically discards old InputEvents. It functions much like a queue - first in first out -
+ * but does not have a fixed size like a circular buffer.
+ */
+public class TimeLimitedInputEventBuffer<T extends InputEvent> implements List<T> {
+
+    private final List<T> mInputEvents;
+    private final long mMaxAgeMs;
+
+    public TimeLimitedInputEventBuffer(long maxAgeMs) {
+        super();
+        mMaxAgeMs = maxAgeMs;
+        mInputEvents = new ArrayList<>();
+    }
+
+    private void ejectOldEvents() {
+        if (mInputEvents.isEmpty()) {
+            return;
+        }
+        Iterator<T> iter = listIterator();
+        long mostRecentMs = mInputEvents.get(mInputEvents.size() - 1).getEventTime();
+        while (iter.hasNext()) {
+            T ev = iter.next();
+            if (mostRecentMs - ev.getEventTime() > mMaxAgeMs) {
+                iter.remove();
+                ev.recycle();
+            }
+        }
+    }
+
+    @Override
+    public void add(int index, T element) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public T remove(int index) {
+        return mInputEvents.remove(index);
+    }
+
+    @Override
+    public int indexOf(Object o) {
+        return mInputEvents.indexOf(o);
+    }
+
+    @Override
+    public int lastIndexOf(Object o) {
+        return mInputEvents.lastIndexOf(o);
+    }
+
+    @Override
+    public int size() {
+        return mInputEvents.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return mInputEvents.isEmpty();
+    }
+
+    @Override
+    public boolean contains(Object o) {
+        return mInputEvents.contains(o);
+    }
+
+    @Override
+    public Iterator<T> iterator() {
+        return mInputEvents.iterator();
+    }
+
+    @Override
+    public Object[] toArray() {
+        return mInputEvents.toArray();
+    }
+
+    @Override
+    public <T2> T2[] toArray(T2[] a) {
+        return mInputEvents.toArray(a);
+    }
+
+    @Override
+    public boolean add(T element) {
+        boolean result = mInputEvents.add(element);
+        ejectOldEvents();
+        return result;
+    }
+
+    @Override
+    public boolean remove(Object o) {
+        return mInputEvents.remove(o);
+    }
+
+    @Override
+    public boolean containsAll(Collection<?> c) {
+        return mInputEvents.containsAll(c);
+    }
+
+    @Override
+    public boolean addAll(Collection<? extends T> collection) {
+        boolean result = mInputEvents.addAll(collection);
+        ejectOldEvents();
+        return result;
+    }
+
+    @Override
+    public boolean addAll(int index, Collection<? extends T> elements) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean removeAll(Collection<?> c) {
+        return mInputEvents.removeAll(c);
+    }
+
+    @Override
+    public boolean retainAll(Collection<?> c) {
+        return mInputEvents.retainAll(c);
+    }
+
+    @Override
+    public void clear() {
+        mInputEvents.clear();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        return mInputEvents.equals(o);
+    }
+
+    @Override
+    public int hashCode() {
+        return mInputEvents.hashCode();
+    }
+
+    @Override
+    public T get(int index) {
+        return mInputEvents.get(index);
+    }
+
+    @Override
+    public T set(int index, T element) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ListIterator<T> listIterator() {
+        return new Iter(0);
+    }
+
+    @Override
+    public ListIterator<T> listIterator(int index) {
+        return new Iter(index);
+    }
+
+    @Override
+    public List<T> subList(int fromIndex, int toIndex) {
+        return mInputEvents.subList(fromIndex, toIndex);
+    }
+
+    class Iter implements ListIterator<T> {
+
+        private final ListIterator<T> mIterator;
+
+        Iter(int index) {
+            this.mIterator = mInputEvents.listIterator(index);
+        }
+
+        @Override
+        public boolean hasNext() {
+            return mIterator.hasNext();
+        }
+
+        @Override
+        public T next() {
+            return mIterator.next();
+        }
+
+        @Override
+        public boolean hasPrevious() {
+            return mIterator.hasPrevious();
+        }
+
+        @Override
+        public T previous() {
+            return mIterator.previous();
+        }
+
+        @Override
+        public int nextIndex() {
+            return mIterator.nextIndex();
+        }
+
+        @Override
+        public int previousIndex() {
+            return mIterator.previousIndex();
+        }
+
+        @Override
+        public void remove() {
+            mIterator.remove();
+        }
+
+        @Override
+        public void set(T inputEvent) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public void add(T element) {
+            throw new UnsupportedOperationException();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
deleted file mode 100644
index 51aede7..0000000
--- a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.classifier;
-
-import android.view.MotionEvent;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-/**
- * Maintains an ordered list of the last N milliseconds of MotionEvents.
- *
- * This class is simply a convenience class designed to look like a simple list, but that
- * automatically discards old MotionEvents. It functions much like a queue - first in first out -
- * but does not have a fixed size like a circular buffer.
- */
-public class TimeLimitedMotionEventBuffer implements List<MotionEvent> {
-
-    private final List<MotionEvent> mMotionEvents;
-    private final long mMaxAgeMs;
-
-    public TimeLimitedMotionEventBuffer(long maxAgeMs) {
-        super();
-        mMaxAgeMs = maxAgeMs;
-        mMotionEvents = new ArrayList<>();
-    }
-
-    private void ejectOldEvents() {
-        if (mMotionEvents.isEmpty()) {
-            return;
-        }
-        Iterator<MotionEvent> iter = listIterator();
-        long mostRecentMs = mMotionEvents.get(mMotionEvents.size() - 1).getEventTime();
-        while (iter.hasNext()) {
-            MotionEvent ev = iter.next();
-            if (mostRecentMs - ev.getEventTime() > mMaxAgeMs) {
-                iter.remove();
-                ev.recycle();
-            }
-        }
-    }
-
-    @Override
-    public void add(int index, MotionEvent element) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public MotionEvent remove(int index) {
-        return mMotionEvents.remove(index);
-    }
-
-    @Override
-    public int indexOf(Object o) {
-        return mMotionEvents.indexOf(o);
-    }
-
-    @Override
-    public int lastIndexOf(Object o) {
-        return mMotionEvents.lastIndexOf(o);
-    }
-
-    @Override
-    public int size() {
-        return mMotionEvents.size();
-    }
-
-    @Override
-    public boolean isEmpty() {
-        return mMotionEvents.isEmpty();
-    }
-
-    @Override
-    public boolean contains(Object o) {
-        return mMotionEvents.contains(o);
-    }
-
-    @Override
-    public Iterator<MotionEvent> iterator() {
-        return mMotionEvents.iterator();
-    }
-
-    @Override
-    public Object[] toArray() {
-        return mMotionEvents.toArray();
-    }
-
-    @Override
-    public <T> T[] toArray(T[] a) {
-        return mMotionEvents.toArray(a);
-    }
-
-    @Override
-    public boolean add(MotionEvent element) {
-        boolean result = mMotionEvents.add(element);
-        ejectOldEvents();
-        return result;
-    }
-
-    @Override
-    public boolean remove(Object o) {
-        return mMotionEvents.remove(o);
-    }
-
-    @Override
-    public boolean containsAll(Collection<?> c) {
-        return mMotionEvents.containsAll(c);
-    }
-
-    @Override
-    public boolean addAll(Collection<? extends MotionEvent> collection) {
-        boolean result = mMotionEvents.addAll(collection);
-        ejectOldEvents();
-        return result;
-    }
-
-    @Override
-    public boolean addAll(int index, Collection<? extends MotionEvent> elements) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean removeAll(Collection<?> c) {
-        return mMotionEvents.removeAll(c);
-    }
-
-    @Override
-    public boolean retainAll(Collection<?> c) {
-        return mMotionEvents.retainAll(c);
-    }
-
-    @Override
-    public void clear() {
-        mMotionEvents.clear();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        return mMotionEvents.equals(o);
-    }
-
-    @Override
-    public int hashCode() {
-        return mMotionEvents.hashCode();
-    }
-
-    @Override
-    public MotionEvent get(int index) {
-        return mMotionEvents.get(index);
-    }
-
-    @Override
-    public MotionEvent set(int index, MotionEvent element) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ListIterator<MotionEvent> listIterator() {
-        return new Iter(0);
-    }
-
-    @Override
-    public ListIterator<MotionEvent> listIterator(int index) {
-        return new Iter(index);
-    }
-
-    @Override
-    public List<MotionEvent> subList(int fromIndex, int toIndex) {
-        return mMotionEvents.subList(fromIndex, toIndex);
-    }
-
-    class Iter implements ListIterator<MotionEvent> {
-
-        private final ListIterator<MotionEvent> mIterator;
-
-        Iter(int index) {
-            this.mIterator = mMotionEvents.listIterator(index);
-        }
-
-        @Override
-        public boolean hasNext() {
-            return mIterator.hasNext();
-        }
-
-        @Override
-        public MotionEvent next() {
-            return mIterator.next();
-        }
-
-        @Override
-        public boolean hasPrevious() {
-            return mIterator.hasPrevious();
-        }
-
-        @Override
-        public MotionEvent previous() {
-            return mIterator.previous();
-        }
-
-        @Override
-        public int nextIndex() {
-            return mIterator.nextIndex();
-        }
-
-        @Override
-        public int previousIndex() {
-            return mIterator.previousIndex();
-        }
-
-        @Override
-        public void remove() {
-            mIterator.remove();
-        }
-
-        @Override
-        public void set(MotionEvent motionEvent) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void add(MotionEvent element) {
-            throw new UnsupportedOperationException();
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
index bb201b6..a43447f 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/EditTextActivity.java
@@ -23,14 +23,20 @@
 import android.content.ClipDescription;
 import android.content.ClipboardManager;
 import android.content.pm.PackageManager;
+import android.graphics.Insets;
 import android.os.Bundle;
 import android.os.PersistableBundle;
 import android.text.Editable;
 import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowInsets;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
+
 import com.android.systemui.res.R;
 
 /**
@@ -53,6 +59,24 @@
         mEditText = findViewById(R.id.edit_text);
         mAttribution = findViewById(R.id.attribution);
         mClipboardManager = requireNonNull(getSystemService(ClipboardManager.class));
+
+        findViewById(R.id.editor_root).setOnApplyWindowInsetsListener(
+                new View.OnApplyWindowInsetsListener() {
+                    @NonNull
+                    @Override
+                    public WindowInsets onApplyWindowInsets(@NonNull View view,
+                            @NonNull WindowInsets windowInsets) {
+                        Insets insets = windowInsets.getInsets(WindowInsets.Type.systemBars());
+                        ViewGroup.MarginLayoutParams layoutParams =
+                                (ViewGroup.MarginLayoutParams) view.getLayoutParams();
+                        layoutParams.leftMargin = insets.left;
+                        layoutParams.bottomMargin = insets.bottom;
+                        layoutParams.rightMargin = insets.right;
+                        layoutParams.topMargin = insets.top;
+                        view.setLayoutParams(layoutParams);
+                        return WindowInsets.CONSUMED;
+                    }
+                });
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/ViewExt.kt b/packages/SystemUI/src/com/android/systemui/common/ui/view/ViewExt.kt
index ce798ba..7dd883b 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/view/ViewExt.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/ViewExt.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.common.ui.view
 
 import android.view.View
+import kotlinx.coroutines.DisposableHandle
 
 /**
  * Set this view's [View#importantForAccessibility] to [View#IMPORTANT_FOR_ACCESSIBILITY_YES] or
@@ -43,3 +44,10 @@
     }
     return null
 }
+
+/** Adds a [View.OnLayoutChangeListener] and provides a [DisposableHandle] for teardown. */
+fun View.onLayoutChanged(onLayoutChanged: (v: View) -> Unit): DisposableHandle {
+    val listener = View.OnLayoutChangeListener { v, _, _, _, _, _, _, _, _ -> onLayoutChanged(v) }
+    addOnLayoutChangeListener(listener)
+    return DisposableHandle { removeOnLayoutChangeListener(listener) }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalPrefsRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalPrefsRepository.kt
index 0e9b32f..40d7440 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalPrefsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalPrefsRepository.kt
@@ -17,8 +17,11 @@
 package com.android.systemui.communal.data.repository
 
 import android.content.Context
+import android.content.IntentFilter
 import android.content.SharedPreferences
 import android.content.pm.UserInfo
+import com.android.systemui.backup.BackupHelper
+import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.log.LogBuffer
@@ -30,15 +33,18 @@
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.user.data.repository.UserRepository
 import com.android.systemui.util.kotlin.SharedPreferencesExt.observe
+import com.android.systemui.util.kotlin.emitOnStart
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.withContext
@@ -65,14 +71,36 @@
     @Background private val bgDispatcher: CoroutineDispatcher,
     private val userRepository: UserRepository,
     private val userFileManager: UserFileManager,
+    broadcastDispatcher: BroadcastDispatcher,
     @CommunalLog logBuffer: LogBuffer,
     @CommunalTableLog tableLogBuffer: TableLogBuffer,
 ) : CommunalPrefsRepository {
 
     private val logger = Logger(logBuffer, "CommunalPrefsRepositoryImpl")
 
+    /**
+     * Emits an event each time a Backup & Restore restoration job is completed. Does not emit an
+     * initial value.
+     */
+    private val backupRestorationEvents: Flow<Unit> =
+        broadcastDispatcher.broadcastFlow(
+            filter = IntentFilter(BackupHelper.ACTION_RESTORE_FINISHED),
+            flags = Context.RECEIVER_NOT_EXPORTED,
+            permission = BackupHelper.PERMISSION_SELF,
+        )
+
     override val isCtaDismissed: Flow<Boolean> =
-        userRepository.selectedUserInfo
+        combine(
+                userRepository.selectedUserInfo,
+                // Make sure combine can emit even if we never get a Backup & Restore event,
+                // which is the most common case as restoration only happens on initial device
+                // setup.
+                backupRestorationEvents.emitOnStart().onEach {
+                    logger.i("Restored state for communal preferences.")
+                },
+            ) { user, _ ->
+                user
+            }
             .flatMapLatest(::observeCtaDismissState)
             .logDiffsForTable(
                 tableLogBuffer = tableLogBuffer,
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
index 7c65d21..c724244 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
@@ -21,6 +21,7 @@
 import android.appwidget.AppWidgetProviderInfo
 import android.content.IntentFilter
 import android.content.pm.UserInfo
+import android.provider.Settings
 import com.android.systemui.Flags.communalHub
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.communal.data.model.CommunalEnabledState
@@ -116,12 +117,12 @@
 
     private fun getEnabledByUser(user: UserInfo): Flow<Boolean> =
         secureSettings
-            .observerFlow(userId = user.id, names = arrayOf(GLANCEABLE_HUB_ENABLED))
+            .observerFlow(userId = user.id, names = arrayOf(Settings.Secure.GLANCEABLE_HUB_ENABLED))
             // Force an update
             .onStart { emit(Unit) }
             .map {
                 secureSettings.getIntForUser(
-                    GLANCEABLE_HUB_ENABLED,
+                    Settings.Secure.GLANCEABLE_HUB_ENABLED,
                     ENABLED_SETTING_DEFAULT,
                     user.id,
                 ) == 1
@@ -138,7 +139,6 @@
             .map { devicePolicyManager.areKeyguardWidgetsAllowed(user.id) }
 
     companion object {
-        const val GLANCEABLE_HUB_ENABLED = "glanceable_hub_enabled"
         const val GLANCEABLE_HUB_CONTENT_SETTING = "glanceable_hub_content_setting"
         private const val ENABLED_SETTING_DEFAULT = 1
     }
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/backup/CommunalPrefsBackupHelper.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/backup/CommunalPrefsBackupHelper.kt
new file mode 100644
index 0000000..55c6ec8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/backup/CommunalPrefsBackupHelper.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.communal.domain.backup
+
+import android.app.backup.SharedPreferencesBackupHelper
+import android.content.Context
+import com.android.systemui.communal.data.repository.CommunalPrefsRepositoryImpl.Companion.FILE_NAME
+import com.android.systemui.settings.UserFileManagerImpl
+
+/** Helper to backup & restore the shared preferences in glanceable hub for the current user. */
+class CommunalPrefsBackupHelper(
+    context: Context,
+    userId: Int,
+) :
+    SharedPreferencesBackupHelper(
+        context,
+        UserFileManagerImpl.createFile(
+                userId = userId,
+                fileName = FILE_NAME,
+            )
+            .path
+    )
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
index 86b254b..246d5d9 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
@@ -81,6 +81,7 @@
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.shareIn
+import kotlinx.coroutines.flow.stateIn
 
 /** Encapsulates business-logic related to communal mode. */
 @OptIn(ExperimentalCoroutinesApi::class)
@@ -239,10 +240,14 @@
      * This will not be true while transitioning to the hub and will turn false immediately when a
      * swipe to exit the hub starts.
      */
-    val isIdleOnCommunal: Flow<Boolean> =
-        communalRepository.transitionState.map {
-            it is ObservableTransitionState.Idle && it.scene == CommunalScenes.Communal
-        }
+    val isIdleOnCommunal: StateFlow<Boolean> =
+        communalRepository.transitionState
+            .map { it is ObservableTransitionState.Idle && it.scene == CommunalScenes.Communal }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.Eagerly,
+                initialValue = false,
+            )
 
     /**
      * Flow that emits a boolean if any portion of the communal UI is visible at all.
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
index 6aa5e8b..2fa42ec 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
@@ -19,6 +19,7 @@
 import android.content.BroadcastReceiver;
 
 import com.android.systemui.GuestResetOrExitSessionReceiver;
+import com.android.systemui.accessibility.hearingaid.HearingDevicesDialogReceiver;
 import com.android.systemui.media.dialog.MediaOutputDialogReceiver;
 import com.android.systemui.people.widget.PeopleSpaceWidgetPinnedReceiver;
 import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
@@ -88,4 +89,13 @@
     @ClassKey(GuestResetOrExitSessionReceiver.class)
     public abstract BroadcastReceiver bindGuestResetOrExitSessionReceiver(
             GuestResetOrExitSessionReceiver broadcastReceiver);
+
+    /**
+     *
+     */
+    @Binds
+    @IntoMap
+    @ClassKey(HearingDevicesDialogReceiver.class)
+    public abstract BroadcastReceiver bindHearingDevicesDialogReceiver(
+            HearingDevicesDialogReceiver broadcastReceiver);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index 1ed4b50..7d86e06 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -43,6 +43,7 @@
 import com.android.systemui.bouncer.data.repository.BouncerRepositoryModule;
 import com.android.systemui.bouncer.domain.interactor.BouncerInteractorModule;
 import com.android.systemui.bouncer.ui.BouncerViewModule;
+import com.android.systemui.brightness.dagger.ScreenBrightnessModule;
 import com.android.systemui.classifier.FalsingModule;
 import com.android.systemui.clipboardoverlay.dagger.ClipboardOverlayModule;
 import com.android.systemui.common.data.CommonDataLayerModule;
@@ -229,6 +230,7 @@
         RecordIssueModule.class,
         ReferenceModule.class,
         RetailModeModule.class,
+        ScreenBrightnessModule.class,
         ScreenshotModule.class,
         SensorModule.class,
         SecurityRepositoryModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/DeviceEntryModule.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/DeviceEntryModule.kt
index 71b5ab2..b8c03c0 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/DeviceEntryModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/DeviceEntryModule.kt
@@ -1,9 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package com.android.systemui.deviceentry
 
+import com.android.keyguard.EmptyLockIconViewController
+import com.android.keyguard.LegacyLockIconViewController
+import com.android.keyguard.LockIconViewController
+import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.deviceentry.data.repository.DeviceEntryRepositoryModule
 import com.android.systemui.deviceentry.data.repository.FaceWakeUpTriggersConfigModule
+import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import dagger.Lazy
 import dagger.Module
+import dagger.Provides
 import dagger.multibindings.Multibinds
 
 @Module(
@@ -18,4 +41,19 @@
      * A set of DeviceEntryIconTransitions. Ensures that this can be injected even if it's empty.
      */
     @Multibinds abstract fun deviceEntryIconTransitionSet(): Set<DeviceEntryIconTransition>
+
+    companion object {
+        @Provides
+        @SysUISingleton
+        fun provideLockIconViewController(
+            legacyLockIconViewController: Lazy<LegacyLockIconViewController>,
+            emptyLockIconViewController: Lazy<EmptyLockIconViewController>,
+        ): LockIconViewController {
+            return if (DeviceEntryUdfpsRefactor.isEnabled) {
+                emptyLockIconViewController.get()
+            } else {
+                legacyLockIconViewController.get()
+            }
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
index 8283438..f779ac8 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/data/repository/DeviceEntryRepository.kt
@@ -1,15 +1,11 @@
 package com.android.systemui.deviceentry.data.repository
 
-import android.util.Log
 import com.android.internal.widget.LockPatternUtils
-import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.keyguard.data.repository.KeyguardRepository
 import com.android.systemui.statusbar.phone.KeyguardBypassController
-import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.user.data.repository.UserRepository
 import dagger.Binds
 import dagger.Module
@@ -17,38 +13,20 @@
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.withContext
 
 /** Interface for classes that can access device-entry-related application state. */
 interface DeviceEntryRepository {
     /**
-     * Whether the device is unlocked.
-     *
-     * A device that is not yet unlocked requires unlocking by completing an authentication
-     * challenge according to the current authentication method, unless in cases when the current
-     * authentication method is not "secure" (for example, None); in such cases, the value of this
-     * flow will always be `true`, even if the lockscreen is showing and still needs to be dismissed
-     * by the user to proceed.
-     */
-    val isUnlocked: StateFlow<Boolean>
-
-    /**
      * Whether the lockscreen is enabled for the current user. This is `true` whenever the user has
      * chosen any secure authentication method and even if they set the lockscreen to be dismissed
      * when the user swipes on it.
      */
     suspend fun isLockscreenEnabled(): Boolean
 
-    /** Report successful authentication for device entry. */
-    fun reportSuccessfulAuthentication()
-
     /**
      * Whether lockscreen bypass is enabled. When enabled, the lockscreen will be automatically
      * dismissed once the authentication challenge is completed.
@@ -73,53 +51,8 @@
     private val userRepository: UserRepository,
     private val lockPatternUtils: LockPatternUtils,
     private val keyguardBypassController: KeyguardBypassController,
-    keyguardStateController: KeyguardStateController,
-    keyguardRepository: KeyguardRepository,
 ) : DeviceEntryRepository {
 
-    private val _isUnlocked = MutableStateFlow(false)
-
-    private val isUnlockedReportedByLegacyKeyguard =
-        conflatedCallbackFlow {
-                val callback =
-                    object : KeyguardStateController.Callback {
-                        override fun onUnlockedChanged() {
-                            trySendWithFailureLogging(
-                                keyguardStateController.isUnlocked,
-                                TAG,
-                                "updated isUnlocked due to onUnlockedChanged"
-                            )
-                        }
-
-                        override fun onKeyguardShowingChanged() {
-                            trySendWithFailureLogging(
-                                keyguardStateController.isUnlocked,
-                                TAG,
-                                "updated isUnlocked due to onKeyguardShowingChanged"
-                            )
-                        }
-                    }
-
-                keyguardStateController.addCallback(callback)
-                // Adding the callback does not send an initial update.
-                trySendWithFailureLogging(
-                    keyguardStateController.isUnlocked,
-                    TAG,
-                    "initial isKeyguardUnlocked"
-                )
-
-                awaitClose { keyguardStateController.removeCallback(callback) }
-            }
-            .distinctUntilChanged()
-            .onEach { _isUnlocked.value = it }
-            .stateIn(
-                applicationScope,
-                SharingStarted.Eagerly,
-                initialValue = false,
-            )
-
-    override val isUnlocked: StateFlow<Boolean> = _isUnlocked.asStateFlow()
-
     override suspend fun isLockscreenEnabled(): Boolean {
         return withContext(backgroundDispatcher) {
             val selectedUserId = userRepository.getSelectedUserInfo().id
@@ -127,11 +60,6 @@
         }
     }
 
-    override fun reportSuccessfulAuthentication() {
-        Log.d(TAG, "Successful authentication reported.")
-        _isUnlocked.value = true
-    }
-
     override val isBypassEnabled: StateFlow<Boolean> =
         conflatedCallbackFlow {
                 val listener =
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFingerprintAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFingerprintAuthInteractor.kt
index c4e0ef7..ec574d2 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFingerprintAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryFingerprintAuthInteractor.kt
@@ -24,6 +24,7 @@
 import com.android.systemui.keyguard.shared.model.FailFingerprintAuthenticationStatus
 import com.android.systemui.keyguard.shared.model.FingerprintAuthenticationStatus
 import com.android.systemui.keyguard.shared.model.HelpFingerprintAuthenticationStatus
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import javax.inject.Inject
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
@@ -58,6 +59,9 @@
     val fingerprintHelp: Flow<HelpFingerprintAuthenticationStatus> =
         repository.authenticationStatus.filterIsInstance<HelpFingerprintAuthenticationStatus>()
 
+    val fingerprintSuccess: Flow<SuccessFingerprintAuthenticationStatus> =
+        repository.authenticationStatus.filterIsInstance<SuccessFingerprintAuthenticationStatus>()
+
     /**
      * Whether fingerprint authentication is currently allowed for the user. This is true if the
      * user has fingerprint auth enabled, enrolled, it is not disabled by any security timeouts by
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
index fa2421a..5c1ca64 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractor.kt
@@ -26,7 +26,6 @@
 import com.android.systemui.flags.SystemPropertiesHelper
 import com.android.systemui.keyguard.domain.interactor.TrustInteractor
 import com.android.systemui.scene.domain.interactor.SceneInteractor
-import com.android.systemui.scene.shared.flag.SceneContainerFlags
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.util.kotlin.Quad
 import javax.inject.Inject
@@ -35,14 +34,11 @@
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.collectLatest
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.merge
-import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
 
@@ -65,8 +61,7 @@
     private val fingerprintAuthInteractor: DeviceEntryFingerprintAuthInteractor,
     private val biometricSettingsInteractor: DeviceEntryBiometricSettingsInteractor,
     private val trustInteractor: TrustInteractor,
-    flags: SceneContainerFlags,
-    deviceUnlockedInteractor: DeviceUnlockedInteractor,
+    private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
     private val systemPropertiesHelper: SystemPropertiesHelper,
 ) {
     /**
@@ -78,7 +73,14 @@
      * of this flow will always be `true`, even if the lockscreen is showing and still needs to be
      * dismissed by the user to proceed.
      */
-    val isUnlocked: StateFlow<Boolean> = deviceUnlockedInteractor.isDeviceUnlocked
+    val isUnlocked: StateFlow<Boolean> =
+        deviceUnlockedInteractor.deviceUnlockStatus
+            .map { it.isUnlocked }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = deviceUnlockedInteractor.deviceUnlockStatus.value.isUnlocked,
+            )
 
     /**
      * Whether the device has been entered (i.e. the lockscreen has been dismissed, by any method).
@@ -100,17 +102,6 @@
             )
 
     /**
-     * Whether the user is currently authenticated by a TrustAgent like trusted device, location,
-     * etc., or by face auth.
-     */
-    private val isPassivelyAuthenticated =
-        merge(
-                trustInteractor.isTrusted,
-                faceAuthInteractor.authenticated,
-            )
-            .onStart { emit(false) }
-
-    /**
      * Whether it's currently possible to swipe up to enter the device without requiring
      * authentication or when the device is already authenticated using a passive authentication
      * mechanism like face or trust manager. This returns `false` whenever the lockscreen has been
@@ -129,10 +120,13 @@
                 authenticationInteractor.authenticationMethod.map {
                     it == AuthenticationMethodModel.None && repository.isLockscreenEnabled()
                 },
-                isPassivelyAuthenticated,
+                deviceUnlockedInteractor.deviceUnlockStatus,
                 isDeviceEntered
-            ) { isSwipeAuthMethod, isPassivelyAuthenticated, isDeviceEntered ->
-                (isSwipeAuthMethod || isPassivelyAuthenticated) && !isDeviceEntered
+            ) { isSwipeAuthMethod, deviceUnlockStatus, isDeviceEntered ->
+                (isSwipeAuthMethod ||
+                    (deviceUnlockStatus.isUnlocked &&
+                        deviceUnlockStatus.deviceUnlockSource?.dismissesLockscreen == false)) &&
+                    !isDeviceEntered
             }
             .stateIn(
                 scope = applicationScope,
@@ -235,7 +229,8 @@
      * `false` if the device can be entered without authenticating first.
      */
     suspend fun isAuthenticationRequired(): Boolean {
-        return !isUnlocked.value && authenticationInteractor.getAuthenticationMethod().isSecure
+        return !deviceUnlockedInteractor.deviceUnlockStatus.value.isUnlocked &&
+            authenticationInteractor.getAuthenticationMethod().isSecure
     }
 
     /**
@@ -246,18 +241,6 @@
      */
     val isBypassEnabled: StateFlow<Boolean> = repository.isBypassEnabled
 
-    init {
-        if (flags.isEnabled()) {
-            applicationScope.launch {
-                authenticationInteractor.onAuthenticationResult.collectLatest { isSuccessful ->
-                    if (isSuccessful) {
-                        repository.reportSuccessfulAuthentication()
-                    }
-                }
-            }
-        }
-    }
-
     private val wasRebootedForMainlineUpdate
         get() = systemPropertiesHelper.get(SYS_BOOT_REASON_PROP) == REBOOT_MAINLINE_UPDATE
 
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
index b0495fb..098ede3 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractor.kt
@@ -21,13 +21,23 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.deviceentry.data.repository.DeviceEntryRepository
+import com.android.systemui.deviceentry.shared.model.DeviceUnlockSource
+import com.android.systemui.deviceentry.shared.model.DeviceUnlockStatus
+import com.android.systemui.keyguard.domain.interactor.TrustInteractor
+import com.android.systemui.power.domain.interactor.PowerInteractor
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
 import kotlinx.coroutines.flow.stateIn
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @SysUISingleton
 class DeviceUnlockedInteractor
 @Inject
@@ -35,28 +45,63 @@
     @Application private val applicationScope: CoroutineScope,
     authenticationInteractor: AuthenticationInteractor,
     deviceEntryRepository: DeviceEntryRepository,
+    trustInteractor: TrustInteractor,
+    faceAuthInteractor: DeviceEntryFaceAuthInteractor,
+    fingerprintAuthInteractor: DeviceEntryFingerprintAuthInteractor,
+    private val powerInteractor: PowerInteractor,
 ) {
 
+    private val deviceUnlockSource =
+        merge(
+            fingerprintAuthInteractor.fingerprintSuccess.map { DeviceUnlockSource.Fingerprint },
+            faceAuthInteractor.authenticated
+                .filter { it }
+                .map {
+                    if (deviceEntryRepository.isBypassEnabled.value) {
+                        DeviceUnlockSource.FaceWithBypass
+                    } else {
+                        DeviceUnlockSource.FaceWithoutBypass
+                    }
+                },
+            trustInteractor.isTrusted.filter { it }.map { DeviceUnlockSource.TrustAgent },
+            authenticationInteractor.onAuthenticationResult
+                .filter { it }
+                .map { DeviceUnlockSource.BouncerInput }
+        )
+
     /**
-     * Whether the device is unlocked.
+     * Whether the device is unlocked or not, along with the information about the authentication
+     * method that was used to unlock the device.
      *
      * A device that is not yet unlocked requires unlocking by completing an authentication
      * challenge according to the current authentication method, unless in cases when the current
      * authentication method is not "secure" (for example, None and Swipe); in such cases, the value
-     * of this flow will always be `true`, even if the lockscreen is showing and still needs to be
-     * dismissed by the user to proceed.
+     * of this flow will always be an instance of [DeviceUnlockStatus] with
+     * [DeviceUnlockStatus.deviceUnlockSource] as null and [DeviceUnlockStatus.isUnlocked] set to
+     * true, even if the lockscreen is showing and still needs to be dismissed by the user to
+     * proceed.
      */
-    val isDeviceUnlocked: StateFlow<Boolean> =
-        combine(
-                deviceEntryRepository.isUnlocked,
-                authenticationInteractor.authenticationMethod,
-            ) { isUnlocked, authenticationMethod ->
-                (!authenticationMethod.isSecure || isUnlocked) &&
-                    authenticationMethod != AuthenticationMethodModel.Sim
+    val deviceUnlockStatus: StateFlow<DeviceUnlockStatus> =
+        authenticationInteractor.authenticationMethod
+            .flatMapLatest { authMethod ->
+                if (!authMethod.isSecure) {
+                    flowOf(DeviceUnlockStatus(true, null))
+                } else if (authMethod == AuthenticationMethodModel.Sim) {
+                    // Device is locked if SIM is locked.
+                    flowOf(DeviceUnlockStatus(false, null))
+                } else {
+                    powerInteractor.isAsleep.flatMapLatest { isAsleep ->
+                        if (isAsleep) {
+                            flowOf(DeviceUnlockStatus(false, null))
+                        } else {
+                            deviceUnlockSource.map { DeviceUnlockStatus(true, it) }
+                        }
+                    }
+                }
             }
             .stateIn(
                 scope = applicationScope,
                 started = SharingStarted.Eagerly,
-                initialValue = false,
+                initialValue = DeviceUnlockStatus(false, null),
             )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/DeviceUnlockSource.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/DeviceUnlockSource.kt
new file mode 100644
index 0000000..619c240
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/DeviceUnlockSource.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.deviceentry.shared.model
+
+/**
+ * Source of the device unlock.
+ *
+ * @property dismissesLockscreen whether unlock with this authentication method dismisses the
+ *   lockscreen and enters the device.
+ */
+sealed class DeviceUnlockSource(val dismissesLockscreen: Boolean) {
+
+    data object Fingerprint : DeviceUnlockSource(true)
+    data object FaceWithBypass : DeviceUnlockSource(dismissesLockscreen = true)
+    data object FaceWithoutBypass : DeviceUnlockSource(dismissesLockscreen = false)
+    data object TrustAgent : DeviceUnlockSource(dismissesLockscreen = false)
+    data object BouncerInput : DeviceUnlockSource(dismissesLockscreen = true)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/DeviceUnlockStatus.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/DeviceUnlockStatus.kt
new file mode 100644
index 0000000..f694c33
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/shared/model/DeviceUnlockStatus.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.deviceentry.shared.model
+
+/**
+ * Wrapper class that combines whether device is unlocked or not, along with the authentication
+ * method used to unlock the device.
+ *
+ * @property isUnlocked whether device is unlocked or not.
+ * @property deviceUnlockSource source that unlocked the device, null if lockscreen is not secure or
+ *   if [isUnlocked] is false.
+ */
+data class DeviceUnlockStatus(
+    val isUnlocked: Boolean,
+    val deviceUnlockSource: DeviceUnlockSource?
+) {
+    init {
+        assert(isUnlocked || deviceUnlockSource == null) {
+            "deviceUnlockSource must be null when device is locked."
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/deviceentry/ui/viewmodel/UdfpsAccessibilityOverlayViewModel.kt b/packages/SystemUI/src/com/android/systemui/deviceentry/ui/viewmodel/UdfpsAccessibilityOverlayViewModel.kt
index f5a8870..191d612 100644
--- a/packages/SystemUI/src/com/android/systemui/deviceentry/ui/viewmodel/UdfpsAccessibilityOverlayViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/deviceentry/ui/viewmodel/UdfpsAccessibilityOverlayViewModel.kt
@@ -54,9 +54,21 @@
     fun onHoverEvent(v: View, event: MotionEvent): Boolean {
         val overlayParams = udfpsOverlayParams.value
         val scaledTouch: Point =
-            udfpsUtils.getTouchInNativeCoordinates(event.getPointerId(0), event, overlayParams)
+            udfpsUtils.getTouchInNativeCoordinates(
+                event.getPointerId(0),
+                event,
+                overlayParams, /* rotateToPortrait */
+                false
+            )
 
-        if (!udfpsUtils.isWithinSensorArea(event.getPointerId(0), event, overlayParams)) {
+        if (
+            !udfpsUtils.isWithinSensorArea(
+                event.getPointerId(0),
+                event,
+                overlayParams,
+                /* rotateTouchToPortrait */ false
+            )
+        ) {
             // view only receives motionEvents when [visible] which requires touchExplorationEnabled
             val announceStr =
                 udfpsUtils.onTouchOutsideOfSensorArea(
@@ -65,6 +77,7 @@
                     scaledTouch.x,
                     scaledTouch.y,
                     overlayParams,
+                    /* touchRotatedToPortrait */ false
                 )
             if (announceStr != null) {
                 v.announceForAccessibility(announceStr)
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index 424bd0a..9a9e698 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -209,6 +209,15 @@
     }
 
     /**
+     * Logs cancelation requests for time ticks
+     * @param isPending is an unschedule request pending?
+     * @param isTimeTickScheduled is a time tick request scheduled
+     */
+    public void tracePendingUnscheduleTimeTick(boolean isPending, boolean isTimeTickScheduled) {
+        mLogger.logPendingUnscheduleTimeTick(isPending, isTimeTickScheduled);
+    }
+
+    /**
      * Appends keyguard visibility change event to the logs
      * @param showing whether the keyguard is now showing
      */
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
index 75b8e51..9d6693e 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
@@ -162,6 +162,15 @@
         })
     }
 
+    fun logPendingUnscheduleTimeTick(isPending: Boolean, isTimeTickScheduled: Boolean) {
+        buffer.log(TAG, INFO, {
+            bool1 = isPending
+            bool2 = isTimeTickScheduled
+        }, {
+            "Pending unschedule time tick, isPending=$bool1, isTimeTickScheduled:$bool2"
+        })
+    }
+
     fun logDozeStateChanged(state: DozeMachine.State) {
         buffer.log(TAG, INFO, {
             str1 = state.name
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 34a80e8..1a855d7 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -26,11 +26,12 @@
 import android.text.format.Formatter;
 import android.util.Log;
 
-import com.android.systemui.DejankUtils;
+import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.doze.dagger.DozeScope;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.AlarmTimeout;
+import com.android.systemui.util.concurrency.DelayableExecutor;
 import com.android.systemui.util.wakelock.WakeLock;
 
 import java.util.Calendar;
@@ -52,14 +53,19 @@
     private final boolean mCanAnimateTransition;
     private final DozeParameters mDozeParameters;
     private final DozeLog mDozeLog;
+    private final DelayableExecutor mBgExecutor;
 
+    private Runnable mCancelRunnable = null;
     private long mLastTimeTickElapsed = 0;
     // If time tick is scheduled and there's not a pending runnable to cancel:
-    private boolean mTimeTickScheduled;
+    private volatile boolean mTimeTickScheduled;
     private final Runnable mCancelTimeTickerRunnable =  new Runnable() {
         @Override
         public void run() {
-            mTimeTicker.cancel();
+            mDozeLog.tracePendingUnscheduleTimeTick(false, mTimeTickScheduled);
+            if (!mTimeTickScheduled) {
+                mTimeTicker.cancel();
+            }
         }
     };
 
@@ -67,11 +73,13 @@
     public DozeUi(Context context, AlarmManager alarmManager,
             WakeLock wakeLock, DozeHost host, @Main Handler handler,
             DozeParameters params,
+            @Background DelayableExecutor bgExecutor,
             DozeLog dozeLog) {
         mContext = context;
         mWakeLock = wakeLock;
         mHost = host;
         mHandler = handler;
+        mBgExecutor = bgExecutor;
         mCanAnimateTransition = !params.getDisplayNeedsBlanking();
         mDozeParameters = params;
         mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", handler);
@@ -166,7 +174,6 @@
             return;
         }
         mTimeTickScheduled = true;
-        DejankUtils.removeCallbacks(mCancelTimeTickerRunnable);
 
         long time = System.currentTimeMillis();
         long delta = roundToNextMinute(time) - System.currentTimeMillis();
@@ -182,7 +189,8 @@
             return;
         }
         mTimeTickScheduled = false;
-        DejankUtils.postAfterTraversal(mCancelTimeTickerRunnable);
+        mDozeLog.tracePendingUnscheduleTimeTick(true, mTimeTickScheduled);
+        mBgExecutor.execute(mCancelTimeTickerRunnable);
     }
 
     private void verifyLastTimeTick() {
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
index 926f7f1..75c50fd 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java
@@ -19,6 +19,7 @@
 import static com.android.systemui.dreams.touch.dagger.BouncerSwipeModule.SWIPE_TO_BOUNCER_FLING_ANIMATION_UTILS_CLOSING;
 import static com.android.systemui.dreams.touch.dagger.BouncerSwipeModule.SWIPE_TO_BOUNCER_FLING_ANIMATION_UTILS_OPENING;
 import static com.android.systemui.dreams.touch.dagger.BouncerSwipeModule.SWIPE_TO_BOUNCER_START_REGION;
+import static com.android.systemui.dreams.touch.dagger.BouncerSwipeModule.MIN_BOUNCER_ZONE_SCREEN_PERCENTAGE;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -81,6 +82,7 @@
     private final LockPatternUtils mLockPatternUtils;
     private final UserTracker mUserTracker;
     private final float mBouncerZoneScreenPercentage;
+    private final float mMinBouncerZoneScreenPercentage;
 
     private final ScrimManager mScrimManager;
     private ScrimController mCurrentScrimController;
@@ -222,6 +224,7 @@
             @Named(SWIPE_TO_BOUNCER_FLING_ANIMATION_UTILS_CLOSING)
                     FlingAnimationUtils flingAnimationUtilsClosing,
             @Named(SWIPE_TO_BOUNCER_START_REGION) float swipeRegionPercentage,
+            @Named(MIN_BOUNCER_ZONE_SCREEN_PERCENTAGE) float minRegionPercentage,
             UiEventLogger uiEventLogger) {
         mCentralSurfaces = centralSurfaces;
         mScrimManager = scrimManager;
@@ -229,6 +232,7 @@
         mLockPatternUtils = lockPatternUtils;
         mUserTracker = userTracker;
         mBouncerZoneScreenPercentage = swipeRegionPercentage;
+        mMinBouncerZoneScreenPercentage = minRegionPercentage;
         mFlingAnimationUtils = flingAnimationUtils;
         mFlingAnimationUtilsClosing = flingAnimationUtilsClosing;
         mValueAnimatorCreator = valueAnimatorCreator;
@@ -237,24 +241,27 @@
     }
 
     @Override
-    public void getTouchInitiationRegion(Rect bounds, Region region) {
+    public void getTouchInitiationRegion(Rect bounds, Region region, Rect exclusionRect) {
         final int width = bounds.width();
         final int height = bounds.height();
+        final float minBouncerHeight = height * mMinBouncerZoneScreenPercentage;
+        final int minAllowableBottom = Math.round(height * (1 - mMinBouncerZoneScreenPercentage));
 
-        if (mCentralSurfaces.map(CentralSurfaces::isBouncerShowing).orElse(false)) {
-            region.op(new Rect(0, 0, width,
-                            Math.round(
-                                    height * mBouncerZoneScreenPercentage)),
-                    Region.Op.UNION);
-        } else {
-            region.op(new Rect(0,
-                            Math.round(height * (1 - mBouncerZoneScreenPercentage)),
-                            width,
-                            height),
-                    Region.Op.UNION);
+        final boolean isBouncerShowing =
+                mCentralSurfaces.map(CentralSurfaces::isBouncerShowing).orElse(false);
+        final Rect normalRegion = isBouncerShowing
+                ? new Rect(0, 0, width, Math.round(height * mBouncerZoneScreenPercentage))
+                : new Rect(0, Math.round(height * (1 - mBouncerZoneScreenPercentage)),
+                        width, height);
+
+        if (!isBouncerShowing && exclusionRect != null) {
+            int lowestBottom = Math.min(Math.max(0, exclusionRect.bottom), minAllowableBottom);
+            normalRegion.top = Math.max(normalRegion.top, lowestBottom);
         }
+        region.union(normalRegion);
     }
 
+
     @Override
     public void onSessionStart(TouchSession session) {
         mVelocityTracker = mVelocityTrackerFactory.obtain();
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/CommunalTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/CommunalTouchHandler.java
index e5c705f..13588c2 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/CommunalTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/CommunalTouchHandler.java
@@ -87,7 +87,7 @@
     }
 
     @Override
-    public void getTouchInitiationRegion(Rect bounds, Region region) {
+    public void getTouchInitiationRegion(Rect bounds, Region region, Rect exclusionRect) {
         final Rect outBounds = new Rect(bounds);
         outBounds.inset(outBounds.width() - mInitiationWidth, 0, 0, 0);
         region.op(outBounds, Region.Op.UNION);
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java
index 55a9c0c..3b22b31 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java
@@ -18,9 +18,15 @@
 
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
 
+import static com.android.systemui.shared.Flags.bouncerAreaExclusion;
+
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.os.RemoteException;
+import android.util.Log;
 import android.view.GestureDetector;
+import android.view.ISystemGestureExclusionListener;
+import android.view.IWindowManager;
 import android.view.InputEvent;
 import android.view.MotionEvent;
 
@@ -31,6 +37,8 @@
 import androidx.lifecycle.LifecycleObserver;
 import androidx.lifecycle.LifecycleOwner;
 
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.DisplayId;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.touch.dagger.InputSessionComponent;
 import com.android.systemui.shared.system.InputChannelCompat;
@@ -58,8 +66,23 @@
 public class DreamOverlayTouchMonitor {
     // This executor is used to protect {@code mActiveTouchSessions} from being modified
     // concurrently. Any operation that adds or removes values should use this executor.
-    private final Executor mExecutor;
+    public String TAG = "DreamOverlayTouchMonitor";
+    private final Executor mMainExecutor;
+    private final Executor mBackgroundExecutor;
     private final Lifecycle mLifecycle;
+    private Rect mExclusionRect = null;
+
+    private ISystemGestureExclusionListener mGestureExclusionListener =
+            new ISystemGestureExclusionListener.Stub() {
+                @Override
+                public void onSystemGestureExclusionChanged(int displayId,
+                        Region systemGestureExclusion,
+                        Region systemGestureExclusionUnrestricted) {
+                    mExclusionRect = systemGestureExclusion.getBounds();
+                }
+            };
+
+
 
     /**
      * Adds a new {@link TouchSessionImpl} to participate in receiving future touches and gestures.
@@ -67,7 +90,7 @@
     private ListenableFuture<DreamTouchHandler.TouchSession> push(
             TouchSessionImpl touchSessionImpl) {
         return CallbackToFutureAdapter.getFuture(completer -> {
-            mExecutor.execute(() -> {
+            mMainExecutor.execute(() -> {
                 if (!mActiveTouchSessions.remove(touchSessionImpl)) {
                     completer.set(null);
                     return;
@@ -90,7 +113,7 @@
     private ListenableFuture<DreamTouchHandler.TouchSession> pop(
             TouchSessionImpl touchSessionImpl) {
         return CallbackToFutureAdapter.getFuture(completer -> {
-            mExecutor.execute(() -> {
+            mMainExecutor.execute(() -> {
                 if (mActiveTouchSessions.remove(touchSessionImpl)) {
                     touchSessionImpl.onRemoved();
 
@@ -240,6 +263,17 @@
      */
     private void startMonitoring() {
         stopMonitoring(true);
+        if (bouncerAreaExclusion()) {
+            mBackgroundExecutor.execute(() -> {
+                try {
+                    mWindowManagerService.registerSystemGestureExclusionListener(
+                            mGestureExclusionListener, mDisplayId);
+                } catch (RemoteException e) {
+                    // Handle the exception
+                    Log.e(TAG, "Failed to register gesture exclusion listener", e);
+                }
+            });
+        }
         mCurrentInputSession = mInputSessionFactory.create(
                 "dreamOverlay",
                 mInputEventListener,
@@ -252,6 +286,18 @@
      * Destroys any active {@link InputSession}.
      */
     private void stopMonitoring(boolean force) {
+        mExclusionRect = null;
+        if (bouncerAreaExclusion()) {
+            mBackgroundExecutor.execute(() -> {
+                try {
+                    mWindowManagerService.unregisterSystemGestureExclusionListener(
+                            mGestureExclusionListener, mDisplayId);
+                } catch (RemoteException e) {
+                    // Handle the exception
+                    Log.e(TAG, "unregisterSystemGestureExclusionListener: failed", e);
+                }
+            });
+        }
         if (mCurrentInputSession == null) {
             return;
         }
@@ -263,7 +309,7 @@
 
         // When we stop monitoring touches, we must ensure that all active touch sessions and
         // descendants informed of the removal so any cleanup for active tracking can proceed.
-        mExecutor.execute(() -> mActiveTouchSessions.forEach(touchSession -> {
+        mMainExecutor.execute(() -> mActiveTouchSessions.forEach(touchSession -> {
             while (touchSession != null) {
                 touchSession.onRemoved();
                 touchSession = touchSession.getPredecessor();
@@ -295,11 +341,15 @@
                             if (!handler.isEnabled()) {
                                 continue;
                             }
-                    final Rect maxBounds = mDisplayHelper.getMaxBounds(ev.getDisplayId(),
-                            TYPE_APPLICATION_OVERLAY);
-
-                    final Region initiationRegion = Region.obtain();
-                    handler.getTouchInitiationRegion(maxBounds, initiationRegion);
+                            final Rect maxBounds = mDisplayHelper.getMaxBounds(ev.getDisplayId(),
+                                    TYPE_APPLICATION_OVERLAY);
+                            final Region initiationRegion = Region.obtain();
+                            Rect exclusionRect = null;
+                            if (bouncerAreaExclusion()) {
+                                exclusionRect = getCurrentExclusionRect();
+                            }
+                            handler.getTouchInitiationRegion(
+                                            maxBounds, initiationRegion, exclusionRect);
 
                     if (!initiationRegion.isEmpty()) {
                         // Initiation regions require a motion event to determine pointer location
@@ -335,6 +385,9 @@
                     .flatMap(Collection::stream)
                     .forEach(inputEventListener -> inputEventListener.onInputEvent(ev));
         }
+                    private Rect getCurrentExclusionRect() {
+                        return mExclusionRect;
+                    }
     };
 
     /**
@@ -416,6 +469,9 @@
 
     private InputSessionComponent.Factory mInputSessionFactory;
     private InputSession mCurrentInputSession;
+    private final int mDisplayId;
+    private final IWindowManager mWindowManagerService;
+
 
     /**
      * Designated constructor for {@link DreamOverlayTouchMonitor}
@@ -432,15 +488,21 @@
     @Inject
     public DreamOverlayTouchMonitor(
             @Main Executor executor,
+            @Background Executor backgroundExecutor,
             Lifecycle lifecycle,
             InputSessionComponent.Factory inputSessionFactory,
             DisplayHelper displayHelper,
-            Set<DreamTouchHandler> handlers) {
+            Set<DreamTouchHandler> handlers,
+            IWindowManager windowManagerService,
+            @DisplayId int displayId) {
+        mDisplayId = displayId;
         mHandlers = handlers;
         mInputSessionFactory = inputSessionFactory;
-        mExecutor = executor;
+        mMainExecutor = executor;
+        mBackgroundExecutor = backgroundExecutor;
         mLifecycle = lifecycle;
         mDisplayHelper = displayHelper;
+        mWindowManagerService = windowManagerService;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java
index 72ad45d..1ec0008 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamTouchHandler.java
@@ -104,7 +104,7 @@
      * indicating the entire screen should be considered.
      * @param region A {@link Region} that is passed in to the target entry touch region.
      */
-    default void getTouchInitiationRegion(Rect bounds, Region region) {
+    default void getTouchInitiationRegion(Rect bounds, Region region, Rect exclusionRect) {
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/ShadeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/ShadeTouchHandler.java
index 6f05e83..e0bf52e 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/ShadeTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/ShadeTouchHandler.java
@@ -82,7 +82,7 @@
     }
 
     @Override
-    public void getTouchInitiationRegion(Rect bounds, Region region) {
+    public void getTouchInitiationRegion(Rect bounds, Region region, Rect exclusionRect) {
         final Rect outBounds = new Rect(bounds);
         outBounds.inset(0, 0, 0, outBounds.height() - mInitiationHeight);
         region.op(outBounds, Region.Op.UNION);
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java
index 8cf11a9..a5db2ff 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/dagger/BouncerSwipeModule.java
@@ -21,10 +21,10 @@
 import android.util.TypedValue;
 import android.view.VelocityTracker;
 
-import com.android.systemui.res.R;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.dreams.touch.BouncerSwipeTouchHandler;
 import com.android.systemui.dreams.touch.DreamTouchHandler;
+import com.android.systemui.res.R;
 import com.android.systemui.shade.ShadeViewController;
 import com.android.wm.shell.animation.FlingAnimationUtils;
 
@@ -46,6 +46,9 @@
      */
     public static final String SWIPE_TO_BOUNCER_START_REGION = "swipe_to_bouncer_start_region";
 
+    public static final String MIN_BOUNCER_ZONE_SCREEN_PERCENTAGE =
+            "min_bouncer_zone_screen_percentage";
+
     /**
      * The {@link android.view.animation.AnimationUtils} for animating the bouncer closing.
      */
@@ -110,6 +113,18 @@
     }
 
     /**
+     * Provides the minimum region to start wipe gestures from.
+     */
+    @Provides
+    @Named(MIN_BOUNCER_ZONE_SCREEN_PERCENTAGE)
+    public static float providesMinBouncerZoneScreenPercentage(@Main Resources resources) {
+        TypedValue typedValue = new TypedValue();
+        resources.getValue(R.dimen.dream_overlay_bouncer_min_region_screen_percentage,
+                typedValue, true);
+        return typedValue.getFloat();
+    }
+
+    /**
      * Provides the default {@link BouncerSwipeTouchHandler.ValueAnimatorCreator}, which is simply
      * a wrapper around {@link ValueAnimator}.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt b/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt
index 1bcee74..8b1f8d3 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FlagDependencies.kt
@@ -53,7 +53,7 @@
 
         // SceneContainer dependencies
         SceneContainerFlag.getFlagDependencies().forEach { (alpha, beta) -> alpha dependsOn beta }
-        SceneContainerFlag.getMainStaticFlag() dependsOn MIGRATE_KEYGUARD_STATUS_BAR_VIEW
+        SceneContainerFlag.getMainAconfigFlag() dependsOn MIGRATE_KEYGUARD_STATUS_BAR_VIEW
 
         // ComposeLockscreen dependencies
         ComposeLockscreen.token dependsOn KeyguardBottomAreaRefactor.token
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index d33e7ff..640534c 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -387,10 +387,6 @@
     // TODO(b/273800936): Tracking Bug
     @JvmField val TRACKPAD_GESTURE_COMMON = releasedFlag("trackpad_gesture_common")
 
-    // 1300 - screenshots
-    // TODO(b/264916608): Tracking Bug
-    @JvmField val SCREENSHOT_METADATA = unreleasedFlag("screenshot_metadata")
-
     // TODO(b/251205791): Tracking Bug
     @JvmField val SCREENSHOT_APP_CLIPS = releasedFlag("screenshot_app_clips")
 
@@ -414,21 +410,6 @@
     val CLIPBOARD_SHARED_TRANSITIONS =
             unreleasedFlag("clipboard_shared_transitions", teamfood = true)
 
-    /**
-     * Whether the scene container (Flexiglass) is enabled. Note that SceneContainerFlags#isEnabled
-     * should be checked and toggled together with [SCENE_CONTAINER_ENABLED] so that ProGuard can
-     * remove unused code from our APK at compile time.
-     */
-    // TODO(b/283300105): Tracking Bug
-    @JvmField val SCENE_CONTAINER_ENABLED = false
-
-    /**
-     * Whether the compose bouncer is enabled. This ensures ProGuard can
-     * remove unused code from our APK at compile time.
-     */
-    // TODO(b/280877228): Tracking Bug
-    @JvmField val COMPOSE_BOUNCER_ENABLED = false
-
     // 1900
     @JvmField val NOTE_TASKS = releasedFlag("keycode_flag")
 
diff --git a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt
index 1705909..f4998a7 100644
--- a/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/haptics/qs/QSLongPressEffectViewBinder.kt
@@ -18,10 +18,10 @@
 
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.qs.tileimpl.QSTileViewImpl
 import kotlinx.coroutines.DisposableHandle
-import kotlinx.coroutines.launch
 
 class QSLongPressEffectViewBinder {
 
@@ -31,16 +31,18 @@
 
     fun bind(
         tile: QSTileViewImpl,
+        tileSpec: String?,
         effect: QSLongPressEffect?,
     ) {
         if (effect == null) return
 
         handle =
             tile.repeatWhenAttached {
-                repeatOnLifecycle(Lifecycle.State.STARTED) {
+                repeatOnLifecycle(Lifecycle.State.CREATED) {
                     effect.scope = this
+                    val tag = "${tileSpec ?: "unknownTileSpec"}#LongPressEffect"
 
-                    launch {
+                    launch("$tag#progress") {
                         effect.effectProgress.collect { progress ->
                             progress?.let {
                                 if (it == 0f) {
@@ -51,7 +53,7 @@
                         }
                     }
 
-                    launch {
+                    launch("$tag#action") {
                         effect.actionType.collect { action ->
                             action?.let {
                                 when (it) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
index 3da3e2f..e6e6ff6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
@@ -35,12 +35,13 @@
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.keyguard.KeyguardStatusView
 import com.android.keyguard.KeyguardStatusViewController
+import com.android.keyguard.LegacyLockIconViewController
 import com.android.keyguard.LockIconView
-import com.android.keyguard.LockIconViewController
 import com.android.keyguard.dagger.KeyguardStatusViewComponent
 import com.android.systemui.CoreStartable
 import com.android.systemui.common.ui.ConfigurationState
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor
 import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
@@ -72,6 +73,7 @@
 import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
 import dagger.Lazy
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.DisposableHandle
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 
@@ -95,7 +97,7 @@
     private val configuration: ConfigurationState,
     private val context: Context,
     private val keyguardIndicationController: KeyguardIndicationController,
-    private val lockIconViewController: Lazy<LockIconViewController>,
+    private val lockIconViewController: Lazy<LegacyLockIconViewController>,
     private val shadeInteractor: ShadeInteractor,
     private val interactionJankMonitor: InteractionJankMonitor,
     private val deviceEntryHapticsInteractor: DeviceEntryHapticsInteractor,
@@ -108,6 +110,7 @@
     private val keyguardBlueprintViewBinder: KeyguardBlueprintViewBinder,
     private val clockInteractor: KeyguardClockInteractor,
     private val keyguardViewMediator: KeyguardViewMediator,
+    @Main private val mainImmediateDispatcher: CoroutineDispatcher,
 ) : CoreStartable {
 
     private var rootViewHandle: DisposableHandle? = null
@@ -205,12 +208,13 @@
                 chipbarCoordinator,
                 screenOffAnimationController,
                 shadeInteractor,
-                { keyguardStatusViewController!!.getClockController() },
+                clockInteractor,
                 interactionJankMonitor,
                 deviceEntryHapticsInteractor,
                 vibratorHelper,
                 falsingManager,
                 keyguardViewMediator,
+                mainImmediateDispatcher,
             )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 53aee5d..654610e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -178,8 +178,6 @@
 import com.android.systemui.wallpapers.data.repository.WallpaperRepository;
 import com.android.wm.shell.keyguard.KeyguardTransitions;
 
-import dagger.Lazy;
-
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -189,6 +187,7 @@
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
+import dagger.Lazy;
 import kotlinx.coroutines.CoroutineDispatcher;
 
 /**
@@ -964,6 +963,13 @@
     @VisibleForTesting
     final ActivityTransitionAnimator.Controller mOccludeAnimationController =
             new ActivityTransitionAnimator.Controller() {
+                private boolean mIsLaunching = true;
+
+                @Override
+                public boolean isLaunching() {
+                    return mIsLaunching;
+                }
+
                 @Override
                 public void onTransitionAnimationStart(boolean isExpandingFullyAbove) {
                     mOccludeAnimationPlaying = true;
@@ -2147,13 +2153,6 @@
         mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_TRANSITION_FROM_AOD);
 
         synchronized (KeyguardViewMediator.this) {
-            if (mHiding && isOccluded) {
-                // We're in the process of going away but WindowManager wants to show a
-                // SHOW_WHEN_LOCKED activity instead.
-                // TODO(bc-unlock): Migrate to remote animation.
-                startKeyguardExitAnimation(0, 0);
-            }
-
             mPowerGestureIntercepted =
                     isOccluded && mUpdateMonitor.isSecureCameraLaunchedOverKeyguard();
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerOcclusionManager.kt b/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerOcclusionManager.kt
index aab90c3..585bd6a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerOcclusionManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WindowManagerOcclusionManager.kt
@@ -263,6 +263,7 @@
     @VisibleForTesting
     val occludeAnimationController: ActivityTransitionAnimator.Controller =
         object : ActivityTransitionAnimator.Controller {
+            override val isLaunching: Boolean = true
 
             override var transitionContainer: ViewGroup
                 get() = keyguardViewController.get().getViewRootImpl().view as ViewGroup
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
index 88eadd7..b3d9a76 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfig.kt
@@ -92,7 +92,8 @@
                 walletController.setupWalletChangeObservers(
                     callback,
                     QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE,
-                    QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE
+                    QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE,
+                    QuickAccessWalletController.WalletChangeEvent.DEFAULT_WALLET_APP_CHANGE
                 )
 
                 withContext(backgroundDispatcher) {
@@ -104,7 +105,8 @@
                 awaitClose {
                     walletController.unregisterWalletChangeObservers(
                         QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE,
-                        QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE
+                        QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE,
+                        QuickAccessWalletController.WalletChangeEvent.DEFAULT_WALLET_APP_CHANGE
                     )
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
index a36bf8b..4c54bfd 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt
@@ -22,7 +22,9 @@
 import android.annotation.FloatRange
 import android.os.Trace
 import android.util.Log
+import com.android.app.tracing.coroutines.withContext
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionInfo
 import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
@@ -30,10 +32,14 @@
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import java.util.UUID
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.channels.BufferOverflow
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asSharedFlow
+import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filter
 
@@ -65,6 +71,9 @@
      */
     val transitions: Flow<TransitionStep>
 
+    /** The [TransitionInfo] of the most recent call to [startTransition]. */
+    val currentTransitionInfoInternal: StateFlow<TransitionInfo>
+
     /**
      * Interactors that require information about changes between [KeyguardState]s will call this to
      * register themselves for flowable [TransitionStep]s when that transition occurs.
@@ -77,7 +86,7 @@
      * Begin a transition from one state to another. Transitions are interruptible, and will issue a
      * [TransitionStep] with state = [TransitionState.CANCELED] before beginning the next one.
      */
-    fun startTransition(info: TransitionInfo): UUID?
+    suspend fun startTransition(info: TransitionInfo): UUID?
 
     /**
      * Allows manual control of a transition. When calling [startTransition], the consumer must pass
@@ -95,7 +104,11 @@
 }
 
 @SysUISingleton
-class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitionRepository {
+class KeyguardTransitionRepositoryImpl
+@Inject
+constructor(
+    @Main val mainDispatcher: CoroutineDispatcher,
+) : KeyguardTransitionRepository {
     /*
      * Each transition between [KeyguardState]s will have an associated Flow.
      * In order to collect these events, clients should call [transition].
@@ -110,6 +123,17 @@
     private var lastStep: TransitionStep = TransitionStep()
     private var lastAnimator: ValueAnimator? = null
 
+    private val _currentTransitionInfo: MutableStateFlow<TransitionInfo> =
+        MutableStateFlow(
+            TransitionInfo(
+                ownerName = "",
+                from = KeyguardState.OFF,
+                to = KeyguardState.LOCKSCREEN,
+                animator = null
+            )
+        )
+    override var currentTransitionInfoInternal = _currentTransitionInfo.asStateFlow()
+
     /*
      * When manual control of the transition is requested, a unique [UUID] is used as the handle
      * to permit calls to [updateTransition]
@@ -122,77 +146,85 @@
         initialTransitionSteps.forEach(::emitTransition)
     }
 
-    override fun startTransition(info: TransitionInfo): UUID? {
-        if (lastStep.from == info.from && lastStep.to == info.to) {
-            Log.i(TAG, "Duplicate call to start the transition, rejecting: $info")
-            return null
-        }
-        val startingValue =
-            if (lastStep.transitionState != TransitionState.FINISHED) {
-                Log.i(TAG, "Transition still active: $lastStep, canceling")
-                when (info.modeOnCanceled) {
-                    TransitionModeOnCanceled.LAST_VALUE -> lastStep.value
-                    TransitionModeOnCanceled.RESET -> 0f
-                    TransitionModeOnCanceled.REVERSE -> 1f - lastStep.value
+    override suspend fun startTransition(info: TransitionInfo): UUID? {
+        _currentTransitionInfo.value = info
+
+        // Animators must be started on the main thread.
+        return withContext("$TAG#startTransition", mainDispatcher) {
+            if (lastStep.from == info.from && lastStep.to == info.to) {
+                Log.i(TAG, "Duplicate call to start the transition, rejecting: $info")
+                return@withContext null
+            }
+            val startingValue =
+                if (lastStep.transitionState != TransitionState.FINISHED) {
+                    Log.i(TAG, "Transition still active: $lastStep, canceling")
+                    when (info.modeOnCanceled) {
+                        TransitionModeOnCanceled.LAST_VALUE -> lastStep.value
+                        TransitionModeOnCanceled.RESET -> 0f
+                        TransitionModeOnCanceled.REVERSE -> 1f - lastStep.value
+                    }
+                } else {
+                    0f
                 }
-            } else {
-                0f
+
+            lastAnimator?.cancel()
+            lastAnimator = info.animator
+
+            // Cancel any existing manual transitions
+            updateTransitionId?.let { uuid ->
+                updateTransition(uuid, lastStep.value, TransitionState.CANCELED)
             }
 
-        lastAnimator?.cancel()
-        lastAnimator = info.animator
-
-        // Cancel any existing manual transitions
-        updateTransitionId?.let { uuid ->
-            updateTransition(uuid, lastStep.value, TransitionState.CANCELED)
-        }
-
-        info.animator?.let { animator ->
-            // An animator was provided, so use it to run the transition
-            animator.setFloatValues(startingValue, 1f)
-            animator.duration = ((1f - startingValue) * animator.duration).toLong()
-            val updateListener = AnimatorUpdateListener { animation ->
-                emitTransition(
-                    TransitionStep(
-                        info,
-                        (animation.animatedValue as Float),
-                        TransitionState.RUNNING
+            info.animator?.let { animator ->
+                // An animator was provided, so use it to run the transition
+                animator.setFloatValues(startingValue, 1f)
+                animator.duration = ((1f - startingValue) * animator.duration).toLong()
+                val updateListener = AnimatorUpdateListener { animation ->
+                    emitTransition(
+                        TransitionStep(
+                            info,
+                            (animation.animatedValue as Float),
+                            TransitionState.RUNNING
+                        )
                     )
-                )
-            }
-            val adapter =
-                object : AnimatorListenerAdapter() {
-                    override fun onAnimationStart(animation: Animator) {
-                        emitTransition(TransitionStep(info, startingValue, TransitionState.STARTED))
-                    }
-
-                    override fun onAnimationCancel(animation: Animator) {
-                        endAnimation(lastStep.value, TransitionState.CANCELED)
-                    }
-
-                    override fun onAnimationEnd(animation: Animator) {
-                        endAnimation(1f, TransitionState.FINISHED)
-                    }
-
-                    private fun endAnimation(value: Float, state: TransitionState) {
-                        emitTransition(TransitionStep(info, value, state))
-                        animator.removeListener(this)
-                        animator.removeUpdateListener(updateListener)
-                        lastAnimator = null
-                    }
                 }
-            animator.addListener(adapter)
-            animator.addUpdateListener(updateListener)
-            animator.start()
-            return@startTransition null
-        }
-            ?: run {
-                emitTransition(TransitionStep(info, startingValue, TransitionState.STARTED))
 
-                // No animator, so it's manual. Provide a mechanism to callback
-                updateTransitionId = UUID.randomUUID()
-                return@startTransition updateTransitionId
+                val adapter =
+                    object : AnimatorListenerAdapter() {
+                        override fun onAnimationStart(animation: Animator) {
+                            emitTransition(
+                                TransitionStep(info, startingValue, TransitionState.STARTED)
+                            )
+                        }
+
+                        override fun onAnimationCancel(animation: Animator) {
+                            endAnimation(lastStep.value, TransitionState.CANCELED)
+                        }
+
+                        override fun onAnimationEnd(animation: Animator) {
+                            endAnimation(1f, TransitionState.FINISHED)
+                        }
+
+                        private fun endAnimation(value: Float, state: TransitionState) {
+                            emitTransition(TransitionStep(info, value, state))
+                            animator.removeListener(this)
+                            animator.removeUpdateListener(updateListener)
+                            lastAnimator = null
+                        }
+                    }
+                animator.addListener(adapter)
+                animator.addUpdateListener(updateListener)
+                animator.start()
+                return@withContext null
             }
+                ?: run {
+                    emitTransition(TransitionStep(info, startingValue, TransitionState.STARTED))
+
+                    // No animator, so it's manual. Provide a mechanism to callback
+                    updateTransitionId = UUID.randomUUID()
+                    return@withContext updateTransitionId
+                }
+        }
     }
 
     override fun updateTransition(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt
index e017129..bf1f074 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractor.kt
@@ -26,6 +26,9 @@
 import com.android.systemui.keyguard.data.repository.BiometricType
 import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
 import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.SceneInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlags
+import com.android.systemui.scene.shared.model.Scenes
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
@@ -33,6 +36,7 @@
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.merge
 import kotlinx.coroutines.launch
@@ -48,6 +52,8 @@
     @Application private val applicationScope: CoroutineScope,
     @Application private val context: Context,
     deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository,
+    private val sceneContainerFlags: SceneContainerFlags,
+    private val sceneInteractor: SceneInteractor,
     private val primaryBouncerInteractor: PrimaryBouncerInteractor,
     alternateBouncerInteractor: AlternateBouncerInteractor,
     private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
@@ -65,16 +71,35 @@
         }
     }
 
+    private val isSideFpsIndicatorOnPrimaryBouncerEnabled: Boolean
+        get() = context.resources.getBoolean(R.bool.config_show_sidefps_hint_on_bouncer)
+
+    private val isBouncerSceneActive: Flow<Boolean> =
+        if (sceneContainerFlags.isEnabled()) {
+            sceneInteractor.currentScene.map { it == Scenes.Bouncer }.distinctUntilChanged()
+        } else {
+            flowOf(false)
+        }
+
     private val showIndicatorForPrimaryBouncer: Flow<Boolean> =
         merge(
+                // Legacy bouncer visibility changes.
                 primaryBouncerInteractor.isShowing,
                 primaryBouncerInteractor.startingToHide,
                 primaryBouncerInteractor.startingDisappearAnimation.filterNotNull(),
+                // Bouncer scene visibility changes.
+                isBouncerSceneActive,
                 deviceEntryFingerprintAuthRepository.shouldUpdateIndicatorVisibility.filter { it }
             )
-            .map { shouldShowIndicatorForPrimaryBouncer() }
+            .map {
+                isBouncerActive() &&
+                    isSideFpsIndicatorOnPrimaryBouncerEnabled &&
+                    keyguardUpdateMonitor.isFingerprintDetectionRunning &&
+                    keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed
+            }
 
     private val showIndicatorForAlternateBouncer: Flow<Boolean> =
+        // Note: this interactor internally verifies that SideFPS is enabled and running.
         alternateBouncerInteractor.isVisible
 
     /**
@@ -89,16 +114,11 @@
             }
             .distinctUntilChanged()
 
-    private fun shouldShowIndicatorForPrimaryBouncer(): Boolean {
-        val sfpsEnabled: Boolean =
-            context.resources.getBoolean(R.bool.config_show_sidefps_hint_on_bouncer)
-        val sfpsDetectionRunning = keyguardUpdateMonitor.isFingerprintDetectionRunning
-        val isUnlockingWithFpAllowed = keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed
-
+    private fun isBouncerActive(): Boolean {
+        if (sceneContainerFlags.isEnabled()) {
+            return sceneInteractor.currentScene.value == Scenes.Bouncer
+        }
         return primaryBouncerInteractor.isBouncerShowing() &&
-            sfpsEnabled &&
-            sfpsDetectionRunning &&
-            isUnlockingWithFpAllowed &&
             !primaryBouncerInteractor.isAnimatingAway()
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
index 47f8046a..dfe56c8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
@@ -100,40 +100,30 @@
                 .onEach { delay(150L) }
                 .sampleCombine(
                     keyguardInteractor.primaryBouncerShowing,
-                    startedKeyguardTransitionStep,
                     powerInteractor.isAwake,
                     keyguardInteractor.isAodAvailable,
                     communalInteractor.isIdleOnCommunal
                 )
-                .collect {
-                    (
-                        isAlternateBouncerShowing,
-                        isPrimaryBouncerShowing,
-                        lastStartedTransitionStep,
-                        isAwake,
-                        isAodAvailable,
-                        isIdleOnCommunal) ->
-                    if (
-                        !isAlternateBouncerShowing &&
-                            !isPrimaryBouncerShowing &&
-                            lastStartedTransitionStep.to == KeyguardState.ALTERNATE_BOUNCER
-                    ) {
-                        val to =
-                            if (!isAwake) {
-                                if (isAodAvailable) {
-                                    KeyguardState.AOD
-                                } else {
-                                    KeyguardState.DOZING
-                                }
+                .filterRelevantKeyguardStateAnd {
+                    (isAlternateBouncerShowing, isPrimaryBouncerShowing, _, _, _) ->
+                    !isAlternateBouncerShowing && !isPrimaryBouncerShowing
+                }
+                .collect { (_, _, isAwake, isAodAvailable, isIdleOnCommunal) ->
+                    val to =
+                        if (!isAwake) {
+                            if (isAodAvailable) {
+                                KeyguardState.AOD
                             } else {
-                                if (isIdleOnCommunal) {
-                                    KeyguardState.GLANCEABLE_HUB
-                                } else {
-                                    KeyguardState.LOCKSCREEN
-                                }
+                                KeyguardState.DOZING
                             }
-                        startTransitionTo(to)
-                    }
+                        } else {
+                            if (isIdleOnCommunal) {
+                                KeyguardState.GLANCEABLE_HUB
+                            } else {
+                                KeyguardState.LOCKSCREEN
+                            }
+                        }
+                    startTransitionTo(to)
                 }
         }
     }
@@ -158,15 +148,10 @@
     private fun listenForAlternateBouncerToPrimaryBouncer() {
         scope.launch {
             keyguardInteractor.primaryBouncerShowing
-                .sampleUtil(startedKeyguardTransitionStep, ::Pair)
-                .collect { (isPrimaryBouncerShowing, startedKeyguardState) ->
-                    if (
-                        isPrimaryBouncerShowing &&
-                            startedKeyguardState.to == KeyguardState.ALTERNATE_BOUNCER
-                    ) {
-                        startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
-                    }
+                .filterRelevantKeyguardStateAnd { isPrimaryBouncerShowing ->
+                    isPrimaryBouncerShowing
                 }
+                .collect { startTransitionTo(KeyguardState.PRIMARY_BOUNCER) }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
index d09ee54..f359525 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt
@@ -18,27 +18,22 @@
 
 import android.animation.ValueAnimator
 import com.android.app.animation.Interpolators
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.KeyguardWmStateRefactor
 import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
 import com.android.systemui.keyguard.shared.model.BiometricUnlockModel.Companion.isWakeAndUnlock
-import com.android.systemui.keyguard.shared.model.DozeStateModel
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
-import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.util.kotlin.Utils.Companion.sample
-import com.android.systemui.util.kotlin.sample
-import java.util.UUID
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.debounce
-import kotlinx.coroutines.flow.filter
-import kotlinx.coroutines.launch
 
 @SysUISingleton
 class FromAodTransitionInteractor
@@ -74,80 +69,73 @@
      * Listen for the signal that we're waking up and figure what state we need to transition to.
      */
     private fun listenForAodToAwake() {
-        val transitionToLockscreen: suspend (TransitionStep) -> UUID? =
-            { startedStep: TransitionStep ->
-                val modeOnCanceled =
-                    if (startedStep.from == KeyguardState.LOCKSCREEN) {
-                        TransitionModeOnCanceled.REVERSE
-                    } else if (startedStep.from == KeyguardState.GONE) {
-                        TransitionModeOnCanceled.RESET
-                    } else {
-                        TransitionModeOnCanceled.LAST_VALUE
-                    }
-                startTransitionTo(
-                    toState = KeyguardState.LOCKSCREEN,
-                    modeOnCanceled = modeOnCanceled,
+        // Use PowerInteractor's wakefulness, which is the earliest wake signal available. We
+        // have all of the information we need at this time to make a decision about where to
+        // transition.
+        scope.launch("$TAG#listenForAodToAwake") {
+            powerInteractor.detailedWakefulness
+                .filterRelevantKeyguardStateAnd { wakefulness -> wakefulness.isAwake() }
+                .sample(
+                    startedKeyguardTransitionStep,
+                    keyguardInteractor.biometricUnlockState,
+                    keyguardInteractor.primaryBouncerShowing,
+                    keyguardInteractor.isKeyguardShowing,
+                    keyguardInteractor.isKeyguardOccluded,
+                    keyguardInteractor.isKeyguardDismissible,
                 )
-            }
+                .collect {
+                    (
+                        _,
+                        startedStep,
+                        biometricUnlockState,
+                        primaryBouncerShowing,
+                        _,
+                        isKeyguardOccludedLegacy,
+                        _) ->
+                    if (!maybeHandleInsecurePowerGesture()) {
+                        val shouldTransitionToLockscreen =
+                            if (KeyguardWmStateRefactor.isEnabled) {
+                                // Check with the superclass to see if an occlusion transition is
+                                // needed. Also, don't react to wake and unlock events, as we'll be
+                                // receiving a call to #dismissAod() shortly when the authentication
+                                // completes.
+                                !maybeStartTransitionToOccludedOrInsecureCamera() &&
+                                    !isWakeAndUnlock(biometricUnlockState) &&
+                                    !primaryBouncerShowing
+                            } else {
+                                !isKeyguardOccludedLegacy &&
+                                    !isWakeAndUnlock(biometricUnlockState) &&
+                                    !primaryBouncerShowing
+                            }
 
-        if (KeyguardWmStateRefactor.isEnabled) {
-            // The refactor uses PowerInteractor's wakefulness, which is the earliest wake signal
-            // available. We have all of the information we need at this time to make a decision
-            // about where to transition.
-            scope.launch {
-                powerInteractor.detailedWakefulness
-                    // React only to wake events.
-                    .filter { it.isAwake() }
-                    .sample(
-                        startedKeyguardTransitionStep,
-                        keyguardInteractor.biometricUnlockState,
-                        keyguardInteractor.primaryBouncerShowing,
-                    )
-                    // Make sure we've at least STARTED a transition to AOD.
-                    .filter { (_, startedStep, _, _) -> startedStep.to == KeyguardState.AOD }
-                    .collect { (_, startedStep, biometricUnlockState, primaryBouncerShowing) ->
-                        // Check with the superclass to see if an occlusion transition is needed.
-                        // Also, don't react to wake and unlock events, as we'll be receiving a call
-                        // to #dismissAod() shortly when the authentication completes.
-                        if (
-                            !maybeStartTransitionToOccludedOrInsecureCamera() &&
-                                !isWakeAndUnlock(biometricUnlockState) &&
-                                !primaryBouncerShowing
-                        ) {
-                            transitionToLockscreen(startedStep)
+                        // With the refactor enabled, maybeStartTransitionToOccludedOrInsecureCamera
+                        // handles transitioning to OCCLUDED.
+                        val shouldTransitionToOccluded =
+                            !KeyguardWmStateRefactor.isEnabled && isKeyguardOccludedLegacy
+
+                        if (shouldTransitionToLockscreen) {
+                            val modeOnCanceled =
+                                if (startedStep.from == KeyguardState.LOCKSCREEN) {
+                                    TransitionModeOnCanceled.REVERSE
+                                } else if (startedStep.from == KeyguardState.GONE) {
+                                    TransitionModeOnCanceled.RESET
+                                } else {
+                                    TransitionModeOnCanceled.LAST_VALUE
+                                }
+
+                            startTransitionTo(
+                                toState = KeyguardState.LOCKSCREEN,
+                                modeOnCanceled = modeOnCanceled,
+                                ownerReason = "listen for aod to awake"
+                            )
+                        } else if (shouldTransitionToOccluded) {
+                            startTransitionTo(
+                                toState = KeyguardState.OCCLUDED,
+                                ownerReason = "waking up and isOccluded=true",
+                            )
                         }
                     }
-            }
-        } else {
-            scope.launch {
-                keyguardInteractor
-                    .dozeTransitionTo(DozeStateModel.FINISH)
-                    .sample(
-                        keyguardInteractor.isKeyguardShowing,
-                        startedKeyguardTransitionStep,
-                        keyguardInteractor.isKeyguardOccluded,
-                        keyguardInteractor.biometricUnlockState,
-                        keyguardInteractor.primaryBouncerShowing,
-                    )
-                    .collect {
-                        (
-                            _,
-                            isKeyguardShowing,
-                            lastStartedStep,
-                            occluded,
-                            biometricUnlockState,
-                            primaryBouncerShowing) ->
-                        if (
-                            lastStartedStep.to == KeyguardState.AOD &&
-                                !occluded &&
-                                !isWakeAndUnlock(biometricUnlockState) &&
-                                isKeyguardShowing &&
-                                !primaryBouncerShowing
-                        ) {
-                            transitionToLockscreen(lastStartedStep)
-                        }
-                    }
-            }
+                }
         }
     }
 
@@ -162,16 +150,15 @@
             return
         }
 
-        scope.launch {
+        scope.launch("$TAG#listenForAodToOccluded") {
             keyguardInteractor.isKeyguardOccluded
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { (isOccluded, lastStartedStep) ->
-                    if (isOccluded && lastStartedStep.to == KeyguardState.AOD) {
-                        startTransitionTo(
-                            toState = KeyguardState.OCCLUDED,
-                            modeOnCanceled = TransitionModeOnCanceled.RESET
-                        )
-                    }
+                .filterRelevantKeyguardStateAnd { isOccluded -> isOccluded }
+                .collect {
+                    startTransitionTo(
+                        toState = KeyguardState.OCCLUDED,
+                        modeOnCanceled = TransitionModeOnCanceled.RESET,
+                        ownerReason = "isOccluded = true",
+                    )
                 }
         }
     }
@@ -181,14 +168,10 @@
      * PRIMARY_BOUNCER.
      */
     private fun listenForAodToPrimaryBouncer() {
-        scope.launch {
+        scope.launch("$TAG#listenForAodToPrimaryBouncer") {
             keyguardInteractor.primaryBouncerShowing
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { (isBouncerShowing, lastStartedTransitionStep) ->
-                    if (isBouncerShowing && lastStartedTransitionStep.to == KeyguardState.AOD) {
-                        startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
-                    }
-                }
+                .filterRelevantKeyguardStateAnd { primaryBouncerShowing -> primaryBouncerShowing }
+                .collect { startTransitionTo(KeyguardState.PRIMARY_BOUNCER) }
         }
     }
 
@@ -198,26 +181,20 @@
             return
         }
 
-        scope.launch {
+        scope.launch("$TAG#listenForAodToGone") {
             powerInteractor.isAwake
                 .debounce(50L)
+                .filterRelevantKeyguardState()
                 .sample(
                     keyguardInteractor.biometricUnlockState,
-                    startedKeyguardTransitionStep,
                     keyguardInteractor.isKeyguardShowing,
                     keyguardInteractor.isKeyguardDismissible,
                 )
-                .collect {
-                    (
-                        isAwake,
-                        biometricUnlockState,
-                        lastStartedTransitionStep,
-                        isKeyguardShowing,
-                        isKeyguardDismissible) ->
+                .collect { (isAwake, biometricUnlockState, isKeyguardShowing, isKeyguardDismissible)
+                    ->
                     KeyguardWmStateRefactor.assertInLegacyMode()
                     if (
                         isAwake &&
-                            lastStartedTransitionStep.to == KeyguardState.AOD &&
                             (isWakeAndUnlock(biometricUnlockState) ||
                                 (!isKeyguardShowing && isKeyguardDismissible))
                     ) {
@@ -232,7 +209,7 @@
      * AOD.
      */
     fun dismissAod() {
-        scope.launch { startTransitionTo(KeyguardState.GONE) }
+        scope.launch("$TAG#dismissAod") { startTransitionTo(KeyguardState.GONE) }
     }
 
     override fun getDefaultAnimatorForTransitionsToState(toState: KeyguardState): ValueAnimator {
@@ -247,7 +224,7 @@
     }
 
     companion object {
-        const val TAG = "FromAodTransitionInteractor"
+        private const val TAG = "FromAodTransitionInteractor"
         private val DEFAULT_DURATION = 500.milliseconds
         val TO_LOCKSCREEN_DURATION = 500.milliseconds
         val TO_GONE_DURATION = DEFAULT_DURATION
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
index 57b2a63..ca7fc66 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDozingTransitionInteractor.kt
@@ -35,7 +35,6 @@
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.debounce
-import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.launch
 
 @SysUISingleton
@@ -83,9 +82,9 @@
         scope.launch {
             powerInteractor.isAwake
                 .debounce(50L)
+                .filterRelevantKeyguardStateAnd { isAwake -> isAwake }
                 .sample(
                     keyguardInteractor.biometricUnlockState,
-                    startedKeyguardTransitionStep,
                     keyguardInteractor.isKeyguardOccluded,
                     communalInteractor.isIdleOnCommunal,
                     canDismissLockScreen,
@@ -93,16 +92,12 @@
                 )
                 .collect {
                     (
-                        isAwake,
+                        _,
                         biometricUnlockState,
-                        lastStartedTransition,
                         occluded,
                         isIdleOnCommunal,
                         canDismissLockScreen,
                         primaryBouncerShowing) ->
-                    if (!(isAwake && lastStartedTransition.to == KeyguardState.DOZING)) {
-                        return@collect
-                    }
                     startTransitionTo(
                         if (isWakeAndUnlock(biometricUnlockState)) {
                             KeyguardState.GONE
@@ -130,20 +125,16 @@
 
         scope.launch {
             powerInteractor.detailedWakefulness
-                .filter { it.isAwake() }
+                .filterRelevantKeyguardStateAnd { it.isAwake() }
                 .sample(
-                    startedKeyguardTransitionStep,
                     communalInteractor.isIdleOnCommunal,
                     keyguardInteractor.biometricUnlockState,
                     canDismissLockScreen,
                     keyguardInteractor.primaryBouncerShowing,
                 )
-                // If we haven't at least STARTED a transition to DOZING, ignore.
-                .filter { (_, startedStep, _, _) -> startedStep.to == KeyguardState.DOZING }
                 .collect {
                     (
                         _,
-                        _,
                         isIdleOnCommunal,
                         biometricUnlockState,
                         canDismissLockscreen,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt
index 6433d0e..10d1e15 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingLockscreenHostedTransitionInteractor.kt
@@ -26,14 +26,12 @@
 import com.android.systemui.keyguard.shared.model.DozeStateModel
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.power.domain.interactor.PowerInteractor
-import com.android.systemui.util.kotlin.Utils.Companion.toTriple
 import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.delay
-import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.launch
 
@@ -73,91 +71,50 @@
                 // Add a slight delay to prevent transitioning to lockscreen from happening too soon
                 // as dozing can arrive in a slight gap after the lockscreen hosted dream stops.
                 .onEach { delay(50) }
-                .sample(
-                    combine(
-                        keyguardInteractor.dozeTransitionModel,
-                        startedKeyguardTransitionStep,
-                        ::Pair
-                    ),
-                    ::toTriple
-                )
-                .collect {
-                    (isActiveDreamLockscreenHosted, dozeTransitionModel, lastStartedTransition) ->
-                    if (
-                        !isActiveDreamLockscreenHosted &&
-                            DozeStateModel.isDozeOff(dozeTransitionModel.to) &&
-                            lastStartedTransition.to == KeyguardState.DREAMING_LOCKSCREEN_HOSTED
-                    ) {
-                        startTransitionTo(KeyguardState.LOCKSCREEN)
-                    }
+                .sample(keyguardInteractor.dozeTransitionModel, ::Pair)
+                .filterRelevantKeyguardStateAnd {
+                    (isActiveDreamLockscreenHosted, dozeTransitionModel) ->
+                    !isActiveDreamLockscreenHosted &&
+                        DozeStateModel.isDozeOff(dozeTransitionModel.to)
                 }
+                .collect { startTransitionTo(KeyguardState.LOCKSCREEN) }
         }
     }
 
     private fun listenForDreamingLockscreenHostedToOccluded() {
         scope.launch {
             keyguardInteractor.isActiveDreamLockscreenHosted
-                .sample(
-                    combine(
-                        keyguardInteractor.isKeyguardOccluded,
-                        startedKeyguardTransitionStep,
-                        ::Pair,
-                    ),
-                    ::toTriple
-                )
-                .collect { (isActiveDreamLockscreenHosted, isOccluded, lastStartedTransition) ->
-                    if (
-                        isOccluded &&
-                            !isActiveDreamLockscreenHosted &&
-                            lastStartedTransition.to == KeyguardState.DREAMING_LOCKSCREEN_HOSTED
-                    ) {
-                        startTransitionTo(KeyguardState.OCCLUDED)
-                    }
+                .sample(keyguardInteractor.isKeyguardOccluded, ::Pair)
+                .filterRelevantKeyguardStateAnd { (isActiveDreamLockscreenHosted, isOccluded) ->
+                    isOccluded && !isActiveDreamLockscreenHosted
                 }
+                .collect { startTransitionTo(KeyguardState.OCCLUDED) }
         }
     }
 
     private fun listenForDreamingLockscreenHostedToPrimaryBouncer() {
         scope.launch {
             keyguardInteractor.primaryBouncerShowing
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { (isBouncerShowing, lastStartedTransitionStep) ->
-                    if (
-                        isBouncerShowing &&
-                            lastStartedTransitionStep.to == KeyguardState.DREAMING_LOCKSCREEN_HOSTED
-                    ) {
-                        startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
-                    }
-                }
+                .filterRelevantKeyguardStateAnd { isBouncerShowing -> isBouncerShowing }
+                .collect { startTransitionTo(KeyguardState.PRIMARY_BOUNCER) }
         }
     }
 
     private fun listenForDreamingLockscreenHostedToGone() {
         scope.launch {
             keyguardInteractor.biometricUnlockState
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { (biometricUnlockState, lastStartedTransitionStep) ->
-                    if (
-                        lastStartedTransitionStep.to == KeyguardState.DREAMING_LOCKSCREEN_HOSTED &&
-                            biometricUnlockState == BiometricUnlockModel.WAKE_AND_UNLOCK_FROM_DREAM
-                    ) {
-                        startTransitionTo(KeyguardState.GONE)
-                    }
+                .filterRelevantKeyguardStateAnd { biometricUnlockState ->
+                    biometricUnlockState == BiometricUnlockModel.WAKE_AND_UNLOCK_FROM_DREAM
                 }
+                .collect { startTransitionTo(KeyguardState.GONE) }
         }
     }
 
     private fun listenForDreamingLockscreenHostedToDozing() {
         scope.launch {
-            combine(keyguardInteractor.dozeTransitionModel, startedKeyguardTransitionStep, ::Pair)
-                .collect { (dozeTransitionModel, lastStartedTransitionStep) ->
-                    if (
-                        dozeTransitionModel.to == DozeStateModel.DOZE &&
-                            lastStartedTransitionStep.to == KeyguardState.DREAMING_LOCKSCREEN_HOSTED
-                    ) {
-                        startTransitionTo(KeyguardState.DOZING)
-                    }
-                }
+            keyguardInteractor.dozeTransitionModel
+                .filterRelevantKeyguardStateAnd { it.to == DozeStateModel.DOZE }
+                .collect { startTransitionTo(KeyguardState.DOZING) }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
index 1f24fc2..bef5ee5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromDreamingTransitionInteractor.kt
@@ -29,17 +29,15 @@
 import com.android.systemui.keyguard.shared.model.DozeStateModel
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.power.domain.interactor.PowerInteractor
-import com.android.systemui.util.kotlin.Utils
 import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
-import com.android.systemui.util.kotlin.Utils.Companion.toTriple
-import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
 import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.FlowPreview
 import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.debounce
 import kotlinx.coroutines.launch
 
 @SysUISingleton
@@ -110,6 +108,7 @@
         }
     }
 
+    @OptIn(FlowPreview::class)
     private fun listenForDreamingToOccluded() {
         if (KeyguardWmStateRefactor.isEnabled) {
             scope.launch {
@@ -118,28 +117,30 @@
                         keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop,
                         ::Pair
                     )
-                    .sample(startedKeyguardTransitionStep, ::toTriple)
-                    .filter { (isDreaming, _, startedStep) ->
-                        !isDreaming && startedStep.to == KeyguardState.DREAMING
-                    }
+                    .filterRelevantKeyguardStateAnd { (isDreaming, _) -> !isDreaming }
                     .collect { maybeStartTransitionToOccludedOrInsecureCamera() }
             }
         } else {
             scope.launch {
                 combine(
                         keyguardInteractor.isKeyguardOccluded,
-                        keyguardInteractor.isDreaming,
+                        keyguardInteractor.isDreaming
+                            // Debounce the dreaming signal since there is a race condition between
+                            // the occluded and dreaming signals. We therefore add a small delay
+                            // to give enough time for occluded to flip to false when the dream
+                            // ends, to avoid transitioning to OCCLUDED erroneously when exiting
+                            // the dream.
+                            .debounce(100.milliseconds),
                         ::Pair
                     )
-                    .sample(startedKeyguardTransitionStep, Utils.Companion::toTriple)
-                    .collect { (isOccluded, isDreaming, lastStartedTransition) ->
-                        if (
-                            isOccluded &&
-                                !isDreaming &&
-                                lastStartedTransition.to == KeyguardState.DREAMING
-                        ) {
-                            startTransitionTo(KeyguardState.OCCLUDED)
-                        }
+                    .filterRelevantKeyguardStateAnd { (isOccluded, isDreaming) ->
+                        isOccluded && !isDreaming
+                    }
+                    .collect {
+                        startTransitionTo(
+                            toState = KeyguardState.OCCLUDED,
+                            ownerReason = "Occluded but no longer dreaming",
+                        )
                     }
             }
         }
@@ -152,13 +153,8 @@
 
         scope.launch {
             keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop
-                .filter { onTop -> !onTop }
-                .sample(startedKeyguardState)
-                .collect { startedState ->
-                    if (startedState == KeyguardState.DREAMING) {
-                        startTransitionTo(KeyguardState.LOCKSCREEN)
-                    }
-                }
+                .filterRelevantKeyguardStateAnd { onTop -> !onTop }
+                .collect { startTransitionTo(KeyguardState.LOCKSCREEN) }
         }
     }
 
@@ -168,49 +164,35 @@
                 .sampleCombine(
                     keyguardInteractor.isKeyguardShowing,
                     keyguardInteractor.isKeyguardDismissible,
-                    startedKeyguardTransitionStep,
                 )
-                .collect {
-                    (isDreaming, isKeyguardShowing, isKeyguardDismissible, lastStartedTransition) ->
-                    if (
-                        !isDreaming &&
-                            lastStartedTransition.to == KeyguardState.DREAMING &&
-                            isKeyguardDismissible &&
-                            !isKeyguardShowing
-                    ) {
-                        startTransitionTo(KeyguardState.GONE)
-                    }
+                .filterRelevantKeyguardStateAnd {
+                    (isDreaming, isKeyguardShowing, isKeyguardDismissible) ->
+                    !isDreaming && isKeyguardDismissible && !isKeyguardShowing
                 }
+                .collect { startTransitionTo(KeyguardState.GONE) }
         }
     }
 
     private fun listenForDreamingToGoneFromBiometricUnlock() {
         scope.launch {
             keyguardInteractor.biometricUnlockState
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { (biometricUnlockState, lastStartedTransitionStep) ->
-                    if (
-                        lastStartedTransitionStep.to == KeyguardState.DREAMING &&
-                            biometricUnlockState == BiometricUnlockModel.WAKE_AND_UNLOCK_FROM_DREAM
-                    ) {
-                        startTransitionTo(KeyguardState.GONE)
-                    }
+                .filterRelevantKeyguardStateAnd { biometricUnlockState ->
+                    biometricUnlockState == BiometricUnlockModel.WAKE_AND_UNLOCK_FROM_DREAM
                 }
+                .collect { startTransitionTo(KeyguardState.GONE) }
         }
     }
 
     private fun listenForDreamingToAodOrDozing() {
         scope.launch {
-            combine(keyguardInteractor.dozeTransitionModel, finishedKeyguardState, ::Pair)
-                .collect { (dozeTransitionModel, keyguardState) ->
-                    if (keyguardState == KeyguardState.DREAMING) {
-                        if (dozeTransitionModel.to == DozeStateModel.DOZE) {
-                            startTransitionTo(KeyguardState.DOZING)
-                        } else if (dozeTransitionModel.to == DozeStateModel.DOZE_AOD) {
-                            startTransitionTo(KeyguardState.AOD)
-                        }
-                    }
+            keyguardInteractor.dozeTransitionModel.filterRelevantKeyguardState().collect {
+                dozeTransitionModel ->
+                if (dozeTransitionModel.to == DozeStateModel.DOZE) {
+                    startTransitionTo(KeyguardState.DOZING)
+                } else if (dozeTransitionModel.to == DozeStateModel.DOZE_AOD) {
+                    startTransitionTo(KeyguardState.AOD)
                 }
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
index 51bc3ae..54d9a78 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
@@ -30,13 +30,11 @@
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.util.kotlin.BooleanFlowOperators.and
 import com.android.systemui.util.kotlin.BooleanFlowOperators.not
-import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.collectLatest
-import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 
@@ -113,46 +111,31 @@
     private fun listenForHubToPrimaryBouncer() {
         scope.launch("$TAG#listenForHubToPrimaryBouncer") {
             keyguardInteractor.primaryBouncerShowing
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { pair ->
-                    val (isBouncerShowing, lastStartedTransitionStep) = pair
-                    if (
-                        isBouncerShowing &&
-                            lastStartedTransitionStep.to == KeyguardState.GLANCEABLE_HUB
-                    ) {
-                        startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
-                    }
-                }
+                .filterRelevantKeyguardStateAnd { primaryBouncerShowing -> primaryBouncerShowing }
+                .collect { startTransitionTo(KeyguardState.PRIMARY_BOUNCER) }
         }
     }
 
     private fun listenForHubToAlternateBouncer() {
         scope.launch("$TAG#listenForHubToAlternateBouncer") {
             keyguardInteractor.alternateBouncerShowing
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { pair ->
-                    val (isAlternateBouncerShowing, lastStartedTransitionStep) = pair
-                    if (
-                        isAlternateBouncerShowing &&
-                            lastStartedTransitionStep.to == KeyguardState.GLANCEABLE_HUB
-                    ) {
-                        startTransitionTo(KeyguardState.ALTERNATE_BOUNCER)
-                    }
+                .filterRelevantKeyguardStateAnd { alternateBouncerShowing ->
+                    alternateBouncerShowing
                 }
+                .collect { pair -> startTransitionTo(KeyguardState.ALTERNATE_BOUNCER) }
         }
     }
 
     private fun listenForHubToDozing() {
         scope.launch {
-            powerInteractor.isAsleep.sample(startedKeyguardTransitionStep, ::Pair).collect {
-                (isAsleep, lastStartedStep) ->
-                if (lastStartedStep.to == fromState && isAsleep) {
+            powerInteractor.isAsleep
+                .filterRelevantKeyguardStateAnd { isAsleep -> isAsleep }
+                .collect {
                     startTransitionTo(
                         toState = KeyguardState.DOZING,
                         modeOnCanceled = TransitionModeOnCanceled.LAST_VALUE,
                     )
                 }
-            }
         }
     }
 
@@ -160,22 +143,17 @@
         if (KeyguardWmStateRefactor.isEnabled) {
             scope.launch {
                 keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop
-                    .filter { onTop -> onTop }
-                    .sample(startedKeyguardState)
-                    .collect {
-                        if (it == KeyguardState.GLANCEABLE_HUB) {
-                            maybeStartTransitionToOccludedOrInsecureCamera()
-                        }
-                    }
+                    .filterRelevantKeyguardStateAnd { onTop -> onTop }
+                    .collect { maybeStartTransitionToOccludedOrInsecureCamera() }
             }
         } else {
             scope.launch {
                 and(keyguardInteractor.isKeyguardOccluded, not(keyguardInteractor.isDreaming))
-                    .sample(startedKeyguardState, ::Pair)
-                    .collect { (isOccludedAndNotDreaming, keyguardState) ->
-                        if (isOccludedAndNotDreaming && keyguardState == fromState) {
-                            startTransitionTo(KeyguardState.OCCLUDED)
-                        }
+                    .filterRelevantKeyguardStateAnd { isOccludedAndNotDreaming ->
+                        isOccludedAndNotDreaming
+                    }
+                    .collect { isOccludedAndNotDreaming ->
+                        startTransitionTo(KeyguardState.OCCLUDED)
                     }
             }
         }
@@ -184,12 +162,8 @@
     private fun listenForHubToGone() {
         scope.launch {
             keyguardInteractor.isKeyguardGoingAway
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { (isKeyguardGoingAway, lastStartedStep) ->
-                    if (isKeyguardGoingAway && lastStartedStep.to == fromState) {
-                        startTransitionTo(KeyguardState.GONE)
-                    }
-                }
+                .filterRelevantKeyguardStateAnd { isKeyguardGoingAway -> isKeyguardGoingAway }
+                .collect { startTransitionTo(KeyguardState.GONE) }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
index 4a3232e..c2c095b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt
@@ -18,6 +18,7 @@
 
 import android.animation.ValueAnimator
 import com.android.app.animation.Interpolators
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
@@ -28,16 +29,12 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
 import com.android.systemui.power.domain.interactor.PowerInteractor
-import com.android.systemui.util.kotlin.Utils.Companion.sample
-import com.android.systemui.util.kotlin.Utils.Companion.toTriple
 import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.launch
 
 @SysUISingleton
@@ -72,93 +69,69 @@
     }
 
     fun showKeyguard() {
-        scope.launch { startTransitionTo(KeyguardState.LOCKSCREEN) }
+        scope.launch("$TAG#showKeyguard") { startTransitionTo(KeyguardState.LOCKSCREEN) }
     }
 
     // Primarily for when the user chooses to lock down the device
     private fun listenForGoneToLockscreenOrHub() {
         if (KeyguardWmStateRefactor.isEnabled) {
-            scope.launch {
+            scope.launch("$TAG#listenForGoneToLockscreenOrHub") {
                 biometricSettingsRepository.isCurrentUserInLockdown
                     .distinctUntilChanged()
-                    .filter { inLockdown -> inLockdown }
-                    .sample(
-                        startedKeyguardState,
-                        communalInteractor.isIdleOnCommunal,
-                    )
-                    .collect { (_, startedState, isIdleOnCommunal) ->
-                        if (startedState == KeyguardState.GONE) {
-                            val to =
-                                if (isIdleOnCommunal) {
-                                    KeyguardState.GLANCEABLE_HUB
-                                } else {
-                                    KeyguardState.LOCKSCREEN
-                                }
-                            startTransitionTo(to, ownerReason = "User initiated lockdown")
-                        }
+                    .filterRelevantKeyguardStateAnd { inLockdown -> inLockdown }
+                    .sample(communalInteractor.isIdleOnCommunal, ::Pair)
+                    .collect { (_, isIdleOnCommunal) ->
+                        val to =
+                            if (isIdleOnCommunal) {
+                                KeyguardState.GLANCEABLE_HUB
+                            } else {
+                                KeyguardState.LOCKSCREEN
+                            }
+                        startTransitionTo(to, ownerReason = "User initiated lockdown")
                     }
             }
         } else {
-            scope.launch {
+            scope.launch("$TAG#listenForGoneToLockscreenOrHub") {
                 keyguardInteractor.isKeyguardShowing
-                    .sample(
-                        startedKeyguardState,
-                        communalInteractor.isIdleOnCommunal,
-                    )
-                    .collect { (isKeyguardShowing, startedState, isIdleOnCommunal) ->
-                        if (isKeyguardShowing && startedState == KeyguardState.GONE) {
-                            val to =
-                                if (isIdleOnCommunal) {
-                                    KeyguardState.GLANCEABLE_HUB
-                                } else {
-                                    KeyguardState.LOCKSCREEN
-                                }
-                            startTransitionTo(to)
-                        }
+                    .filterRelevantKeyguardStateAnd { isKeyguardShowing -> isKeyguardShowing }
+                    .sample(communalInteractor.isIdleOnCommunal, ::Pair)
+                    .collect { (_, isIdleOnCommunal) ->
+                        val to =
+                            if (isIdleOnCommunal) {
+                                KeyguardState.GLANCEABLE_HUB
+                            } else {
+                                KeyguardState.LOCKSCREEN
+                            }
+                        startTransitionTo(to)
                     }
             }
         }
     }
 
     private fun listenForGoneToDreamingLockscreenHosted() {
-        scope.launch {
+        scope.launch("$TAG#listenForGoneToDreamingLockscreenHosted") {
             keyguardInteractor.isActiveDreamLockscreenHosted
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { (isActiveDreamLockscreenHosted, lastStartedStep) ->
-                    if (isActiveDreamLockscreenHosted && lastStartedStep.to == KeyguardState.GONE) {
-                        startTransitionTo(KeyguardState.DREAMING_LOCKSCREEN_HOSTED)
-                    }
+                .filterRelevantKeyguardStateAnd { isActiveDreamLockscreenHosted ->
+                    isActiveDreamLockscreenHosted
                 }
+                .collect { startTransitionTo(KeyguardState.DREAMING_LOCKSCREEN_HOSTED) }
         }
     }
 
     private fun listenForGoneToDreaming() {
-        scope.launch {
+        scope.launch("$TAG#listenForGoneToDreaming") {
             keyguardInteractor.isAbleToDream
-                .sample(
-                    combine(
-                        startedKeyguardTransitionStep,
-                        keyguardInteractor.isActiveDreamLockscreenHosted,
-                        ::Pair
-                    ),
-                    ::toTriple
-                )
-                .collect { (isAbleToDream, lastStartedStep, isActiveDreamLockscreenHosted) ->
-                    if (
-                        isAbleToDream &&
-                            lastStartedStep.to == KeyguardState.GONE &&
-                            !isActiveDreamLockscreenHosted
-                    ) {
-                        startTransitionTo(KeyguardState.DREAMING)
-                    }
+                .sample(keyguardInteractor.isActiveDreamLockscreenHosted, ::Pair)
+                .filterRelevantKeyguardStateAnd { (isAbleToDream, isActiveDreamLockscreenHosted) ->
+                    isAbleToDream && !isActiveDreamLockscreenHosted
                 }
+                .collect { startTransitionTo(KeyguardState.DREAMING) }
         }
     }
 
     private fun listenForGoneToAodOrDozing() {
-        scope.launch {
+        scope.launch("$TAG#listenForGoneToAodOrDozing") {
             listenForSleepTransition(
-                from = KeyguardState.GONE,
                 modeOnCanceledFromStartedStep = { TransitionModeOnCanceled.RESET },
             )
         }
@@ -179,6 +152,7 @@
     }
 
     companion object {
+        private const val TAG = "FromGoneTransitionInteractor"
         private val DEFAULT_DURATION = 500.milliseconds
         val TO_DREAMING_DURATION = 933.milliseconds
         val TO_AOD_DURATION = 1300.milliseconds
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
index 2649d43..56261e0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt
@@ -19,6 +19,7 @@
 import android.animation.ValueAnimator
 import android.util.MathUtils
 import com.android.app.animation.Interpolators
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
@@ -32,8 +33,7 @@
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.shade.data.repository.ShadeRepository
-import com.android.systemui.util.kotlin.Utils.Companion.toQuad
-import com.android.systemui.util.kotlin.sample
+import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
 import java.util.UUID
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
@@ -41,14 +41,11 @@
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
 
 @SysUISingleton
 class FromLockscreenTransitionInteractor
@@ -123,27 +120,24 @@
         }
 
         val invalidFromStates = setOf(KeyguardState.AOD, KeyguardState.DOZING)
-        scope.launch {
+        scope.launch("$TAG#listenForLockscreenToDreaming") {
             keyguardInteractor.isAbleToDream
-                .sample(
-                    combine(
-                        startedKeyguardTransitionStep,
-                        finishedKeyguardState,
-                        keyguardInteractor.isActiveDreamLockscreenHosted,
-                        ::Triple
-                    ),
-                    ::toQuad
+                .filterRelevantKeyguardState()
+                .sampleCombine(
+                    transitionInteractor.currentTransitionInfoInternal,
+                    finishedKeyguardState,
+                    keyguardInteractor.isActiveDreamLockscreenHosted,
                 )
                 .collect {
                     (
                         isAbleToDream,
-                        lastStartedTransition,
+                        transitionInfo,
                         finishedKeyguardState,
                         isActiveDreamLockscreenHosted) ->
                     val isOnLockscreen = finishedKeyguardState == KeyguardState.LOCKSCREEN
                     val isTransitionInterruptible =
-                        lastStartedTransition.to == KeyguardState.LOCKSCREEN &&
-                            !invalidFromStates.contains(lastStartedTransition.from)
+                        transitionInfo.to == KeyguardState.LOCKSCREEN &&
+                            !invalidFromStates.contains(transitionInfo.from)
                     if (isAbleToDream && (isOnLockscreen || isTransitionInterruptible)) {
                         if (isActiveDreamLockscreenHosted) {
                             startTransitionTo(KeyguardState.DREAMING_LOCKSCREEN_HOSTED)
@@ -156,118 +150,108 @@
     }
 
     private fun listenForLockscreenToPrimaryBouncer() {
-        scope.launch {
+        scope.launch("$TAG#listenForLockscreenToPrimaryBouncer") {
             keyguardInteractor.primaryBouncerShowing
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { pair ->
-                    val (isBouncerShowing, lastStartedTransitionStep) = pair
-                    if (
-                        isBouncerShowing && lastStartedTransitionStep.to == KeyguardState.LOCKSCREEN
-                    ) {
-                        startTransitionTo(
-                            KeyguardState.PRIMARY_BOUNCER,
-                            ownerReason = "#listenForLockscreenToPrimaryBouncer"
-                        )
-                    }
+                .filterRelevantKeyguardStateAnd { isBouncerShowing -> isBouncerShowing }
+                .collect {
+                    startTransitionTo(
+                        KeyguardState.PRIMARY_BOUNCER,
+                        ownerReason = "#listenForLockscreenToPrimaryBouncer"
+                    )
                 }
         }
     }
 
     private fun listenForLockscreenToAlternateBouncer() {
-        scope.launch {
+        scope.launch("$TAG#listenForLockscreenToAlternateBouncer") {
             keyguardInteractor.alternateBouncerShowing
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { pair ->
-                    val (isAlternateBouncerShowing, lastStartedTransitionStep) = pair
-                    if (
-                        isAlternateBouncerShowing &&
-                            lastStartedTransitionStep.to == KeyguardState.LOCKSCREEN
-                    ) {
-                        startTransitionTo(KeyguardState.ALTERNATE_BOUNCER)
-                    }
+                .filterRelevantKeyguardStateAnd { isAlternateBouncerShowing ->
+                    isAlternateBouncerShowing
                 }
+                .collect { pair -> startTransitionTo(KeyguardState.ALTERNATE_BOUNCER) }
         }
     }
 
     /* Starts transitions when manually dragging up the bouncer from the lockscreen. */
     private fun listenForLockscreenToPrimaryBouncerDragging() {
         var transitionId: UUID? = null
-        scope.launch {
+        scope.launch("$TAG#listenForLockscreenToPrimaryBouncerDragging") {
             shadeRepository.legacyShadeExpansion
-                .sample(
-                    combine(
-                        startedKeyguardTransitionStep,
-                        keyguardInteractor.statusBarState,
-                        keyguardInteractor.isKeyguardDismissible,
-                        ::Triple
-                    ),
-                    ::toQuad
+                .sampleCombine(
+                    startedKeyguardTransitionStep,
+                    transitionInteractor.currentTransitionInfoInternal,
+                    keyguardInteractor.statusBarState,
+                    keyguardInteractor.isKeyguardDismissible,
                 )
-                .collect { (shadeExpansion, keyguardState, statusBarState, isKeyguardUnlocked) ->
-                    withContext(mainDispatcher) {
-                        val id = transitionId
-                        if (id != null) {
-                            if (keyguardState.to == KeyguardState.PRIMARY_BOUNCER) {
-                                // An existing `id` means a transition is started, and calls to
-                                // `updateTransition` will control it until FINISHED or CANCELED
-                                var nextState =
-                                    if (shadeExpansion == 0f) {
-                                        TransitionState.FINISHED
-                                    } else if (shadeExpansion == 1f) {
-                                        TransitionState.CANCELED
-                                    } else {
-                                        TransitionState.RUNNING
-                                    }
-                                transitionRepository.updateTransition(
-                                    id,
-                                    // This maps the shadeExpansion to a much faster curve, to match
-                                    // the existing logic
-                                    1f -
-                                        MathUtils.constrainedMap(0f, 1f, 0.95f, 1f, shadeExpansion),
-                                    nextState,
-                                )
-
-                                if (
-                                    nextState == TransitionState.CANCELED ||
-                                        nextState == TransitionState.FINISHED
-                                ) {
-                                    transitionId = null
+                .collect {
+                    (
+                        shadeExpansion,
+                        startedStep,
+                        currentTransitionInfo,
+                        statusBarState,
+                        isKeyguardUnlocked) ->
+                    val id = transitionId
+                    if (id != null) {
+                        if (startedStep.to == KeyguardState.PRIMARY_BOUNCER) {
+                            // An existing `id` means a transition is started, and calls to
+                            // `updateTransition` will control it until FINISHED or CANCELED
+                            var nextState =
+                                if (shadeExpansion == 0f) {
+                                    TransitionState.FINISHED
+                                } else if (shadeExpansion == 1f) {
+                                    TransitionState.CANCELED
+                                } else {
+                                    TransitionState.RUNNING
                                 }
+                            transitionRepository.updateTransition(
+                                id,
+                                // This maps the shadeExpansion to a much faster curve, to match
+                                // the existing logic
+                                1f - MathUtils.constrainedMap(0f, 1f, 0.95f, 1f, shadeExpansion),
+                                nextState,
+                            )
 
-                                // If canceled, just put the state back
-                                // TODO(b/278086361): This logic should happen in
-                                //  FromPrimaryBouncerInteractor.
-                                if (nextState == TransitionState.CANCELED) {
-                                    transitionRepository.startTransition(
-                                        TransitionInfo(
-                                            ownerName = name,
-                                            from = KeyguardState.PRIMARY_BOUNCER,
-                                            to = KeyguardState.LOCKSCREEN,
-                                            animator =
-                                                getDefaultAnimatorForTransitionsToState(
-                                                        KeyguardState.LOCKSCREEN
-                                                    )
-                                                    .apply { duration = 0 }
-                                        )
-                                    )
-                                }
-                            }
-                        } else {
-                            // TODO (b/251849525): Remove statusbarstate check when that state is
-                            // integrated into KeyguardTransitionRepository
                             if (
-                                keyguardState.to == KeyguardState.LOCKSCREEN &&
-                                    shadeRepository.legacyShadeTracking.value &&
-                                    !isKeyguardUnlocked &&
-                                    statusBarState == KEYGUARD
+                                nextState == TransitionState.CANCELED ||
+                                    nextState == TransitionState.FINISHED
                             ) {
-                                transitionId =
-                                    startTransitionTo(
-                                        toState = KeyguardState.PRIMARY_BOUNCER,
-                                        animator = null, // transition will be manually controlled,
-                                        ownerReason = "#listenForLockscreenToPrimaryBouncerDragging"
-                                    )
+                                transitionId = null
                             }
+
+                            // If canceled, just put the state back
+                            // TODO(b/278086361): This logic should happen in
+                            //  FromPrimaryBouncerInteractor.
+                            if (nextState == TransitionState.CANCELED) {
+                                transitionRepository.startTransition(
+                                    TransitionInfo(
+                                        ownerName = name,
+                                        from = KeyguardState.PRIMARY_BOUNCER,
+                                        to = KeyguardState.LOCKSCREEN,
+                                        animator =
+                                            getDefaultAnimatorForTransitionsToState(
+                                                    KeyguardState.LOCKSCREEN
+                                                )
+                                                .apply { duration = 0 }
+                                    )
+                                )
+                            }
+                        }
+                    } else {
+                        // TODO (b/251849525): Remove statusbarstate check when that state is
+                        // integrated into KeyguardTransitionRepository
+                        if (
+                            // Use currentTransitionInfo to decide whether to start the transition.
+                            currentTransitionInfo.to == KeyguardState.LOCKSCREEN &&
+                                shadeRepository.legacyShadeTracking.value &&
+                                !isKeyguardUnlocked &&
+                                statusBarState == KEYGUARD
+                        ) {
+                            transitionId =
+                                startTransitionTo(
+                                    toState = KeyguardState.PRIMARY_BOUNCER,
+                                    animator = null, // transition will be manually controlled,
+                                    ownerReason = "#listenForLockscreenToPrimaryBouncerDragging"
+                                )
                         }
                     }
                 }
@@ -275,7 +259,7 @@
     }
 
     fun dismissKeyguard() {
-        scope.launch { startTransitionTo(KeyguardState.GONE) }
+        scope.launch("$TAG#dismissKeyguard") { startTransitionTo(KeyguardState.GONE) }
     }
 
     private fun listenForLockscreenToGone() {
@@ -283,17 +267,14 @@
             return
         }
 
-        scope.launch {
+        scope.launch("$TAG#listenForLockscreenToGone") {
             keyguardInteractor.isKeyguardGoingAway
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { pair ->
-                    val (isKeyguardGoingAway, lastStartedStep) = pair
-                    if (isKeyguardGoingAway && lastStartedStep.to == KeyguardState.LOCKSCREEN) {
-                        startTransitionTo(
-                            KeyguardState.GONE,
-                            modeOnCanceled = TransitionModeOnCanceled.RESET,
-                        )
-                    }
+                .filterRelevantKeyguardStateAnd { isKeyguardGoingAway -> isKeyguardGoingAway }
+                .collect {
+                    startTransitionTo(
+                        KeyguardState.GONE,
+                        modeOnCanceled = TransitionModeOnCanceled.RESET,
+                    )
                 }
         }
     }
@@ -301,49 +282,42 @@
     private fun listenForLockscreenToGoneDragging() {
         if (KeyguardWmStateRefactor.isEnabled) {
             // When the refactor is enabled, we no longer use isKeyguardGoingAway.
-            scope.launch {
-                swipeToDismissInteractor.dismissFling.filterNotNull().collect { _ ->
-                    startTransitionTo(KeyguardState.GONE)
-                }
+            scope.launch("$TAG#listenForLockscreenToGoneDragging") {
+                swipeToDismissInteractor.dismissFling
+                    .filterNotNull()
+                    .filterRelevantKeyguardState()
+                    .collect { _ -> startTransitionTo(KeyguardState.GONE) }
             }
         }
     }
 
     private fun listenForLockscreenToOccludedOrDreaming() {
         if (KeyguardWmStateRefactor.isEnabled) {
-            scope.launch {
+            scope.launch("$TAG#listenForLockscreenToOccludedOrDreaming") {
                 keyguardOcclusionInteractor.showWhenLockedActivityInfo
-                    .filter { it.isOnTop }
-                    .sample(startedKeyguardState, ::Pair)
-                    .collect { (taskInfo, startedState) ->
-                        if (startedState == KeyguardState.LOCKSCREEN) {
-                            startTransitionTo(
-                                if (taskInfo.isDream()) {
-                                    KeyguardState.DREAMING
-                                } else {
-                                    KeyguardState.OCCLUDED
-                                }
-                            )
-                        }
+                    .filterRelevantKeyguardStateAnd { it.isOnTop }
+                    .collect { taskInfo ->
+                        startTransitionTo(
+                            if (taskInfo.isDream()) {
+                                KeyguardState.DREAMING
+                            } else {
+                                KeyguardState.OCCLUDED
+                            }
+                        )
                     }
             }
         } else {
-            scope.launch {
+            scope.launch("$TAG#listenForLockscreenToOccludedOrDreaming") {
                 keyguardInteractor.isKeyguardOccluded
-                    .sample(startedKeyguardState, ::Pair)
-                    .collect { (isOccluded, keyguardState) ->
-                        if (isOccluded && keyguardState == KeyguardState.LOCKSCREEN) {
-                            startTransitionTo(KeyguardState.OCCLUDED)
-                        }
-                    }
+                    .filterRelevantKeyguardStateAnd { isOccluded -> isOccluded }
+                    .collect { startTransitionTo(KeyguardState.OCCLUDED) }
             }
         }
     }
 
     private fun listenForLockscreenToAodOrDozing() {
-        scope.launch {
+        scope.launch("$TAG#listenForLockscreenToAodOrDozing") {
             listenForSleepTransition(
-                from = KeyguardState.LOCKSCREEN,
                 modeOnCanceledFromStartedStep = { startedStep ->
                     if (
                         transitionInteractor.asleepKeyguardState.value == KeyguardState.AOD &&
@@ -394,7 +368,7 @@
     }
 
     companion object {
-        const val TAG = "FromLockscreenTransitionInteractor"
+        private const val TAG = "FromLockscreenTransitionInteractor"
         private val DEFAULT_DURATION = 400.milliseconds
         val TO_DOZING_DURATION = 500.milliseconds
         val TO_DREAMING_DURATION = 933.milliseconds
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
index a0ab869..b6289d4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromOccludedTransitionInteractor.kt
@@ -32,7 +32,6 @@
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.launch
 
 @SysUISingleton
@@ -70,25 +69,16 @@
     private fun listenForOccludedToPrimaryBouncer() {
         scope.launch {
             keyguardInteractor.primaryBouncerShowing
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { (isBouncerShowing, lastStartedTransitionStep) ->
-                    if (
-                        isBouncerShowing && lastStartedTransitionStep.to == KeyguardState.OCCLUDED
-                    ) {
-                        startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
-                    }
-                }
+                .filterRelevantKeyguardStateAnd { isBouncerShowing -> isBouncerShowing }
+                .collect { startTransitionTo(KeyguardState.PRIMARY_BOUNCER) }
         }
     }
 
     private fun listenForOccludedToDreaming() {
         scope.launch {
-            keyguardInteractor.isAbleToDream.sample(finishedKeyguardState, ::Pair).collect {
-                (isAbleToDream, keyguardState) ->
-                if (isAbleToDream && keyguardState == KeyguardState.OCCLUDED) {
-                    startTransitionTo(KeyguardState.DREAMING)
-                }
-            }
+            keyguardInteractor.isAbleToDream
+                .filterRelevantKeyguardStateAnd { isAbleToDream -> isAbleToDream }
+                .collect { startTransitionTo(KeyguardState.DREAMING) }
         }
     }
 
@@ -96,23 +86,18 @@
         if (KeyguardWmStateRefactor.isEnabled) {
             scope.launch {
                 keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop
-                    .filter { onTop -> !onTop }
-                    .sample(
-                        startedKeyguardState,
-                        communalInteractor.isIdleOnCommunal,
-                    )
-                    .collect { (_, startedState, isIdleOnCommunal) ->
+                    .filterRelevantKeyguardStateAnd { onTop -> !onTop }
+                    .sample(communalInteractor.isIdleOnCommunal, ::Pair)
+                    .collect { (_, isIdleOnCommunal) ->
                         // Occlusion signals come from the framework, and should interrupt any
                         // existing transition
-                        if (startedState == KeyguardState.OCCLUDED) {
-                            val to =
-                                if (isIdleOnCommunal) {
-                                    KeyguardState.GLANCEABLE_HUB
-                                } else {
-                                    KeyguardState.LOCKSCREEN
-                                }
-                            startTransitionTo(to)
-                        }
+                        val to =
+                            if (isIdleOnCommunal) {
+                                KeyguardState.GLANCEABLE_HUB
+                            } else {
+                                KeyguardState.LOCKSCREEN
+                            }
+                        startTransitionTo(to)
                     }
             }
         } else {
@@ -120,26 +105,21 @@
                 keyguardInteractor.isKeyguardOccluded
                     .sample(
                         keyguardInteractor.isKeyguardShowing,
-                        startedKeyguardTransitionStep,
                         communalInteractor.isIdleOnCommunal,
                     )
-                    .collect { (isOccluded, isShowing, lastStartedKeyguardState, isIdleOnCommunal)
-                        ->
+                    .filterRelevantKeyguardStateAnd { (isOccluded, isShowing, _) ->
+                        !isOccluded && isShowing
+                    }
+                    .collect { (_, _, isIdleOnCommunal) ->
                         // Occlusion signals come from the framework, and should interrupt any
                         // existing transition
-                        if (
-                            !isOccluded &&
-                                isShowing &&
-                                lastStartedKeyguardState.to == KeyguardState.OCCLUDED
-                        ) {
-                            val to =
-                                if (isIdleOnCommunal) {
-                                    KeyguardState.GLANCEABLE_HUB
-                                } else {
-                                    KeyguardState.LOCKSCREEN
-                                }
-                            startTransitionTo(to)
-                        }
+                        val to =
+                            if (isIdleOnCommunal) {
+                                KeyguardState.GLANCEABLE_HUB
+                            } else {
+                                KeyguardState.LOCKSCREEN
+                            }
+                        startTransitionTo(to)
                     }
             }
         }
@@ -156,20 +136,12 @@
 
         scope.launch {
             keyguardInteractor.isKeyguardOccluded
-                .sample(
-                    keyguardInteractor.isKeyguardShowing,
-                    startedKeyguardTransitionStep,
-                )
-                .collect { (isOccluded, isShowing, lastStartedKeyguardState) ->
+                .sample(keyguardInteractor.isKeyguardShowing, ::Pair)
+                .filterRelevantKeyguardStateAnd { (occluded, showing) -> !occluded && !showing }
+                .collect {
                     // Occlusion signals come from the framework, and should interrupt any
                     // existing transition
-                    if (
-                        !isOccluded &&
-                            !isShowing &&
-                            lastStartedKeyguardState.to == KeyguardState.OCCLUDED
-                    ) {
-                        startTransitionTo(KeyguardState.GONE)
-                    }
+                    startTransitionTo(KeyguardState.GONE)
                 }
         }
     }
@@ -179,21 +151,16 @@
     }
 
     private fun listenForOccludedToAsleep() {
-        scope.launch { listenForSleepTransition(from = KeyguardState.OCCLUDED) }
+        scope.launch { listenForSleepTransition() }
     }
 
     private fun listenForOccludedToAlternateBouncer() {
         scope.launch {
             keyguardInteractor.alternateBouncerShowing
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { (isAlternateBouncerShowing, lastStartedTransitionStep) ->
-                    if (
-                        isAlternateBouncerShowing &&
-                            lastStartedTransitionStep.to == KeyguardState.OCCLUDED
-                    ) {
-                        startTransitionTo(KeyguardState.ALTERNATE_BOUNCER)
-                    }
+                .filterRelevantKeyguardStateAnd { isAlternateBouncerShowing ->
+                    isAlternateBouncerShowing
                 }
+                .collect { startTransitionTo(KeyguardState.ALTERNATE_BOUNCER) }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
index c7fafba..181a551 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromPrimaryBouncerTransitionInteractor.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.power.domain.interactor.PowerInteractor
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
 import com.android.systemui.util.kotlin.Utils.Companion.sample
-import com.android.systemui.util.kotlin.Utils.Companion.toTriple
 import com.android.systemui.util.kotlin.sample
 import com.android.wm.shell.animation.Interpolators
 import javax.inject.Inject
@@ -40,7 +39,6 @@
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.onStart
 import kotlinx.coroutines.launch
 
@@ -104,21 +102,14 @@
             scope.launch {
                 keyguardInteractor.primaryBouncerShowing
                     .sample(
-                        startedKeyguardTransitionStep,
                         powerInteractor.isAwake,
                         keyguardInteractor.isActiveDreamLockscreenHosted,
                         communalInteractor.isIdleOnCommunal
                     )
-                    .filter { (_, startedStep, _, _) ->
-                        startedStep.to == KeyguardState.PRIMARY_BOUNCER
-                    }
+                    .filterRelevantKeyguardState()
                     .collect {
-                        (
-                            isBouncerShowing,
-                            _,
-                            isAwake,
-                            isActiveDreamLockscreenHosted,
-                            isIdleOnCommunal) ->
+                        (isBouncerShowing, isAwake, isActiveDreamLockscreenHosted, isIdleOnCommunal)
+                        ->
                         if (
                             !maybeStartTransitionToOccludedOrInsecureCamera() &&
                                 !isBouncerShowing &&
@@ -140,69 +131,45 @@
                 keyguardInteractor.primaryBouncerShowing
                     .sample(
                         powerInteractor.isAwake,
-                        startedKeyguardTransitionStep,
                         keyguardInteractor.isKeyguardOccluded,
                         keyguardInteractor.isDreaming,
                         keyguardInteractor.isActiveDreamLockscreenHosted,
                         communalInteractor.isIdleOnCommunal,
                     )
-                    .collect {
-                        (
-                            isBouncerShowing,
-                            isAwake,
-                            lastStartedTransitionStep,
-                            occluded,
-                            isDreaming,
-                            isActiveDreamLockscreenHosted,
-                            isIdleOnCommunal) ->
-                        if (
-                            !isBouncerShowing &&
-                                lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER &&
-                                isAwake &&
-                                !isActiveDreamLockscreenHosted
-                        ) {
-                            val toState =
-                                if (occluded && !isDreaming) {
-                                    KeyguardState.OCCLUDED
-                                } else if (isIdleOnCommunal) {
-                                    KeyguardState.GLANCEABLE_HUB
-                                } else if (isDreaming) {
-                                    KeyguardState.DREAMING
-                                } else {
-                                    KeyguardState.LOCKSCREEN
-                                }
-                            startTransitionTo(toState)
-                        }
+                    .filterRelevantKeyguardStateAnd {
+                        (isBouncerShowing, isAwake, _, _, isActiveDreamLockscreenHosted, _) ->
+                        !isBouncerShowing && isAwake && !isActiveDreamLockscreenHosted
+                    }
+                    .collect { (_, _, occluded, isDreaming, _, isIdleOnCommunal) ->
+                        val toState =
+                            if (occluded && !isDreaming) {
+                                KeyguardState.OCCLUDED
+                            } else if (isIdleOnCommunal) {
+                                KeyguardState.GLANCEABLE_HUB
+                            } else if (isDreaming) {
+                                KeyguardState.DREAMING
+                            } else {
+                                KeyguardState.LOCKSCREEN
+                            }
+                        startTransitionTo(toState)
                     }
             }
         }
     }
 
     private fun listenForPrimaryBouncerToAsleep() {
-        scope.launch { listenForSleepTransition(from = KeyguardState.PRIMARY_BOUNCER) }
+        scope.launch { listenForSleepTransition() }
     }
 
     private fun listenForPrimaryBouncerToDreamingLockscreenHosted() {
         scope.launch {
             keyguardInteractor.primaryBouncerShowing
-                .sample(
-                    combine(
-                        keyguardInteractor.isActiveDreamLockscreenHosted,
-                        startedKeyguardTransitionStep,
-                        ::Pair
-                    ),
-                    ::toTriple
-                )
-                .collect {
-                    (isBouncerShowing, isActiveDreamLockscreenHosted, lastStartedTransitionStep) ->
-                    if (
-                        !isBouncerShowing &&
-                            isActiveDreamLockscreenHosted &&
-                            lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER
-                    ) {
-                        startTransitionTo(KeyguardState.DREAMING_LOCKSCREEN_HOSTED)
-                    }
+                .sample(keyguardInteractor.isActiveDreamLockscreenHosted, ::Pair)
+                .filterRelevantKeyguardStateAnd { (isBouncerShowing, isActiveDreamLockscreenHosted)
+                    ->
+                    !isBouncerShowing && isActiveDreamLockscreenHosted
                 }
+                .collect { startTransitionTo(KeyguardState.DREAMING_LOCKSCREEN_HOSTED) }
         }
     }
 
@@ -216,33 +183,28 @@
 
         scope.launch {
             keyguardInteractor.isKeyguardGoingAway
-                .sample(startedKeyguardTransitionStep, ::Pair)
-                .collect { (isKeyguardGoingAway, lastStartedTransitionStep) ->
-                    if (
-                        isKeyguardGoingAway &&
-                            lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER
-                    ) {
-                        val securityMode =
-                            keyguardSecurityModel.getSecurityMode(
-                                selectedUserInteractor.getSelectedUserId()
-                            )
-                        // IME for password requires a slightly faster animation
-                        val duration =
-                            if (securityMode == KeyguardSecurityModel.SecurityMode.Password) {
-                                TO_GONE_SHORT_DURATION
-                            } else {
-                                TO_GONE_DURATION
-                            }
-
-                        startTransitionTo(
-                            toState = KeyguardState.GONE,
-                            animator =
-                                getDefaultAnimatorForTransitionsToState(KeyguardState.GONE).apply {
-                                    this.duration = duration.inWholeMilliseconds
-                                },
-                            modeOnCanceled = TransitionModeOnCanceled.RESET,
+                .filterRelevantKeyguardStateAnd { isKeyguardGoingAway -> isKeyguardGoingAway }
+                .collect {
+                    val securityMode =
+                        keyguardSecurityModel.getSecurityMode(
+                            selectedUserInteractor.getSelectedUserId()
                         )
-                    }
+                    // IME for password requires a slightly faster animation
+                    val duration =
+                        if (securityMode == KeyguardSecurityModel.SecurityMode.Password) {
+                            TO_GONE_SHORT_DURATION
+                        } else {
+                            TO_GONE_DURATION
+                        }
+
+                    startTransitionTo(
+                        toState = KeyguardState.GONE,
+                        animator =
+                            getDefaultAnimatorForTransitionsToState(KeyguardState.GONE).apply {
+                                this.duration = duration.inWholeMilliseconds
+                            },
+                        modeOnCanceled = TransitionModeOnCanceled.RESET,
+                    )
                 }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt
index d492135..d551c9b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt
@@ -17,7 +17,9 @@
 
 package com.android.systemui.keyguard.domain.interactor
 
+import android.util.Log
 import com.android.keyguard.ClockEventController
+import com.android.keyguard.KeyguardClockSwitch
 import com.android.keyguard.KeyguardClockSwitch.ClockSize
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.data.repository.KeyguardClockRepository
@@ -29,8 +31,7 @@
 import kotlinx.coroutines.flow.StateFlow
 
 private val TAG = KeyguardClockInteractor::class.simpleName
-/** Manages keyguard clock for the lockscreen root view. */
-/** Encapsulates business-logic related to the keyguard clock. */
+/** Manages and ecapsulates the clock components of the lockscreen root view. */
 @SysUISingleton
 class KeyguardClockInteractor
 @Inject
@@ -46,6 +47,8 @@
 
     val previewClock: Flow<ClockController> = keyguardClockRepository.previewClock
 
+    val clockEventController: ClockEventController by keyguardClockRepository::clockEventController
+
     var clock: ClockController? by keyguardClockRepository.clockEventController::clock
 
     val clockSize: StateFlow<Int> = keyguardClockRepository.clockSize
@@ -53,8 +56,19 @@
         keyguardClockRepository.setClockSize(size)
     }
 
-    val clockEventController: ClockEventController
+    val renderedClockId: ClockId
         get() {
-            return keyguardClockRepository.clockEventController
+            return clock?.let { clock -> clock.config.id }
+                ?: run {
+                    Log.e(TAG, "No clock is available")
+                    KeyguardClockSwitch.MISSING_CLOCK_ID
+                }
         }
+
+    fun animateFoldToAod(foldFraction: Float) {
+        clock?.let { clock ->
+            clock.smallClock.animations.fold(foldFraction)
+            clock.largeClock.animations.fold(foldFraction)
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
index 851eafa..2182fe3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt
@@ -49,6 +49,7 @@
 import com.android.systemui.shade.data.repository.ShadeRepository
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
+import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
 import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
 import javax.inject.Provider
@@ -192,7 +193,7 @@
     val isKeyguardShowing: Flow<Boolean> = repository.isKeyguardShowing
 
     /** Whether the keyguard is dismissible or not. */
-    val isKeyguardDismissible: Flow<Boolean> = repository.isKeyguardDismissible
+    val isKeyguardDismissible: StateFlow<Boolean> = repository.isKeyguardDismissible
 
     /** Whether the keyguard is occluded (covered by an activity). */
     @Deprecated("Use KeyguardTransitionInteractor + KeyguardState.OCCLUDED")
@@ -279,12 +280,16 @@
      * signal should be sent directly to transitions.
      */
     val dismissAlpha: Flow<Float?> =
-        combine(
-                shadeRepository.legacyShadeExpansion,
+        shadeRepository.legacyShadeExpansion
+            .filter { it < 1f }
+            .sampleCombine(
                 statusBarState,
                 keyguardTransitionInteractor.currentKeyguardState,
                 isKeyguardDismissible,
-            ) { legacyShadeExpansion, statusBarState, currentKeyguardState, isKeyguardDismissible ->
+            )
+            .map {
+                (legacyShadeExpansion, statusBarState, currentKeyguardState, isKeyguardDismissible)
+                ->
                 if (
                     statusBarState == StatusBarState.KEYGUARD &&
                         isKeyguardDismissible &&
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt
index 03ed567..4abd6c6 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardOcclusionInteractor.kt
@@ -107,7 +107,7 @@
      */
     val occludingActivityWillDismissKeyguard: StateFlow<Boolean> =
         if (SceneContainerFlag.isEnabled) {
-                deviceUnlockedInteractor.get().isDeviceUnlocked
+                deviceUnlockedInteractor.get().deviceUnlockStatus.map { it.isUnlocked }
             } else {
                 keyguardInteractor.isKeyguardDismissible
             }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
index 68ea5d0..141cca3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionAuditLogger.kt
@@ -21,6 +21,7 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.log.core.LogLevel.VERBOSE
 import com.android.systemui.power.domain.interactor.PowerInteractor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel
 import javax.inject.Inject
@@ -69,9 +70,11 @@
             }
         }
 
-        scope.launch {
-            sharedNotificationContainerViewModel.bounds.collect {
-                logger.log(TAG, VERBOSE, "Notif: bounds", it)
+        if (!SceneContainerFlag.isEnabled) {
+            scope.launch {
+                sharedNotificationContainerViewModel.bounds.collect {
+                    logger.log(TAG, VERBOSE, "Notif: bounds", it)
+                }
             }
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
index 804b630..97081d9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt
@@ -35,6 +35,7 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
 import com.android.systemui.keyguard.shared.model.KeyguardState.OFF
 import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
+import com.android.systemui.keyguard.shared.model.TransitionInfo
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.util.kotlin.pairwise
@@ -391,6 +392,31 @@
             .distinctUntilChanged()
             .shareIn(scope, SharingStarted.Eagerly, replay = 1)
 
+    /**
+     * The [TransitionInfo] of the most recent call to
+     * [KeyguardTransitionRepository.startTransition].
+     *
+     * This should only be used by keyguard transition internals (From*TransitionInteractor and
+     * related classes). Other consumers of keyguard state in System UI should use
+     * [startedKeyguardState], [currentKeyguardState], and related flows.
+     *
+     * Keyguard internals use this to determine the most up-to-date KeyguardState that we've
+     * requested a transition to, even if the animator running the transition on the main thread has
+     * not yet emitted the STARTED TransitionStep.
+     *
+     * For example: if we're finished in GONE and press the power button twice very quickly, we may
+     * request a transition to AOD, but then receive the second power button press prior to the
+     * STARTED -> AOD transition step emitting. We still need the FromAodTransitionInteractor to
+     * request a transition from AOD -> LOCKSCREEN in response to the power press, even though the
+     * main thread animator hasn't emitted STARTED > AOD yet (which means [startedKeyguardState] is
+     * still GONE, which is not relevant to FromAodTransitionInteractor). In this case, the
+     * interactor can use this current transition info to determine that a STARTED -> AOD step
+     * *will* be emitted, and therefore that it can safely request an AOD -> LOCKSCREEN transition
+     * which will subsequently cancel GONE -> AOD.
+     */
+    internal val currentTransitionInfoInternal: StateFlow<TransitionInfo> =
+        repository.currentTransitionInfoInternal
+
     /** Whether we've currently STARTED a transition and haven't yet FINISHED it. */
     val isInTransitionToAnyState = isInTransitionWhere({ true }, { true })
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/ToAodFoldTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/ToAodFoldTransitionInteractor.kt
new file mode 100644
index 0000000..6729246
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/ToAodFoldTransitionInteractor.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.keyguard.domain.interactor
+
+import android.animation.ValueAnimator
+import android.view.ViewGroup
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
+import com.android.systemui.keyguard.shared.model.TransitionInfo
+import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
+import com.android.systemui.shade.NotificationPanelViewController
+import com.android.systemui.shade.ShadeFoldAnimator
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+@SysUISingleton
+class ToAodFoldTransitionInteractor
+@Inject
+constructor(
+    private val keyguardClockInteractor: KeyguardClockInteractor,
+    private val transitionInteractor: KeyguardTransitionInteractor,
+    private val transitionRepository: KeyguardTransitionRepository,
+    @Application private val mainScope: CoroutineScope,
+    @Main private val mainDispatcher: CoroutineDispatcher,
+) {
+    private var parentAnimator: NotificationPanelViewController.ShadeFoldAnimatorImpl? = null
+
+    // TODO(b/331770313): Migrate to PowerInteractor; Deprecate ShadeFoldAnimator again
+    val foldAnimator =
+        object : ShadeFoldAnimator {
+            override val view: ViewGroup?
+                get() = throw NotImplementedError("Deprecated. Do not call.")
+
+            override fun prepareFoldToAodAnimation() {
+                forceToAod()
+                parentAnimator?.prepareFoldToAodAnimation()
+            }
+
+            override fun startFoldToAodAnimation(
+                startAction: Runnable,
+                endAction: Runnable,
+                cancelAction: Runnable
+            ) {
+                parentAnimator?.let {
+                    it.buildViewAnimator(startAction, endAction, cancelAction)
+                        .setUpdateListener {
+                            keyguardClockInteractor.animateFoldToAod(it.animatedFraction)
+                        }
+                        .start()
+                }
+            }
+
+            override fun cancelFoldToAodAnimation() {
+                parentAnimator?.cancelFoldToAodAnimation()
+            }
+        }
+
+    fun initialize(parentAnimator: ShadeFoldAnimator) {
+        this.parentAnimator =
+            parentAnimator as? NotificationPanelViewController.ShadeFoldAnimatorImpl?
+    }
+
+    /** Forces the keyguard into AOD or Doze */
+    private fun forceToAod() {
+        mainScope.launch(mainDispatcher) {
+            transitionRepository.startTransition(
+                TransitionInfo(
+                    "$TAG (Fold transition triggered)",
+                    transitionInteractor.getCurrentState(),
+                    transitionInteractor.asleepKeyguardState.value,
+                    ValueAnimator().apply { duration = 0 },
+                    TransitionModeOnCanceled.LAST_VALUE,
+                )
+            )
+        }
+    }
+
+    companion object {
+        private val TAG = ToAodFoldTransitionInteractor::class.simpleName!!
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
index 375df3e..e456a55 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/TransitionInteractor.kt
@@ -29,11 +29,11 @@
 import java.util.UUID
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
 
 /**
  * Each TransitionInteractor is responsible for determining under which conditions to notify
@@ -78,32 +78,38 @@
         // a bugreport.
         ownerReason: String = "",
     ): UUID? {
-        if (
-            fromState != transitionInteractor.startedKeyguardState.replayCache.last() &&
-                fromState != transitionInteractor.finishedKeyguardState.replayCache.last()
-        ) {
+        if (fromState != transitionInteractor.currentTransitionInfoInternal.value.to) {
             Log.e(
                 name,
-                "startTransition: We were asked to transition from " +
-                    "$fromState to $toState, however we last finished a transition to " +
-                    "${transitionInteractor.finishedKeyguardState.replayCache.last()}, " +
-                    "and last started a transition to " +
-                    "${transitionInteractor.startedKeyguardState.replayCache.last()}. " +
-                    "Ignoring startTransition, but this should never happen."
+                "Ignoring startTransition: This interactor asked to transition from " +
+                    "$fromState -> $toState, but we last transitioned to " +
+                    "${transitionInteractor.currentTransitionInfoInternal.value.to}, not " +
+                    "$fromState. This should never happen - check currentTransitionInfoInternal " +
+                    "or use filterRelevantKeyguardState before starting transitions."
             )
+
+            if (fromState == transitionInteractor.finishedKeyguardState.replayCache.last()) {
+                Log.e(
+                    name,
+                    "This transition would not have been ignored prior to ag/26681239, since we " +
+                        "are FINISHED in $fromState (but have since started another transition). " +
+                        "If ignoring this transition has caused a regression, fix it by ensuring " +
+                        "that transitions are exclusively started from the most recently started " +
+                        "state."
+                )
+            }
             return null
         }
-        return withContext(mainDispatcher) {
-            transitionRepository.startTransition(
-                TransitionInfo(
-                    name + if (ownerReason.isNotBlank()) "($ownerReason)" else "",
-                    fromState,
-                    toState,
-                    animator,
-                    modeOnCanceled,
-                )
+
+        return transitionRepository.startTransition(
+            TransitionInfo(
+                name + if (ownerReason.isNotBlank()) "($ownerReason)" else "",
+                fromState,
+                toState,
+                animator,
+                modeOnCanceled,
             )
-        }
+        )
     }
 
     /**
@@ -114,25 +120,15 @@
      * Returns true if a transition was started, false otherwise.
      */
     suspend fun maybeStartTransitionToOccludedOrInsecureCamera(): Boolean {
+        // The refactor is required for the occlusion interactor to work.
+        KeyguardWmStateRefactor.isUnexpectedlyInLegacyMode()
+
+        // Check if we should start a transition from the power gesture.
         if (keyguardOcclusionInteractor.shouldTransitionFromPowerButtonGesture()) {
-            if (transitionInteractor.getCurrentState() == KeyguardState.GONE) {
-                // If the current state is GONE when the launch gesture is triggered, it means we
-                // were in transition from GONE -> DOZING/AOD due to the first power button tap. The
-                // second tap indicates that the user's intent was actually to launch the unlocked
-                // (insecure) camera, so we should transition back to GONE.
-                startTransitionTo(
-                    KeyguardState.GONE,
-                    ownerReason = "Power button gesture while GONE"
-                )
-            } else if (keyguardOcclusionInteractor.occludingActivityWillDismissKeyguard.value) {
-                // The double tap gesture occurred while not GONE (AOD/LOCKSCREEN/etc.), but the
-                // keyguard is dismissable. The activity launch will dismiss the keyguard, so we
-                // should transition to GONE.
-                startTransitionTo(
-                    KeyguardState.GONE,
-                    ownerReason = "Power button gesture on dismissable keyguard"
-                )
-            } else {
+            // See if we handled the insecure power gesture. If not, then we'll be launching the
+            // secure camera. Once KeyguardWmStateRefactor is fully enabled, we can clean up this
+            // code path by pulling maybeHandleInsecurePowerGesture() into this conditional.
+            if (!maybeHandleInsecurePowerGesture()) {
                 // Otherwise, the double tap gesture occurred while not GONE and not dismissable,
                 // which means we will launch the secure camera, which OCCLUDES the keyguard.
                 startTransitionTo(
@@ -159,6 +155,43 @@
     }
 
     /**
+     * Transition to [KeyguardState.GONE] for the insecure power button launch gesture, if the
+     * conditions to do so are met.
+     *
+     * Called from [FromAodTransitionInteractor] if [KeyguardWmStateRefactor] is not enabled, or
+     * [maybeStartTransitionToOccludedOrInsecureCamera] if it's enabled.
+     */
+    @Deprecated("Will be merged into maybeStartTransitionToOccludedOrInsecureCamera")
+    suspend fun maybeHandleInsecurePowerGesture(): Boolean {
+        if (keyguardOcclusionInteractor.shouldTransitionFromPowerButtonGesture()) {
+            if (transitionInteractor.getCurrentState() == KeyguardState.GONE) {
+                // If the current state is GONE when the launch gesture is triggered, it means we
+                // were in transition from GONE -> DOZING/AOD due to the first power button tap. The
+                // second tap indicates that the user's intent was actually to launch the unlocked
+                // (insecure) camera, so we should transition back to GONE.
+                startTransitionTo(
+                    KeyguardState.GONE,
+                    ownerReason = "Power button gesture while GONE"
+                )
+
+                return true
+            } else if (keyguardOcclusionInteractor.occludingActivityWillDismissKeyguard.value) {
+                // The double tap gesture occurred while not GONE (AOD/LOCKSCREEN/etc.), but the
+                // keyguard is dismissable. The activity launch will dismiss the keyguard, so we
+                // should transition to GONE.
+                startTransitionTo(
+                    KeyguardState.GONE,
+                    ownerReason = "Power button gesture on dismissable keyguard"
+                )
+
+                return true
+            }
+        }
+
+        return false
+    }
+
+    /**
      * Transition to the appropriate state when the device goes to sleep while in [from].
      *
      * We could also just use [fromState], but it's more readable in the From*TransitionInteractor
@@ -166,15 +199,14 @@
      * state, [startTransitionTo] would complain anyway.
      */
     suspend fun listenForSleepTransition(
-        from: KeyguardState,
         modeOnCanceledFromStartedStep: (TransitionStep) -> TransitionModeOnCanceled = {
             TransitionModeOnCanceled.LAST_VALUE
         }
     ) {
         powerInteractor.isAsleep
             .filter { isAsleep -> isAsleep }
+            .filterRelevantKeyguardState()
             .sample(startedKeyguardTransitionStep)
-            .filter { startedStep -> startedStep.to == from }
             .map(modeOnCanceledFromStartedStep)
             .collect { modeOnCanceled ->
                 startTransitionTo(
@@ -211,6 +243,34 @@
     }
 
     /**
+     * Whether we're in the KeyguardState relevant to this From*TransitionInteractor (which we know
+     * from [fromState]).
+     *
+     * This uses [KeyguardTransitionInteractor.currentTransitionInfoInternal], which is more up to
+     * date than [startedKeyguardState] as it does not wait for the emission of the first STARTED
+     * step.
+     */
+    fun inOrTransitioningToRelevantKeyguardState(): Boolean {
+        return transitionInteractor.currentTransitionInfoInternal.value.to == fromState
+    }
+
+    /**
+     * Filters emissions whenever we're not in a KeyguardState relevant to this
+     * From*TransitionInteractor (which we know from [fromState]).
+     */
+    fun <T> Flow<T>.filterRelevantKeyguardState(): Flow<T> {
+        return filter { inOrTransitioningToRelevantKeyguardState() }
+    }
+
+    /**
+     * Filters emissions whenever we're not in a KeyguardState relevant to this
+     * From*TransitionInteractor (which we know from [fromState]).
+     */
+    fun <T> Flow<T>.filterRelevantKeyguardStateAnd(predicate: (T) -> Boolean): Flow<T> {
+        return filter { inOrTransitioningToRelevantKeyguardState() && predicate.invoke(it) }
+    }
+
+    /**
      * Returns a ValueAnimator to be used for transitions to [toState], if one is not explicitly
      * passed to [startTransitionTo].
      */
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerMessageAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerMessageAreaViewBinder.kt
index 9186dde..fe5f632 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerMessageAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerMessageAreaViewBinder.kt
@@ -18,6 +18,7 @@
 
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
 import com.android.keyguard.AuthKeyguardMessageArea
 import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerMessageAreaViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
@@ -36,14 +37,18 @@
         view.setIsVisible(true)
         view.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.STARTED) {
-                viewModel.message.collect { biometricMsg ->
-                    if (biometricMsg == null) {
-                        view.setMessage("", true)
-                    } else {
-                        view.setMessage(biometricMsg.message, true)
+                launch("$TAG#viewModel.message") {
+                    viewModel.message.collect { biometricMsg ->
+                        if (biometricMsg == null) {
+                            view.setMessage("", true)
+                        } else {
+                            view.setMessage(biometricMsg.message, true)
+                        }
                     }
                 }
             }
         }
     }
+
+    private const val TAG = "AlternateBouncerMessageAreaViewBinder"
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerUdfpsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerUdfpsViewBinder.kt
index a861a87..9dc77d3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerUdfpsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerUdfpsViewBinder.kt
@@ -21,12 +21,12 @@
 import android.view.View
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
 import com.android.systemui.keyguard.ui.view.DeviceEntryIconView
 import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerUdfpsIconViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.launch
 
 @ExperimentalCoroutinesApi
 object AlternateBouncerUdfpsViewBinder {
@@ -46,13 +46,13 @@
         view.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.STARTED) {
                 view.alpha = 0f
-                launch {
+                launch("$TAG#viewModel.accessibilityDelegateHint") {
                     viewModel.accessibilityDelegateHint.collect { hint ->
                         view.accessibilityHintType = hint
                     }
                 }
 
-                launch { viewModel.alpha.collect { view.alpha = it } }
+                launch("$TAG#viewModel.alpha") { viewModel.alpha.collect { view.alpha = it } }
             }
         }
 
@@ -77,13 +77,17 @@
         bgView.visibility = View.VISIBLE
         bgView.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.STARTED) {
-                launch {
+                launch("$TAG#viewModel.bgColor") {
                     viewModel.bgColor.collect { color ->
                         bgView.imageTintList = ColorStateList.valueOf(color)
                     }
                 }
-                launch { viewModel.bgAlpha.collect { alpha -> bgView.alpha = alpha } }
+                launch("$TAG#viewModel.bgAlpha") {
+                    viewModel.bgAlpha.collect { alpha -> bgView.alpha = alpha }
+                }
             }
         }
     }
+
+    private const val TAG = "AlternateBouncerUdfpsViewBinder"
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt
index 1eea556..53f0132 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt
@@ -28,6 +28,7 @@
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
@@ -46,7 +47,6 @@
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.launch
 
 /**
  * When necessary, adds the alternate bouncer window above most other windows (including the
@@ -92,7 +92,7 @@
         if (!DeviceEntryUdfpsRefactor.isEnabled) {
             return
         }
-        applicationScope.launch {
+        applicationScope.launch("$TAG#alternateBouncerWindowViewModel") {
             alternateBouncerWindowViewModel.get().alternateBouncerWindowRequired.collect {
                 addAlternateBouncerWindowView ->
                 if (addAlternateBouncerWindowView) {
@@ -186,7 +186,7 @@
         val tapGestureDetector = alternateBouncerDependencies.tapGestureDetector
         view.repeatWhenAttached { alternateBouncerViewContainer ->
             repeatOnLifecycle(Lifecycle.State.STARTED) {
-                launch {
+                launch("$TAG#viewModel.registerForDismissGestures") {
                     viewModel.registerForDismissGestures.collect { registerForDismissGestures ->
                         if (registerForDismissGestures) {
                             swipeUpAnywhereGestureHandler.addOnGestureDetectedCallback(swipeTag) { _
@@ -205,9 +205,13 @@
                     }
                 }
 
-                launch { viewModel.scrimAlpha.collect { scrim.viewAlpha = it } }
+                launch("$TAG#viewModel.scrimAlpha") {
+                    viewModel.scrimAlpha.collect { scrim.viewAlpha = it }
+                }
 
-                launch { viewModel.scrimColor.collect { scrim.tint = it } }
+                launch("$TAG#viewModel.scrimColor") {
+                    viewModel.scrimColor.collect { scrim.tint = it }
+                }
             }
         }
     }
@@ -219,7 +223,7 @@
     ) {
         view.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.CREATED) {
-                launch {
+                launch("$TAG#udfpsIconViewModel.iconLocation") {
                     udfpsIconViewModel.iconLocation.collect { iconLocation ->
                         // add UDFPS a11y overlay
                         val udfpsA11yOverlayViewId =
@@ -292,7 +296,9 @@
             }
         }
     }
+    companion object {
+        private const val TAG = "AlternateBouncerViewBinder"
+        private const val swipeTag = "AlternateBouncer-SWIPE"
+        private const val tapTag = "AlternateBouncer-TAP"
+    }
 }
-
-private const val swipeTag = "AlternateBouncer-SWIPE"
-private const val tapTag = "AlternateBouncer-TAP"
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt
index f46a207..e423fe0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/DeviceEntryIconViewBinder.kt
@@ -25,6 +25,7 @@
 import androidx.core.view.isInvisible
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.common.ui.view.LongPressHandlingView
 import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
 import com.android.systemui.keyguard.ui.view.DeviceEntryIconView
@@ -34,13 +35,15 @@
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.statusbar.VibratorHelper
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.launch
 
 @ExperimentalCoroutinesApi
 object DeviceEntryIconViewBinder {
 
+    private const val TAG = "DeviceEntryIconViewBinder"
+
     /**
      * Updates UI for:
      * - device entry containing view (parent view for the below views)
@@ -58,6 +61,7 @@
         bgViewModel: DeviceEntryBackgroundViewModel,
         falsingManager: FalsingManager,
         vibratorHelper: VibratorHelper,
+        mainImmediateDispatcher: CoroutineDispatcher,
     ) {
         DeviceEntryUdfpsRefactor.isUnexpectedlyInLegacyMode()
         val longPressHandlingView = view.longPressHandlingView
@@ -73,31 +77,33 @@
                         view,
                         HapticFeedbackConstants.CONFIRM,
                     )
-                    applicationScope.launch { viewModel.onLongPress() }
+                    applicationScope.launch("$TAG#viewModel.onLongPress") {
+                        viewModel.onLongPress()
+                    }
                 }
             }
 
-        view.repeatWhenAttached {
+        view.repeatWhenAttached(mainImmediateDispatcher) {
             // Repeat on CREATED so that the view will always observe the entire
             // GONE => AOD transition (even though the view may not be visible until the middle
             // of the transition.
             repeatOnLifecycle(Lifecycle.State.CREATED) {
-                launch {
+                launch("$TAG#viewModel.isVisible") {
                     viewModel.isVisible.collect { isVisible ->
                         longPressHandlingView.isInvisible = !isVisible
                     }
                 }
-                launch {
+                launch("$TAG#viewModel.isLongPressEnabled") {
                     viewModel.isLongPressEnabled.collect { isEnabled ->
                         longPressHandlingView.setLongPressHandlingEnabled(isEnabled)
                     }
                 }
-                launch {
+                launch("$TAG#viewModel.accessibilityDelegateHint") {
                     viewModel.accessibilityDelegateHint.collect { hint ->
                         view.accessibilityHintType = hint
                     }
                 }
-                launch {
+                launch("$TAG#viewModel.useBackgroundProtection") {
                     viewModel.useBackgroundProtection.collect { useBackgroundProtection ->
                         if (useBackgroundProtection) {
                             bgView.visibility = View.VISIBLE
@@ -106,7 +112,7 @@
                         }
                     }
                 }
-                launch {
+                launch("$TAG#viewModel.burnInOffsets") {
                     viewModel.burnInOffsets.collect { burnInOffsets ->
                         view.translationX = burnInOffsets.x.toFloat()
                         view.translationY = burnInOffsets.y.toFloat()
@@ -114,15 +120,17 @@
                     }
                 }
 
-                launch { viewModel.deviceEntryViewAlpha.collect { alpha -> view.alpha = alpha } }
+                launch("$TAG#viewModel.deviceEntryViewAlpha") {
+                    viewModel.deviceEntryViewAlpha.collect { alpha -> view.alpha = alpha }
+                }
             }
         }
 
-        fgIconView.repeatWhenAttached {
+        fgIconView.repeatWhenAttached(mainImmediateDispatcher) {
             repeatOnLifecycle(Lifecycle.State.STARTED) {
                 // Start with an empty state
                 fgIconView.setImageState(StateSet.NOTHING, /* merge */ false)
-                launch {
+                launch("$TAG#fgViewModel.viewModel") {
                     fgViewModel.viewModel.collect { viewModel ->
                         fgIconView.setImageState(
                             view.getIconState(viewModel.type, viewModel.useAodVariant),
@@ -142,8 +150,10 @@
 
         bgView.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.CREATED) {
-                launch { bgViewModel.alpha.collect { alpha -> bgView.alpha = alpha } }
-                launch {
+                launch("$TAG#bgViewModel.alpha") {
+                    bgViewModel.alpha.collect { alpha -> bgView.alpha = alpha }
+                }
+                launch("$TAG#bgViewModel.color") {
                     bgViewModel.color.collect { color ->
                         bgView.imageTintList = ColorStateList.valueOf(color)
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt
index 7e3ddf9..b5d6177 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBlueprintViewBinder.kt
@@ -26,6 +26,7 @@
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.KeyguardBottomAreaRefactor
@@ -39,7 +40,6 @@
 import com.android.systemui.res.R
 import javax.inject.Inject
 import kotlin.math.max
-import kotlinx.coroutines.launch
 
 private const val TAG = "KeyguardBlueprintViewBinder"
 private const val DEBUG = false
@@ -90,7 +90,7 @@
     ) {
         constraintLayout.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.CREATED) {
-                launch {
+                launch("$TAG#viewModel.blueprint") {
                     viewModel.blueprint.collect { blueprint ->
                         Trace.beginSection("KeyguardBlueprintViewBinder#applyBlueprint")
                         val prevBluePrint = viewModel.currentBluePrint
@@ -137,7 +137,7 @@
                     }
                 }
 
-                launch {
+                launch("$TAG#viewModel.refreshTransition") {
                     viewModel.refreshTransition.collect { transition ->
                         Trace.beginSection("KeyguardBlueprintViewBinder#refreshTransition")
                         val cs =
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
index 397cbe5..660a650 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardBottomAreaViewBinder.kt
@@ -36,6 +36,7 @@
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.animation.Interpolators
+import com.android.app.tracing.coroutines.launch
 import com.android.settingslib.Utils
 import com.android.systemui.animation.ActivityTransitionAnimator
 import com.android.systemui.animation.Expandable
@@ -61,7 +62,6 @@
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.launch
 
 /**
  * Binds a keyguard bottom area view to its view-model.
@@ -77,6 +77,7 @@
     private const val EXIT_DOZE_BUTTON_REVEAL_ANIMATION_DURATION_MS = 250L
     private const val SCALE_SELECTED_BUTTON = 1.23f
     private const val DIM_ALPHA = 0.3f
+    private const val TAG = "KeyguardBottomAreaViewBinder"
 
     /**
      * Defines interface for an object that acts as the binding between the view and its view-model.
@@ -171,7 +172,7 @@
             view.repeatWhenAttached {
                 repeatOnLifecycle(Lifecycle.State.STARTED) {
                     // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt]
-                    launch {
+                    launch("$TAG#viewModel.startButton") {
                         viewModel.startButton.collect { buttonModel ->
                             updateButton(
                                 view = startButton,
@@ -184,7 +185,7 @@
                     }
 
                     // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt]
-                    launch {
+                    launch("$TAG#viewModel.endButton") {
                         viewModel.endButton.collect { buttonModel ->
                             updateButton(
                                 view = endButton,
@@ -196,7 +197,7 @@
                         }
                     }
 
-                    launch {
+                    launch("$TAG#viewModel.isOverlayContainerVisible") {
                         viewModel.isOverlayContainerVisible.collect { isVisible ->
                             overlayContainer.visibility =
                                 if (isVisible) {
@@ -207,7 +208,7 @@
                         }
                     }
 
-                    launch {
+                    launch("$TAG#viewModel.alpha") {
                         viewModel.alpha.collect { alpha ->
                             ambientIndicationArea?.apply {
                                 this.importantForAccessibility =
@@ -222,7 +223,7 @@
                     }
 
                     // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt]
-                    launch {
+                    launch("$TAG#updateButtonAlpha") {
                         updateButtonAlpha(
                             view = startButton,
                             viewModel = viewModel.startButton,
@@ -231,7 +232,7 @@
                     }
 
                     // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt]
-                    launch {
+                    launch("$TAG#updateButtonAlpha") {
                         updateButtonAlpha(
                             view = endButton,
                             viewModel = viewModel.endButton,
@@ -239,13 +240,13 @@
                         )
                     }
 
-                    launch {
+                    launch("$TAG#viewModel.indicationAreaTranslationX") {
                         viewModel.indicationAreaTranslationX.collect { translationX ->
                             ambientIndicationArea?.translationX = translationX
                         }
                     }
 
-                    launch {
+                    launch("$TAG#viewModel.indicationAreaTranslationY") {
                         configurationBasedDimensions
                             .map { it.defaultBurnInPreventionYOffsetPx }
                             .flatMapLatest { defaultBurnInOffsetY ->
@@ -257,7 +258,7 @@
                     }
 
                     // If updated, be sure to update [KeyguardQuickAffordanceViewBinder.kt]
-                    launch {
+                    launch("$TAG#startButton.updateLayoutParams<ViewGroup") {
                         configurationBasedDimensions.collect { dimensions ->
                             startButton.updateLayoutParams<ViewGroup.LayoutParams> {
                                 width = dimensions.buttonSizePx.width
@@ -270,7 +271,7 @@
                         }
                     }
 
-                    launch {
+                    launch("$TAG#viewModel.settingsMenuViewModel") {
                         viewModel.settingsMenuViewModel.isVisible.distinctUntilChanged().collect {
                             isVisible ->
                             settingsMenu.animateVisibility(visible = isVisible)
@@ -297,7 +298,7 @@
                     // shows up in the Wallpaper Picker app. If we do that, then the
                     // settings menu should never be visible.
                     if (activityStarter != null) {
-                        launch {
+                        launch("$TAG#viewModel.settingsMenuViewModel") {
                             viewModel.settingsMenuViewModel.shouldOpenSettings
                                 .filter { it }
                                 .collect {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
index 6255f0d..1b06a69 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardClockViewBinder.kt
@@ -26,6 +26,7 @@
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
 import com.android.keyguard.KeyguardClockSwitch.LARGE
 import com.android.keyguard.KeyguardClockSwitch.SMALL
 import com.android.systemui.keyguard.MigrateClocksToBlueprint
@@ -37,10 +38,10 @@
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.clocks.ClockController
 import com.android.systemui.shared.clocks.DEFAULT_CLOCK_ID
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.DisposableHandle
 
 object KeyguardClockViewBinder {
-    private val TAG = KeyguardClockViewBinder::class.simpleName!!
+    private const val TAG = "KeyguardClockViewBinder"
     // When changing to new clock, we need to remove old clock views from burnInLayer
     private var lastClock: ClockController? = null
     @JvmStatic
@@ -50,15 +51,12 @@
         viewModel: KeyguardClockViewModel,
         keyguardClockInteractor: KeyguardClockInteractor,
         blueprintInteractor: KeyguardBlueprintInteractor,
-    ) {
-        keyguardRootView.repeatWhenAttached {
+    ): DisposableHandle {
+        keyguardClockInteractor.clockEventController.registerListeners(keyguardRootView)
+
+        return keyguardRootView.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.CREATED) {
-                keyguardClockInteractor.clockEventController.registerListeners(keyguardRootView)
-            }
-        }
-        keyguardRootView.repeatWhenAttached {
-            repeatOnLifecycle(Lifecycle.State.CREATED) {
-                launch {
+                launch("$TAG#viewModel.currentClock") {
                     if (!MigrateClocksToBlueprint.isEnabled) return@launch
                     viewModel.currentClock.collect { currentClock ->
                         cleanupClockViews(currentClock, keyguardRootView, viewModel.burnInLayer)
@@ -67,14 +65,14 @@
                         applyConstraints(clockSection, keyguardRootView, true)
                     }
                 }
-                launch {
+                launch("$TAG#viewModel.clockSize") {
                     if (!MigrateClocksToBlueprint.isEnabled) return@launch
                     viewModel.clockSize.collect {
                         updateBurnInLayer(keyguardRootView, viewModel)
                         blueprintInteractor.refreshBlueprint(Type.ClockSize)
                     }
                 }
-                launch {
+                launch("$TAG#viewModel.clockShouldBeCentered") {
                     if (!MigrateClocksToBlueprint.isEnabled) return@launch
                     viewModel.clockShouldBeCentered.collect { clockShouldBeCentered ->
                         viewModel.currentClock.value?.let {
@@ -91,7 +89,7 @@
                         }
                     }
                 }
-                launch {
+                launch("$TAG#viewModel.isAodIconsVisible") {
                     if (!MigrateClocksToBlueprint.isEnabled) return@launch
                     viewModel.isAodIconsVisible.collect { isAodIconsVisible ->
                         viewModel.currentClock.value?.let {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt
index 267d68e..23c2491 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardIndicationAreaBinder.kt
@@ -22,6 +22,7 @@
 import android.widget.TextView
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.keyguard.KeyguardBottomAreaRefactor
 import com.android.systemui.keyguard.MigrateClocksToBlueprint
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel
@@ -34,7 +35,6 @@
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.launch
 
 /**
  * Binds a keyguard indication area view to its view-model.
@@ -66,7 +66,7 @@
         val disposableHandle =
             view.repeatWhenAttached {
                 repeatOnLifecycle(Lifecycle.State.STARTED) {
-                    launch {
+                    launch("$TAG#viewModel.alpha") {
                         // Do not independently apply alpha, as [KeyguardRootViewModel] should work
                         // for this and all its children
                         if (
@@ -77,13 +77,13 @@
                         }
                     }
 
-                    launch {
+                    launch("$TAG#viewModel.indicationAreaTranslationX") {
                         viewModel.indicationAreaTranslationX.collect { translationX ->
                             view.translationX = translationX
                         }
                     }
 
-                    launch {
+                    launch("$TAG#viewModel.isIndicationAreaPadded") {
                         combine(
                                 viewModel.isIndicationAreaPadded,
                                 configurationBasedDimensions.map { it.indicationAreaPaddingPx },
@@ -97,7 +97,7 @@
                             .collect { paddingPx -> view.setPadding(paddingPx, 0, paddingPx, 0) }
                     }
 
-                    launch {
+                    launch("$TAG#viewModel.indicationAreaTranslationY") {
                         configurationBasedDimensions
                             .map { it.defaultBurnInPreventionYOffsetPx }
                             .flatMapLatest { defaultBurnInOffsetY ->
@@ -106,7 +106,7 @@
                             .collect { translationY -> view.translationY = translationY }
                     }
 
-                    launch {
+                    launch("$TAG#indicationText.setTextSize") {
                         configurationBasedDimensions.collect { dimensions ->
                             indicationText.setTextSize(
                                 TypedValue.COMPLEX_UNIT_PX,
@@ -119,7 +119,7 @@
                         }
                     }
 
-                    launch {
+                    launch("$TAG#viewModel.configurationChange") {
                         viewModel.configurationChange.collect {
                             configurationBasedDimensions.value = loadFromResources(view)
                         }
@@ -147,4 +147,6 @@
         val indicationAreaPaddingPx: Int,
         val indicationTextSizePx: Int,
     )
+
+    private const val TAG = "KeyguardIndicationAreaBinder"
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt
index 9cc503c..09fe067 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardLongPressViewBinder.kt
@@ -20,11 +20,11 @@
 import android.view.View
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.common.ui.view.LongPressHandlingView
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.FalsingManager
-import kotlinx.coroutines.launch
 
 object KeyguardLongPressViewBinder {
     /**
@@ -64,7 +64,7 @@
 
         view.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.STARTED) {
-                launch {
+                launch("$TAG#viewModel.isLongPressHandlingEnabled") {
                     viewModel.isLongPressHandlingEnabled.collect { isEnabled ->
                         view.setLongPressHandlingEnabled(isEnabled)
                     }
@@ -72,4 +72,6 @@
             }
         }
     }
+
+    private const val TAG = "KeyguardLongPressViewBinder"
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
index 5906cfd..486320a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewClockViewBinder.kt
@@ -33,6 +33,8 @@
 import androidx.core.view.isVisible
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
+import com.android.internal.policy.SystemBarUtils
 import com.android.systemui.customization.R as customizationR
 import com.android.systemui.keyguard.shared.model.SettingsClockSize
 import com.android.systemui.keyguard.ui.preview.KeyguardPreviewRenderer
@@ -44,7 +46,6 @@
 import com.android.systemui.res.R
 import com.android.systemui.util.Utils
 import kotlin.reflect.KSuspendFunction1
-import kotlinx.coroutines.launch
 
 /** Binder for the small clock view, large clock view. */
 object KeyguardPreviewClockViewBinder {
@@ -56,13 +57,17 @@
     ) {
         largeClockHostView.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.STARTED) {
-                viewModel.isLargeClockVisible.collect { largeClockHostView.isVisible = it }
+                launch("$TAG#viewModel.isLargeClockVisible") {
+                    viewModel.isLargeClockVisible.collect { largeClockHostView.isVisible = it }
+                }
             }
         }
 
         smallClockHostView.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.STARTED) {
-                viewModel.isSmallClockVisible.collect { smallClockHostView.isVisible = it }
+                launch("$TAG#viewModel.isSmallClockVisible") {
+                    viewModel.isSmallClockVisible.collect { smallClockHostView.isVisible = it }
+                }
             }
         }
     }
@@ -76,7 +81,7 @@
     ) {
         rootView.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.STARTED) {
-                launch {
+                launch("$TAG#viewModel.previewClock") {
                     var lastClock: ClockController? = null
                     viewModel.previewClock.collect { currentClock ->
                         lastClock?.let { clock ->
@@ -112,7 +117,7 @@
             constrainWidth(R.id.lockscreen_clock_view_large, ConstraintSet.WRAP_CONTENT)
             constrainHeight(R.id.lockscreen_clock_view_large, ConstraintSet.MATCH_CONSTRAINT)
             val largeClockTopMargin =
-                context.resources.getDimensionPixelSize(R.dimen.status_bar_height) +
+                SystemBarUtils.getStatusBarHeight(context) +
                     context.resources.getDimensionPixelSize(
                         customizationR.dimen.small_clock_padding_top
                     ) +
@@ -207,4 +212,5 @@
 
     private const val DATE_WEATHER_VIEW_HEIGHT = "date_weather_view_height"
     private const val ENHANCED_SMARTSPACE_HEIGHT = "enhanced_smartspace_height"
+    private const val TAG = "KeyguardPreviewClockViewBinder"
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt
index f5e4c6a..49ae35a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardPreviewSmartspaceViewBinder.kt
@@ -17,27 +17,47 @@
 
 package com.android.systemui.keyguard.ui.binder
 
+import android.content.Context
 import android.view.View
 import androidx.core.view.isInvisible
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
+import com.android.systemui.keyguard.shared.model.SettingsClockSize
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardPreviewSmartspaceViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
-import kotlinx.coroutines.launch
 
 /** Binder for the small clock view, large clock view and smartspace. */
 object KeyguardPreviewSmartspaceViewBinder {
 
     @JvmStatic
     fun bind(
+        context: Context,
         smartspace: View,
+        splitShadePreview: Boolean,
         viewModel: KeyguardPreviewSmartspaceViewModel,
     ) {
         smartspace.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.STARTED) {
-                launch { viewModel.smartspaceTopPadding.collect { smartspace.setTopPadding(it) } }
-
-                launch { viewModel.shouldHideSmartspace.collect { smartspace.isInvisible = it } }
+                launch("$TAG#viewModel.selectedClockSize") {
+                    viewModel.selectedClockSize.collect {
+                        val topPadding =
+                            when (it) {
+                                SettingsClockSize.DYNAMIC ->
+                                    viewModel.getLargeClockSmartspaceTopPadding(
+                                        splitShadePreview,
+                                    )
+                                SettingsClockSize.SMALL ->
+                                    viewModel.getSmallClockSmartspaceTopPadding(
+                                        splitShadePreview,
+                                    )
+                            }
+                        smartspace.setTopPadding(topPadding)
+                    }
+                }
+                launch("$TAG#viewModel.shouldHideSmartspace") {
+                    viewModel.shouldHideSmartspace.collect { smartspace.isInvisible = it }
+                }
             }
         }
     }
@@ -45,4 +65,6 @@
     private fun View.setTopPadding(padding: Int) {
         setPaddingRelative(paddingStart, padding, paddingEnd, paddingBottom)
     }
+
+    private const val TAG = "KeyguardPreviewSmartspaceViewBinder"
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
index abd79ab..6c21e6c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardQuickAffordanceViewBinder.kt
@@ -30,6 +30,7 @@
 import androidx.core.view.updateLayoutParams
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
 import com.android.settingslib.Utils
 import com.android.systemui.animation.Expandable
 import com.android.systemui.animation.view.LaunchableImageView
@@ -41,11 +42,11 @@
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.VibratorHelper
 import com.android.systemui.util.doOnEnd
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.launch
 
 /** This is only for a SINGLE Quick affordance */
 object KeyguardQuickAffordanceViewBinder {
@@ -53,6 +54,7 @@
     private const val EXIT_DOZE_BUTTON_REVEAL_ANIMATION_DURATION_MS = 250L
     private const val SCALE_SELECTED_BUTTON = 1.23f
     private const val DIM_ALPHA = 0.3f
+    private const val TAG = "KeyguardQuickAffordanceViewBinder"
 
     /**
      * Defines interface for an object that acts as the binding between the view and its view-model.
@@ -74,14 +76,15 @@
         alpha: Flow<Float>,
         falsingManager: FalsingManager?,
         vibratorHelper: VibratorHelper?,
+        mainImmediateDispatcher: CoroutineDispatcher,
         messageDisplayer: (Int) -> Unit,
     ): Binding {
         val button = view as ImageView
         val configurationBasedDimensions = MutableStateFlow(loadFromResources(view))
         val disposableHandle =
-            view.repeatWhenAttached {
+            view.repeatWhenAttached(mainImmediateDispatcher) {
                 repeatOnLifecycle(Lifecycle.State.STARTED) {
-                    launch {
+                    launch("$TAG#viewModel.collect") {
                         viewModel.collect { buttonModel ->
                             updateButton(
                                 view = button,
@@ -93,7 +96,7 @@
                         }
                     }
 
-                    launch {
+                    launch("$TAG#updateButtonAlpha") {
                         updateButtonAlpha(
                             view = button,
                             viewModel = viewModel,
@@ -101,7 +104,7 @@
                         )
                     }
 
-                    launch {
+                    launch("$TAG#configurationBasedDimensions") {
                         configurationBasedDimensions.collect { dimensions ->
                             button.updateLayoutParams<ViewGroup.LayoutParams> {
                                 width = dimensions.buttonSizePx.width
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
index 4d9354dd..0249abd 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt
@@ -33,9 +33,9 @@
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.app.animation.Interpolators
+import com.android.app.tracing.coroutines.launch
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD
-import com.android.keyguard.KeyguardClockSwitch.MISSING_CLOCK_ID
 import com.android.systemui.Flags.newAodTransition
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.shared.model.Text
@@ -46,6 +46,7 @@
 import com.android.systemui.keyguard.KeyguardBottomAreaRefactor
 import com.android.systemui.keyguard.KeyguardViewMediator
 import com.android.systemui.keyguard.MigrateClocksToBlueprint
+import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.ui.viewmodel.BurnInParameters
@@ -54,7 +55,6 @@
 import com.android.systemui.keyguard.ui.viewmodel.ViewStateAccessor
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.FalsingManager
-import com.android.systemui.plugins.clocks.ClockController
 import com.android.systemui.res.R
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.statusbar.CrossFadeHelper
@@ -68,8 +68,8 @@
 import com.android.systemui.util.ui.isAnimating
 import com.android.systemui.util.ui.stopAnimating
 import com.android.systemui.util.ui.value
-import javax.inject.Provider
 import kotlin.math.min
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.DisposableHandle
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.coroutineScope
@@ -77,12 +77,10 @@
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.flow.update
-import kotlinx.coroutines.launch
 
 /** Bind occludingAppDeviceEntryMessageViewModel to run whenever the keyguard view is attached. */
 @OptIn(ExperimentalCoroutinesApi::class)
 object KeyguardRootViewBinder {
-
     @SuppressLint("ClickableViewAccessibility")
     @JvmStatic
     fun bind(
@@ -93,23 +91,16 @@
         chipbarCoordinator: ChipbarCoordinator,
         screenOffAnimationController: ScreenOffAnimationController,
         shadeInteractor: ShadeInteractor,
-        clockControllerProvider: Provider<ClockController>?,
+        clockInteractor: KeyguardClockInteractor,
         interactionJankMonitor: InteractionJankMonitor?,
         deviceEntryHapticsInteractor: DeviceEntryHapticsInteractor?,
         vibratorHelper: VibratorHelper?,
         falsingManager: FalsingManager?,
         keyguardViewMediator: KeyguardViewMediator?,
+        mainImmediateDispatcher: CoroutineDispatcher,
     ): DisposableHandle {
         var onLayoutChangeListener: OnLayoutChange? = null
         val childViews = mutableMapOf<Int, View>()
-        val statusViewId = R.id.keyguard_status_view
-        val burnInLayerId = R.id.burn_in_layer
-        val aodNotificationIconContainerId = R.id.aod_notification_icon_container
-        val largeClockId = R.id.lockscreen_clock_view_large
-        val indicationArea = R.id.keyguard_indication_area
-        val startButton = R.id.start_button
-        val endButton = R.id.end_button
-        val lockIcon = R.id.lock_icon_view
 
         if (KeyguardBottomAreaRefactor.isEnabled) {
             view.setOnTouchListener { _, event ->
@@ -127,9 +118,9 @@
             )
 
         val disposableHandle =
-            view.repeatWhenAttached {
+            view.repeatWhenAttached(mainImmediateDispatcher) {
                 repeatOnLifecycle(Lifecycle.State.CREATED) {
-                    launch {
+                    launch("$TAG#occludingAppDeviceEntryMessageViewModel.message") {
                         occludingAppDeviceEntryMessageViewModel.message.collect { biometricMessage
                             ->
                             if (biometricMessage?.message != null) {
@@ -148,7 +139,7 @@
                     if (
                         KeyguardBottomAreaRefactor.isEnabled || DeviceEntryUdfpsRefactor.isEnabled
                     ) {
-                        launch {
+                        launch("$TAG#viewModel.alpha") {
                             viewModel.alpha(viewState).collect { alpha ->
                                 view.alpha = alpha
                                 if (KeyguardBottomAreaRefactor.isEnabled) {
@@ -160,21 +151,21 @@
                     }
 
                     if (MigrateClocksToBlueprint.isEnabled) {
-                        launch {
+                        launch("$TAG#viewModel.burnInLayerVisibility") {
                             viewModel.burnInLayerVisibility.collect { visibility ->
                                 childViews[burnInLayerId]?.visibility = visibility
                                 childViews[aodNotificationIconContainerId]?.visibility = visibility
                             }
                         }
 
-                        launch {
+                        launch("$TAG#viewModel.burnInLayerAlpha") {
                             viewModel.burnInLayerAlpha.collect { alpha ->
                                 childViews[statusViewId]?.alpha = alpha
                                 childViews[aodNotificationIconContainerId]?.alpha = alpha
                             }
                         }
 
-                        launch {
+                        launch("$TAG#viewModel.topClippingBounds") {
                             val clipBounds = Rect()
                             viewModel.topClippingBounds.collect { clipTop ->
                                 if (clipTop == null) {
@@ -191,13 +182,13 @@
                             }
                         }
 
-                        launch {
+                        launch("$TAG#viewModel.lockscreenStateAlpha") {
                             viewModel.lockscreenStateAlpha(viewState).collect { alpha ->
                                 childViews[statusViewId]?.alpha = alpha
                             }
                         }
 
-                        launch {
+                        launch("$TAG#viewModel.translationY") {
                             // When translation happens in burnInLayer, it won't be weather clock
                             // large clock isn't added to burnInLayer due to its scale transition
                             // so we also need to add translation to it here
@@ -209,12 +200,12 @@
                             }
                         }
 
-                        launch {
+                        launch("$TAG#viewModel.translationX") {
                             viewModel.translationX.collect { state ->
                                 val px = state.value ?: return@collect
                                 when {
                                     state.isToOrFrom(KeyguardState.AOD) -> {
-                                        childViews[largeClockId]?.translationX = px
+                                        // Large Clock is not translated in the x direction
                                         childViews[burnInLayerId]?.translationX = px
                                         childViews[aodNotificationIconContainerId]?.translationX =
                                             px
@@ -236,7 +227,7 @@
                             }
                         }
 
-                        launch {
+                        launch("$TAG#viewModel.scale") {
                             viewModel.scale.collect { scaleViewModel ->
                                 if (scaleViewModel.scaleClockOnly) {
                                     // For clocks except weather clock, we have scale transition
@@ -267,7 +258,7 @@
                         }
 
                         if (NotificationIconContainerRefactor.isEnabled) {
-                            launch {
+                            launch("$TAG#viewModel.isNotifIconContainerVisible") {
                                 val iconsAppearTranslationPx =
                                     configuration
                                         .getDimensionPixelSize(R.dimen.shelf_appear_translation)
@@ -284,18 +275,15 @@
                         }
 
                         interactionJankMonitor?.let { jankMonitor ->
-                            launch {
+                            launch("$TAG#viewModel.goneToAodTransition") {
                                 viewModel.goneToAodTransition.collect {
                                     when (it.transitionState) {
                                         TransitionState.STARTED -> {
-                                            val clockId =
-                                                clockControllerProvider?.get()?.config?.id
-                                                    ?: MISSING_CLOCK_ID
+                                            val clockId = clockInteractor.renderedClockId
                                             val builder =
                                                 InteractionJankMonitor.Configuration.Builder
                                                     .withView(CUJ_SCREEN_OFF_SHOW_AOD, view)
                                                     .setTag(clockId)
-
                                             jankMonitor.begin(builder)
                                         }
                                         TransitionState.CANCELED ->
@@ -313,7 +301,7 @@
                         }
                     }
 
-                    launch {
+                    launch("$TAG#shadeInteractor.isAnyFullyExpanded") {
                         shadeInteractor.isAnyFullyExpanded.collect { isFullyAnyExpanded ->
                             view.visibility =
                                 if (isFullyAnyExpanded) {
@@ -324,10 +312,12 @@
                         }
                     }
 
-                    launch { burnInParams.collect { viewModel.updateBurnInParams(it) } }
+                    launch("$TAG#burnInParams.collect") {
+                        burnInParams.collect { viewModel.updateBurnInParams(it) }
+                    }
 
                     if (deviceEntryHapticsInteractor != null && vibratorHelper != null) {
-                        launch {
+                        launch("$TAG#deviceEntryHapticsInteractor.playSuccessHaptic") {
                             deviceEntryHapticsInteractor.playSuccessHaptic.collect {
                                 vibratorHelper.performHapticFeedback(
                                     view,
@@ -337,7 +327,7 @@
                             }
                         }
 
-                        launch {
+                        launch("$TAG#deviceEntryHapticsInteractor.playErrorHaptic") {
                             deviceEntryHapticsInteractor.playErrorHaptic.collect {
                                 vibratorHelper.performHapticFeedback(
                                     view,
@@ -350,12 +340,6 @@
                 }
             }
 
-        if (!MigrateClocksToBlueprint.isEnabled) {
-            burnInParams.update { current ->
-                current.copy(clockControllerProvider = clockControllerProvider)
-            }
-        }
-
         if (MigrateClocksToBlueprint.isEnabled) {
             burnInParams.update { current ->
                 current.copy(translationY = { childViews[burnInLayerId]?.translationY })
@@ -436,7 +420,7 @@
             oldRight: Int,
             oldBottom: Int
         ) {
-            childViews[R.id.nssl_placeholder]?.let { notificationListPlaceholder ->
+            childViews[nsslPlaceholderId]?.let { notificationListPlaceholder ->
                 // After layout, ensure the notifications are positioned correctly
                 viewModel.onNotificationContainerBoundsChanged(
                     notificationListPlaceholder.top.toFloat(),
@@ -460,14 +444,14 @@
                                 )
                             }
                         } else {
-                            childViews[R.id.keyguard_status_view]?.top ?: 0
+                            childViews[statusViewId]?.top ?: 0
                         }
                 )
             }
         }
 
         private fun isUserVisible(view: View): Boolean {
-            return view.id != R.id.burn_in_layer &&
+            return view.id != burnInLayerId &&
                 view.visibility == VISIBLE &&
                 view.width > 0 &&
                 view.height > 0
@@ -589,6 +573,18 @@
     private fun ViewPropertyAnimator.animateInIconTranslation(): ViewPropertyAnimator =
         setInterpolator(Interpolators.DECELERATE_QUINT).translationY(0f)
 
+    private val statusViewId = R.id.keyguard_status_view
+    private val burnInLayerId = R.id.burn_in_layer
+    private val aodNotificationIconContainerId = R.id.aod_notification_icon_container
+    private val largeClockId = R.id.lockscreen_clock_view_large
+    private val smallClockId = R.id.lockscreen_clock_view
+    private val indicationArea = R.id.keyguard_indication_area
+    private val startButton = R.id.start_button
+    private val endButton = R.id.end_button
+    private val lockIcon = R.id.lock_icon_view
+    private val nsslPlaceholderId = R.id.nssl_placeholder
+
     private const val ID = "occluding_app_device_entry_unlock_msg"
     private const val AOD_ICONS_APPEAR_DURATION: Long = 200
+    private const val TAG = "KeyguardRootViewBinder"
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
index b1adef4..fa57565 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSettingsViewBinder.kt
@@ -22,6 +22,7 @@
 import androidx.core.view.isVisible
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.animation.ActivityTransitionAnimator
 import com.android.systemui.common.ui.binder.IconViewBinder
 import com.android.systemui.common.ui.binder.TextViewBinder
@@ -38,7 +39,6 @@
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.filterNotNull
-import kotlinx.coroutines.launch
 
 object KeyguardSettingsViewBinder {
     fun bind(
@@ -52,7 +52,7 @@
         val disposableHandle =
             view.repeatWhenAttached {
                 repeatOnLifecycle(Lifecycle.State.STARTED) {
-                    launch {
+                    launch("$TAG#viewModel.isVisible") {
                         viewModel.isVisible.distinctUntilChanged().collect { isVisible ->
                             view.animateVisibility(visible = isVisible)
                             if (isVisible) {
@@ -78,7 +78,7 @@
                     // shows up in the Wallpaper Picker app. If we do that, then the
                     // settings menu should never be visible.
                     if (activityStarter != null) {
-                        launch {
+                        launch("$TAG#viewModel.shouldOpenSettings") {
                             viewModel.shouldOpenSettings
                                 .filter { it }
                                 .collect {
@@ -91,7 +91,7 @@
                         }
                     }
 
-                    launch {
+                    launch("$TAG#rootViewModel?.lastRootViewTapPosition") {
                         rootViewModel?.lastRootViewTapPosition?.filterNotNull()?.collect { point ->
                             if (view.isVisible) {
                                 val hitRect = Rect()
@@ -136,4 +136,6 @@
             }
             .start()
     }
+
+    private const val TAG = "KeyguardSettingsViewBinder"
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt
index 9aebf66..6b11dc5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSmartspaceViewBinder.kt
@@ -21,6 +21,7 @@
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.keyguard.MigrateClocksToBlueprint
 import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor
 import com.android.systemui.keyguard.ui.view.layout.blueprints.transitions.IntraBlueprintTransition.Config
@@ -30,7 +31,6 @@
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.res.R
 import com.android.systemui.shared.R as sharedR
-import kotlinx.coroutines.launch
 
 object KeyguardSmartspaceViewBinder {
     @JvmStatic
@@ -42,7 +42,7 @@
     ) {
         keyguardRootView.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.CREATED) {
-                launch {
+                launch("$TAG#clockViewModel.hasCustomWeatherDataDisplay") {
                     if (!MigrateClocksToBlueprint.isEnabled) return@launch
                     clockViewModel.hasCustomWeatherDataDisplay.collect { hasCustomWeatherDataDisplay
                         ->
@@ -61,7 +61,7 @@
                     }
                 }
 
-                launch {
+                launch("$TAG#smartspaceViewModel.bcSmartspaceVisibility") {
                     if (!MigrateClocksToBlueprint.isEnabled) return@launch
                     smartspaceViewModel.bcSmartspaceVisibility.collect {
                         updateBCSmartspaceInBurnInLayer(keyguardRootView, clockViewModel)
@@ -148,4 +148,6 @@
             }
         }
     }
+
+    private const val TAG = "KeyguardSmartspaceViewBinder"
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindViewBinder.kt
index 599f69f..fd27dc3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindViewBinder.kt
@@ -16,10 +16,10 @@
 
 package com.android.systemui.keyguard.ui.binder
 
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.keyguard.WindowManagerLockscreenVisibilityManager
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardSurfaceBehindViewModel
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
 
 /**
  * Binds the [WindowManagerLockscreenVisibilityManager] "view", which manages the visibility of the
@@ -32,6 +32,10 @@
         applier: KeyguardSurfaceBehindParamsApplier,
         scope: CoroutineScope
     ) {
-        scope.launch { viewModel.surfaceBehindViewParams.collect { applier.viewParams = it } }
+        scope.launch("$TAG#viewModel.surfaceBehindViewParams") {
+            viewModel.surfaceBehindViewParams.collect { applier.viewParams = it }
+        }
     }
+
+    private const val TAG = "KeyguardSurfaceBehindViewBinder"
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/LightRevealScrimViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/LightRevealScrimViewBinder.kt
index f1da882..b2ee689 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/LightRevealScrimViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/LightRevealScrimViewBinder.kt
@@ -18,6 +18,7 @@
 
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.repeatOnLifecycle
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.statusbar.LightRevealScrim
@@ -28,11 +29,11 @@
     fun bind(revealScrim: LightRevealScrim, viewModel: LightRevealScrimViewModel) {
         revealScrim.repeatWhenAttached {
             repeatOnLifecycle(Lifecycle.State.CREATED) {
-                launch {
+                launch("$TAG#viewModel.revealAmount") {
                     viewModel.revealAmount.collect { amount -> revealScrim.revealAmount = amount }
                 }
 
-                launch {
+                launch("$TAG#viewModel.lightRevealEffect") {
                     viewModel.lightRevealEffect.collect { effect ->
                         revealScrim.revealEffect = effect
                     }
@@ -40,4 +41,6 @@
             }
         }
     }
+
+    private const val TAG = "LightRevealScrimViewBinder"
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityViewBinder.kt
index fc0c78a..ae46dd3 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityViewBinder.kt
@@ -16,39 +16,41 @@
 
 package com.android.systemui.keyguard.ui.binder
 
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.keyguard.WindowManagerLockscreenVisibilityManager
 import com.android.systemui.keyguard.ui.viewmodel.WindowManagerLockscreenVisibilityViewModel
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
 
 /**
  * Binds the [WindowManagerLockscreenVisibilityManager] "view", which manages the visibility of the
  * surface behind the keyguard.
  */
 object WindowManagerLockscreenVisibilityViewBinder {
+    private const val TAG = "WindowManagerLockscreenVisibilityViewBinder"
+
     @JvmStatic
     fun bind(
         viewModel: WindowManagerLockscreenVisibilityViewModel,
         lockscreenVisibilityManager: WindowManagerLockscreenVisibilityManager,
         scope: CoroutineScope
     ) {
-        scope.launch {
+        scope.launch("$TAG#viewModel.surfaceBehindVisibility") {
             viewModel.surfaceBehindVisibility.collect {
                 lockscreenVisibilityManager.setSurfaceBehindVisibility(it)
             }
         }
 
-        scope.launch {
+        scope.launch("$TAG#viewModel.lockscreenVisibility") {
             viewModel.lockscreenVisibility.collect {
                 lockscreenVisibilityManager.setLockscreenShown(it)
             }
         }
 
-        scope.launch {
+        scope.launch("$TAG#viewModel.aodVisibility") {
             viewModel.aodVisibility.collect { lockscreenVisibilityManager.setAodVisible(it) }
         }
 
-        scope.launch {
+        scope.launch("$TAG#viewModel.surfaceBehindAnimating") {
             viewModel.surfaceBehindAnimating.collect {
                 lockscreenVisibilityManager.setUsingGoingAwayRemoteAnimation(it)
             }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index cbf52ef..42bd4af 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -46,8 +46,8 @@
 import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID
 import androidx.constraintlayout.widget.ConstraintSet.START
 import androidx.constraintlayout.widget.ConstraintSet.TOP
-import androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT
 import androidx.core.view.isInvisible
+import com.android.internal.policy.SystemBarUtils
 import com.android.keyguard.ClockEventController
 import com.android.keyguard.KeyguardClockSwitch
 import com.android.systemui.animation.view.LaunchableImageView
@@ -61,6 +61,7 @@
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.KeyguardBottomAreaRefactor
 import com.android.systemui.keyguard.MigrateClocksToBlueprint
+import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
 import com.android.systemui.keyguard.ui.binder.KeyguardPreviewClockViewBinder
 import com.android.systemui.keyguard.ui.binder.KeyguardPreviewSmartspaceViewBinder
 import com.android.systemui.keyguard.ui.binder.KeyguardQuickAffordanceViewBinder
@@ -141,6 +142,7 @@
     private val secureSettings: SecureSettings,
     private val communalTutorialViewModel: CommunalTutorialIndicatorViewModel,
     private val defaultShortcutsSection: DefaultShortcutsSection,
+    private val keyguardClockInteractor: KeyguardClockInteractor,
 ) {
     val hostToken: IBinder? = bundle.getBinder(KEY_HOST_TOKEN)
     private val width: Int = bundle.getInt(KEY_VIEW_WIDTH)
@@ -325,13 +327,9 @@
         smartSpaceView = lockscreenSmartspaceController.buildAndConnectDateView(parentView)
 
         val topPadding: Int =
-            KeyguardPreviewSmartspaceViewModel.getLargeClockSmartspaceTopPadding(
-                previewContext.resources,
-            )
-        val startPadding: Int =
-            previewContext.resources.getDimensionPixelSize(R.dimen.below_clock_padding_start)
-        val endPadding: Int =
-            previewContext.resources.getDimensionPixelSize(R.dimen.below_clock_padding_end)
+            smartspaceViewModel.getLargeClockSmartspaceTopPadding(previewInSplitShade())
+        val startPadding: Int = smartspaceViewModel.getSmartspaceStartPadding()
+        val endPadding: Int = smartspaceViewModel.getSmartspaceEndPadding()
 
         smartSpaceView?.let {
             it.setPaddingRelative(startPadding, topPadding, endPadding, 0)
@@ -369,6 +367,7 @@
             ),
         )
     }
+
     @OptIn(ExperimentalCoroutinesApi::class)
     private fun setupKeyguardRootView(previewContext: Context, rootView: FrameLayout) {
         val keyguardRootView = KeyguardRootView(previewContext, null)
@@ -382,12 +381,13 @@
                     chipbarCoordinator,
                     screenOffAnimationController,
                     shadeInteractor,
-                    null, // clock provider only needed for burn in
+                    keyguardClockInteractor,
                     null, // jank monitor not required for preview mode
                     null, // device entry haptics not required preview mode
                     null, // device entry haptics not required for preview mode
                     null, // falsing manager not required for preview mode
                     null, // keyguard view mediator is not required for preview mode
+                    mainDispatcher,
                 )
         }
         rootView.addView(
@@ -426,7 +426,15 @@
         }
 
         setUpSmartspace(previewContext, rootView)
-        smartSpaceView?.let { KeyguardPreviewSmartspaceViewBinder.bind(it, smartspaceViewModel) }
+
+        smartSpaceView?.let {
+            KeyguardPreviewSmartspaceViewBinder.bind(
+                context,
+                it,
+                previewInSplitShade(),
+                smartspaceViewModel
+            )
+        }
         setupCommunalTutorialIndicator(keyguardRootView)
     }
 
@@ -446,6 +454,7 @@
                     alpha = flowOf(1f),
                     falsingManager = falsingManager,
                     vibratorHelper = vibratorHelper,
+                    mainImmediateDispatcher = mainDispatcher,
                 ) { message ->
                     indicationController.showTransientIndication(message)
                 }
@@ -460,6 +469,7 @@
                     alpha = flowOf(1f),
                     falsingManager = falsingManager,
                     vibratorHelper = vibratorHelper,
+                    mainImmediateDispatcher = mainDispatcher,
                 ) { message ->
                     indicationController.showTransientIndication(message)
                 }
@@ -530,7 +540,7 @@
                     )
                 )
             layoutParams.topMargin =
-                KeyguardPreviewSmartspaceViewModel.getStatusBarHeight(resources) +
+                SystemBarUtils.getStatusBarHeight(previewContext) +
                     resources.getDimensionPixelSize(
                         com.android.systemui.customization.R.dimen.small_clock_padding_top
                     )
@@ -705,6 +715,14 @@
         smallClockHostView.addView(clock.smallClock.view)
     }
 
+    /*
+     * When multi_crop_preview_ui_flag is on, we can preview portrait in split shadow direction
+     * or vice versa. So we need to decide preview direction by width and height
+     */
+    private fun previewInSplitShade(): Boolean {
+        return width > height
+    }
+
     companion object {
         private const val TAG = "KeyguardPreviewRenderer"
         private const val OVERLAY_CATEGORY_THEME_STYLE = "android.theme.customization.theme_style"
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
index 2e96638..5404729 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AlignShortcutsToUdfpsSection.kt
@@ -36,6 +36,7 @@
 import com.android.systemui.statusbar.KeyguardIndicationController
 import com.android.systemui.statusbar.VibratorHelper
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
 
 class AlignShortcutsToUdfpsSection
 @Inject
@@ -47,6 +48,7 @@
     private val falsingManager: FalsingManager,
     private val indicationController: KeyguardIndicationController,
     private val vibratorHelper: VibratorHelper,
+    @Main private val mainImmediateDispatcher: CoroutineDispatcher,
 ) : BaseShortcutSection() {
     override fun addViews(constraintLayout: ConstraintLayout) {
         if (KeyguardBottomAreaRefactor.isEnabled) {
@@ -64,6 +66,7 @@
                     keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
                     falsingManager,
                     vibratorHelper,
+                    mainImmediateDispatcher,
                 ) {
                     indicationController.showTransientIndication(it)
                 }
@@ -74,6 +77,7 @@
                     keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
                     falsingManager,
                     vibratorHelper,
+                    mainImmediateDispatcher,
                 ) {
                     indicationController.showTransientIndication(it)
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
index 4a09939..e0bf815 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSection.kt
@@ -43,10 +43,9 @@
 import com.android.systemui.plugins.clocks.ClockFaceLayout
 import com.android.systemui.res.R
 import com.android.systemui.shared.R as sharedR
-import com.android.systemui.statusbar.policy.SplitShadeStateController
-import com.android.systemui.util.Utils
 import dagger.Lazy
 import javax.inject.Inject
+import kotlinx.coroutines.DisposableHandle
 
 internal fun ConstraintSet.setVisibility(
     views: Iterable<View>,
@@ -64,23 +63,26 @@
     private val clockInteractor: KeyguardClockInteractor,
     protected val keyguardClockViewModel: KeyguardClockViewModel,
     private val context: Context,
-    private val splitShadeStateController: SplitShadeStateController,
     val smartspaceViewModel: KeyguardSmartspaceViewModel,
     val blueprintInteractor: Lazy<KeyguardBlueprintInteractor>,
 ) : KeyguardSection() {
+    private var handle: DisposableHandle? = null
+
     override fun addViews(constraintLayout: ConstraintLayout) {}
 
     override fun bindData(constraintLayout: ConstraintLayout) {
         if (!MigrateClocksToBlueprint.isEnabled) {
             return
         }
-        KeyguardClockViewBinder.bind(
-            this,
-            constraintLayout,
-            keyguardClockViewModel,
-            clockInteractor,
-            blueprintInteractor.get()
-        )
+        handle?.dispose()
+        handle =
+            KeyguardClockViewBinder.bind(
+                this,
+                constraintLayout,
+                keyguardClockViewModel,
+                clockInteractor,
+                blueprintInteractor.get()
+            )
     }
 
     override fun applyConstraints(constraintSet: ConstraintSet) {
@@ -92,7 +94,13 @@
         }
     }
 
-    override fun removeViews(constraintLayout: ConstraintLayout) {}
+    override fun removeViews(constraintLayout: ConstraintLayout) {
+        if (!MigrateClocksToBlueprint.isEnabled) {
+            return
+        }
+        handle?.dispose()
+        handle = null
+    }
 
     private fun buildConstraints(
         clock: ClockController,
@@ -162,12 +170,7 @@
             connect(R.id.lockscreen_clock_view_large, START, PARENT_ID, START)
             connect(R.id.lockscreen_clock_view_large, END, guideline, END)
             connect(R.id.lockscreen_clock_view_large, BOTTOM, R.id.device_entry_icon_view, TOP)
-            var largeClockTopMargin =
-                context.resources.getDimensionPixelSize(R.dimen.status_bar_height) +
-                    context.resources.getDimensionPixelSize(
-                        customizationR.dimen.small_clock_padding_top
-                    ) +
-                    context.resources.getDimensionPixelSize(R.dimen.keyguard_smartspace_top_offset)
+            var largeClockTopMargin = KeyguardClockViewModel.getLargeClockTopMargin(context)
             largeClockTopMargin += getDimen(DATE_WEATHER_VIEW_HEIGHT)
             largeClockTopMargin += getDimen(ENHANCED_SMARTSPACE_HEIGHT)
 
@@ -187,14 +190,7 @@
                 context.resources.getDimensionPixelSize(customizationR.dimen.clock_padding_start) +
                     context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal)
             )
-            val smallClockTopMargin =
-                if (splitShadeStateController.shouldUseSplitNotificationShade(context.resources)) {
-                    context.resources.getDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin)
-                } else {
-                    context.resources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin) +
-                        Utils.getStatusBarHeaderHeightKeyguard(context)
-                }
-
+            val smallClockTopMargin = keyguardClockViewModel.getSmallClockTopMargin(context)
             create(R.id.small_clock_guideline_top, ConstraintSet.HORIZONTAL_GUIDELINE)
             setGuidelineBegin(R.id.small_clock_guideline_top, smallClockTopMargin)
             connect(R.id.lockscreen_clock_view, TOP, R.id.small_clock_guideline_top, BOTTOM)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
index 29041d1..865e989 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySection.kt
@@ -30,6 +30,7 @@
 import com.android.keyguard.LockIconViewController
 import com.android.systemui.biometrics.AuthController
 import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.deviceentry.shared.DeviceEntryUdfpsRefactor
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.flags.Flags
@@ -47,6 +48,7 @@
 import com.android.systemui.statusbar.VibratorHelper
 import dagger.Lazy
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 
@@ -67,6 +69,7 @@
     private val deviceEntryBackgroundViewModel: Lazy<DeviceEntryBackgroundViewModel>,
     private val falsingManager: Lazy<FalsingManager>,
     private val vibratorHelper: Lazy<VibratorHelper>,
+    @Main private val mainImmediateDispatcher: CoroutineDispatcher,
 ) : KeyguardSection() {
     private val deviceEntryIconViewId = R.id.device_entry_icon_view
 
@@ -104,6 +107,7 @@
                     deviceEntryBackgroundViewModel.get(),
                     falsingManager.get(),
                     vibratorHelper.get(),
+                    mainImmediateDispatcher,
                 )
             }
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
index 45b8257..27ca5cd 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultShortcutsSection.kt
@@ -35,6 +35,7 @@
 import com.android.systemui.statusbar.KeyguardIndicationController
 import com.android.systemui.statusbar.VibratorHelper
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
 
 class DefaultShortcutsSection
 @Inject
@@ -46,6 +47,7 @@
     private val falsingManager: FalsingManager,
     private val indicationController: KeyguardIndicationController,
     private val vibratorHelper: VibratorHelper,
+    @Main private val mainImmediateDispatcher: CoroutineDispatcher,
 ) : BaseShortcutSection() {
     override fun addViews(constraintLayout: ConstraintLayout) {
         if (KeyguardBottomAreaRefactor.isEnabled) {
@@ -63,6 +65,7 @@
                     keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
                     falsingManager,
                     vibratorHelper,
+                    mainImmediateDispatcher,
                 ) {
                     indicationController.showTransientIndication(it)
                 }
@@ -73,6 +76,7 @@
                     keyguardQuickAffordancesCombinedViewModel.transitionAlpha,
                     falsingManager,
                     vibratorHelper,
+                    mainImmediateDispatcher,
                 ) {
                     indicationController.showTransientIndication(it)
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt
index 1847d27..eaa5e33 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SmartspaceSection.kt
@@ -96,12 +96,8 @@
     override fun applyConstraints(constraintSet: ConstraintSet) {
         if (!MigrateClocksToBlueprint.isEnabled) return
         if (!keyguardSmartspaceViewModel.isSmartspaceEnabled) return
-        val horizontalPaddingStart =
-            context.resources.getDimensionPixelSize(R.dimen.below_clock_padding_start) +
-                context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal)
-        val horizontalPaddingEnd =
-            context.resources.getDimensionPixelSize(R.dimen.below_clock_padding_end) +
-                context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal)
+        val horizontalPaddingStart = KeyguardSmartspaceViewModel.getSmartspaceStartMargin(context)
+        val horizontalPaddingEnd = KeyguardSmartspaceViewModel.getSmartspaceEndMargin(context)
         constraintSet.apply {
             // migrate addDateWeatherView, addWeatherView from KeyguardClockSwitchController
             constrainHeight(sharedR.id.date_smartspace_view, ConstraintSet.WRAP_CONTENT)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt
index ded680c..df0b3dc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerUdfpsIconViewModel.kt
@@ -60,12 +60,12 @@
     val iconLocation: Flow<IconLocation> =
         isSupported.flatMapLatest { supportsUI ->
             if (supportsUI) {
-                fingerprintPropertyInteractor.sensorLocation.map { sensorLocation ->
+                fingerprintPropertyInteractor.udfpsSensorBounds.map { bounds ->
                     IconLocation(
-                        left = (sensorLocation.centerX - sensorLocation.radius).toInt(),
-                        top = (sensorLocation.centerY - sensorLocation.radius).toInt(),
-                        right = (sensorLocation.centerX + sensorLocation.radius).toInt(),
-                        bottom = (sensorLocation.centerY + sensorLocation.radius).toInt(),
+                        left = bounds.left,
+                        top = bounds.top,
+                        right = bounds.right,
+                        bottom = bounds.bottom,
                     )
                 }
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
index 2054932..4ddd5711 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodBurnInViewModel.kt
@@ -33,10 +33,8 @@
 import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
 import com.android.systemui.keyguard.shared.model.TransitionState.STARTED
 import com.android.systemui.keyguard.ui.StateToValue
-import com.android.systemui.plugins.clocks.ClockController
 import com.android.systemui.res.R
 import javax.inject.Inject
-import javax.inject.Provider
 import kotlin.math.max
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
@@ -128,12 +126,12 @@
                 yDimenResourceId = R.dimen.burn_in_prevention_offset_y
             ),
         ) { interpolated, burnIn ->
+            val useAltAod =
+                keyguardClockViewModel.currentClock.value?.let { clock ->
+                    clock.config.useAlternateSmartspaceAODTransition
+                } == true
             val useScaleOnly =
-                (clockController(params.clockControllerProvider)
-                    ?.get()
-                    ?.config
-                    ?.useAlternateSmartspaceAODTransition
-                    ?: false) && keyguardClockViewModel.clockSize.value == KeyguardClockSwitch.LARGE
+                useAltAod && keyguardClockViewModel.clockSize.value == KeyguardClockSwitch.LARGE
 
             if (useScaleOnly) {
                 BurnInModel(
@@ -164,21 +162,10 @@
             }
         }
     }
-
-    private fun clockController(
-        provider: Provider<ClockController>?,
-    ): Provider<ClockController>? {
-        return if (MigrateClocksToBlueprint.isEnabled) {
-            Provider { keyguardClockViewModel.currentClock.value }
-        } else {
-            provider
-        }
-    }
 }
 
 /** UI-sourced parameters to pass into the various methods of [AodBurnInViewModel]. */
 data class BurnInParameters(
-    val clockControllerProvider: Provider<ClockController>? = null,
     /** System insets that keyguard needs to stay out of */
     val topInset: Int = 0,
     /** The min y-value of the visible elements on lockscreen */
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
index 1b91c49..87324a2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryBackgroundViewModel.kt
@@ -20,6 +20,7 @@
 import android.content.Context
 import com.android.settingslib.Utils
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
+import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import javax.inject.Inject
@@ -34,6 +35,7 @@
 /** Models the UI state for the device entry icon background view. */
 @Suppress("WHEN_ENUM_CAN_BE_NULL_IN_JAVA")
 @ExperimentalCoroutinesApi
+@SysUISingleton
 class DeviceEntryBackgroundViewModel
 @Inject
 constructor(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt
index 6281097..0aa6d12 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryForegroundViewModel.kt
@@ -21,6 +21,7 @@
 import com.android.settingslib.Utils
 import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
+import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -39,6 +40,7 @@
 
 /** Models the UI state for the device entry icon foreground view (displayed icon). */
 @ExperimentalCoroutinesApi
+@SysUISingleton
 class DeviceEntryForegroundViewModel
 @Inject
 constructor(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
index bc4fd1c..49fffdd 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DeviceEntryIconViewModel.kt
@@ -19,6 +19,7 @@
 import android.animation.FloatEvaluator
 import android.animation.IntEvaluator
 import com.android.keyguard.KeyguardViewController
+import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntrySourceInteractor
@@ -52,6 +53,7 @@
 
 /** Models the UI state for the containing device entry icon & long-press handling view. */
 @ExperimentalCoroutinesApi
+@SysUISingleton
 class DeviceEntryIconViewModel
 @Inject
 constructor(
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
index 3d64951..c9251c7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModel.kt
@@ -17,9 +17,12 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.content.Context
+import androidx.annotation.VisibleForTesting
 import androidx.constraintlayout.helper.widget.Layer
+import com.android.internal.policy.SystemBarUtils
 import com.android.keyguard.KeyguardClockSwitch.LARGE
 import com.android.keyguard.KeyguardClockSwitch.SMALL
+import com.android.systemui.customization.R as customizationR
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
@@ -47,7 +50,7 @@
     private val keyguardClockInteractor: KeyguardClockInteractor,
     @Application private val applicationScope: CoroutineScope,
     notifsKeyguardInteractor: NotificationsKeyguardInteractor,
-    private val shadeInteractor: ShadeInteractor,
+    @VisibleForTesting val shadeInteractor: ShadeInteractor,
 ) {
     var burnInLayer: Layer? = null
     val useLargeClock: Boolean
@@ -161,6 +164,16 @@
         return topMargin
     }
 
+    companion object {
+        fun getLargeClockTopMargin(context: Context): Int {
+            return SystemBarUtils.getStatusBarHeight(context) +
+                context.resources.getDimensionPixelSize(
+                    customizationR.dimen.small_clock_padding_top
+                ) +
+                context.resources.getDimensionPixelSize(R.dimen.keyguard_smartspace_top_offset)
+        }
+    }
+
     enum class ClockLayout {
         LARGE_CLOCK,
         SMALL_CLOCK,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
index 33718c41..b57e3ec 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardPreviewSmartspaceViewModel.kt
@@ -17,13 +17,13 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.content.Context
-import android.content.res.Resources
-import com.android.systemui.res.R
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
 import com.android.systemui.keyguard.shared.model.SettingsClockSize
+import com.android.systemui.res.R
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.map
 
@@ -33,15 +33,11 @@
 constructor(
     @Application private val context: Context,
     interactor: KeyguardClockInteractor,
+    val smartspaceViewModel: KeyguardSmartspaceViewModel,
+    val clockViewModel: KeyguardClockViewModel,
 ) {
 
-    val smartspaceTopPadding: Flow<Int> =
-        interactor.selectedClockSize.map {
-            when (it) {
-                SettingsClockSize.DYNAMIC -> getLargeClockSmartspaceTopPadding(context.resources)
-                SettingsClockSize.SMALL -> getSmallClockSmartspaceTopPadding(context.resources)
-            }
-        }
+    val selectedClockSize: StateFlow<SettingsClockSize> = interactor.selectedClockSize
 
     val shouldHideSmartspace: Flow<Boolean> =
         combine(
@@ -59,34 +55,37 @@
                 }
             }
 
-    companion object {
-        fun getLargeClockSmartspaceTopPadding(resources: Resources): Int {
-            return with(resources) {
-                getDimensionPixelSize(R.dimen.status_bar_header_height_keyguard) +
-                    getDimensionPixelSize(R.dimen.keyguard_smartspace_top_offset) +
-                    getDimensionPixelSize(R.dimen.keyguard_clock_top_margin)
-            }
-        }
+    fun getSmartspaceStartPadding(): Int {
+        return KeyguardSmartspaceViewModel.getSmartspaceStartMargin(context)
+    }
 
-        fun getSmallClockSmartspaceTopPadding(resources: Resources): Int {
-            return with(resources) {
-                getStatusBarHeight(this) +
-                    getDimensionPixelSize(
-                        com.android.systemui.customization.R.dimen.small_clock_padding_top
-                    ) +
-                    getDimensionPixelSize(
-                        com.android.systemui.customization.R.dimen.small_clock_height
-                    )
-            }
-        }
+    fun getSmartspaceEndPadding(): Int {
+        return KeyguardSmartspaceViewModel.getSmartspaceEndMargin(context)
+    }
 
-        fun getStatusBarHeight(resource: Resources): Int {
-            var result = 0
-            val resourceId: Int = resource.getIdentifier("status_bar_height", "dimen", "android")
-            if (resourceId > 0) {
-                result = resource.getDimensionPixelSize(resourceId)
+    fun getSmallClockSmartspaceTopPadding(splitShadePreview: Boolean): Int {
+        return getSmallClockTopPadding(splitShadePreview) +
+            context.resources.getDimensionPixelSize(
+                com.android.systemui.customization.R.dimen.small_clock_height
+            )
+    }
+
+    fun getLargeClockSmartspaceTopPadding(splitShadePreview: Boolean): Int {
+        return getSmallClockTopPadding(splitShadePreview)
+    }
+
+    /*
+     * SmallClockTopPadding decides the top position of smartspace
+     */
+    private fun getSmallClockTopPadding(splitShadePreview: Boolean): Int {
+        return with(context.resources) {
+            if (splitShadePreview) {
+                getDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin)
+            } else {
+                getDimensionPixelSize(R.dimen.keyguard_clock_top_margin) +
+                    getDimensionPixelSize(R.dimen.status_bar_header_height_keyguard) +
+                    getDimensionPixelSize(R.dimen.keyguard_smartspace_top_offset)
             }
-            return result
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index e8313a9..64e1565 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -20,6 +20,7 @@
 import android.graphics.Point
 import android.util.MathUtils
 import android.view.View.VISIBLE
+import com.android.app.tracing.coroutines.launch
 import com.android.systemui.Flags.newAodTransition
 import com.android.systemui.common.shared.model.NotificationContainerBounds
 import com.android.systemui.communal.domain.interactor.CommunalInteractor
@@ -268,7 +269,9 @@
         burnInJob?.cancel()
 
         burnInJob =
-            scope.launch { aodBurnInViewModel.movement(params).collect { burnInModel.value = it } }
+            scope.launch("$TAG#aodBurnInViewModel") {
+                aodBurnInViewModel.movement(params).collect { burnInModel.value = it }
+            }
     }
 
     val scale: Flow<BurnInScaleViewModel> =
@@ -368,4 +371,8 @@
     fun setRootViewLastTapPosition(point: Point) {
         keyguardInteractor.setLastRootViewTapPosition(point)
     }
+
+    companion object {
+        private const val TAG = "KeyguardRootViewModel"
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt
index e8c1ab5..9e7dbd4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardSmartspaceViewModel.kt
@@ -16,9 +16,11 @@
 
 package com.android.systemui.keyguard.ui.viewmodel
 
+import android.content.Context
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.domain.interactor.KeyguardSmartspaceInteractor
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
@@ -83,4 +85,16 @@
 
     /* trigger clock and smartspace constraints change when smartspace appears */
     var bcSmartspaceVisibility: StateFlow<Int> = smartspaceInteractor.bcSmartspaceVisibility
+
+    companion object {
+        fun getSmartspaceStartMargin(context: Context): Int {
+            return context.resources.getDimensionPixelSize(R.dimen.below_clock_padding_start) +
+                context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal)
+        }
+
+        fun getSmartspaceEndMargin(context: Context): Int {
+            return context.resources.getDimensionPixelSize(R.dimen.below_clock_padding_end) +
+                context.resources.getDimensionPixelSize(R.dimen.status_view_margin_horizontal)
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
index 3a19780..a09d58a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
@@ -21,15 +21,21 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
 import com.android.systemui.keyguard.domain.interactor.FromOccludedTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import com.android.systemui.res.R
+import com.android.systemui.util.kotlin.pairwise
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
 
 /**
  * Breaks down OCCLUDED->LOCKSCREEN transition into discrete steps for corresponding views to
@@ -43,6 +49,8 @@
     deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
     configurationInteractor: ConfigurationInteractor,
     animationFlow: KeyguardTransitionAnimationFlow,
+    keyguardInteractor: KeyguardInteractor,
+    keyguardTransitionInteractor: KeyguardTransitionInteractor,
 ) : DeviceEntryIconTransition {
 
     private val transitionAnimation =
@@ -74,11 +82,28 @@
 
     /** Lockscreen views alpha */
     val lockscreenAlpha: Flow<Float> =
-        transitionAnimation.sharedFlow(
-            startTime = 233.milliseconds,
-            duration = 250.milliseconds,
-            onStep = { it },
-            name = "OCCLUDED->LOCKSCREEN: lockscreenAlpha",
+        merge(
+            transitionAnimation.sharedFlow(
+                startTime = 233.milliseconds,
+                duration = 250.milliseconds,
+                onStep = { it },
+                name = "OCCLUDED->LOCKSCREEN: lockscreenAlpha",
+            ),
+            // Required to fix a bug where the shade expands while lockscreenAlpha=1f, due to a call
+            // to setOccluded(false) triggering a reset() call in KeyguardViewMediator. The
+            // permanent solution is to only expand the shade once the keyguard transition from
+            // OCCLUDED starts, but that requires more refactoring of expansion amounts. For now,
+            // emit alpha = 0f for OCCLUDED -> LOCKSCREEN whenever isOccluded flips from true to
+            // false while currentState == OCCLUDED, so that alpha = 0f when that expansion occurs.
+            // TODO(b/332946323): Remove this once it's no longer needed.
+            keyguardInteractor.isKeyguardOccluded
+                .pairwise()
+                .filter { (wasOccluded, isOccluded) ->
+                    wasOccluded &&
+                        !isOccluded &&
+                        keyguardTransitionInteractor.getCurrentState() == KeyguardState.OCCLUDED
+                }
+                .map { 0f }
         )
 
     val deviceEntryBackgroundViewAlpha: Flow<Float> =
diff --git a/packages/SystemUI/src/com/android/systemui/lifecycle/RepeatWhenAttached.kt b/packages/SystemUI/src/com/android/systemui/lifecycle/RepeatWhenAttached.kt
index 1c11178..5dafd94 100644
--- a/packages/SystemUI/src/com/android/systemui/lifecycle/RepeatWhenAttached.kt
+++ b/packages/SystemUI/src/com/android/systemui/lifecycle/RepeatWhenAttached.kt
@@ -26,7 +26,9 @@
 import androidx.lifecycle.lifecycleScope
 import com.android.app.tracing.coroutines.createCoroutineTracingContext
 import com.android.app.tracing.coroutines.launch
+import com.android.systemui.Flags.coroutineTracing
 import com.android.systemui.util.Assert
+import com.android.systemui.util.Compile
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.EmptyCoroutineContext
 import kotlinx.coroutines.Dispatchers
@@ -69,6 +71,12 @@
     // presumably want to call view methods that require being called from said UI thread.
     val lifecycleCoroutineContext =
         Dispatchers.Main + createCoroutineTracingContext() + coroutineContext
+    val traceName =
+        if (Compile.IS_DEBUG && coroutineTracing()) {
+            traceSectionName()
+        } else {
+            DEFAULT_TRACE_NAME
+        }
     var lifecycleOwner: ViewLifecycleOwner? = null
     val onAttachListener =
         object : View.OnAttachStateChangeListener {
@@ -77,6 +85,7 @@
                 lifecycleOwner?.onDestroy()
                 lifecycleOwner =
                     createLifecycleOwnerAndRun(
+                        traceName,
                         view,
                         lifecycleCoroutineContext,
                         block,
@@ -93,6 +102,7 @@
     if (view.isAttachedToWindow) {
         lifecycleOwner =
             createLifecycleOwnerAndRun(
+                traceName,
                 view,
                 lifecycleCoroutineContext,
                 block,
@@ -109,18 +119,14 @@
 }
 
 private fun createLifecycleOwnerAndRun(
+    nameForTrace: String,
     view: View,
     coroutineContext: CoroutineContext,
     block: suspend LifecycleOwner.(View) -> Unit,
 ): ViewLifecycleOwner {
     return ViewLifecycleOwner(view).apply {
         onCreate()
-        lifecycleScope.launch(
-            "ViewLifecycleOwner(${view::class.java.simpleName})",
-            coroutineContext
-        ) {
-            block(view)
-        }
+        lifecycleScope.launch(nameForTrace, coroutineContext) { block(view) }
     }
 }
 
@@ -186,3 +192,24 @@
             }
     }
 }
+
+private fun isFrameInteresting(frame: StackWalker.StackFrame): Boolean =
+    frame.className != CURRENT_CLASS_NAME && frame.className != JAVA_ADAPTER_CLASS_NAME
+
+/** Get a name for the trace section include the name of the call site. */
+private fun traceSectionName(): String {
+    val interestingFrame =
+        StackWalker.getInstance().walk { stream ->
+            stream.filter(::isFrameInteresting).limit(5).findFirst()
+        }
+    if (interestingFrame.isPresent) {
+        val frame = interestingFrame.get()
+        return "${frame.className}#${frame.methodName}:${frame.lineNumber} [$DEFAULT_TRACE_NAME]"
+    } else {
+        return DEFAULT_TRACE_NAME
+    }
+}
+
+private const val DEFAULT_TRACE_NAME = "repeatWhenAttached"
+private const val CURRENT_CLASS_NAME = "com.android.systemui.lifecycle.RepeatWhenAttachedKt"
+private const val JAVA_ADAPTER_CLASS_NAME = "com.android.systemui.util.kotlin.JavaAdapterKt"
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt b/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
index b94a4af..df34169 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/data/repository/MediaFilterRepository.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.media.controls.data.repository
 
+import com.android.internal.logging.InstanceId
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.media.controls.shared.model.MediaData
 import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
@@ -28,17 +29,18 @@
 @SysUISingleton
 class MediaFilterRepository @Inject constructor() {
 
-    /** Key of media control that recommendations card reactivated. */
-    private val _reactivatedKey: MutableStateFlow<String?> = MutableStateFlow(null)
-    val reactivatedKey: StateFlow<String?> = _reactivatedKey.asStateFlow()
+    /** Instance id of media control that recommendations card reactivated. */
+    private val _reactivatedId: MutableStateFlow<InstanceId?> = MutableStateFlow(null)
+    val reactivatedId: StateFlow<InstanceId?> = _reactivatedId.asStateFlow()
 
     private val _smartspaceMediaData: MutableStateFlow<SmartspaceMediaData> =
         MutableStateFlow(SmartspaceMediaData())
     val smartspaceMediaData: StateFlow<SmartspaceMediaData> = _smartspaceMediaData.asStateFlow()
 
-    private val _selectedUserEntries: MutableStateFlow<Map<String, MediaData>> =
+    private val _selectedUserEntries: MutableStateFlow<Map<InstanceId, MediaData>> =
         MutableStateFlow(LinkedHashMap())
-    val selectedUserEntries: StateFlow<Map<String, MediaData>> = _selectedUserEntries.asStateFlow()
+    val selectedUserEntries: StateFlow<Map<InstanceId, MediaData>> =
+        _selectedUserEntries.asStateFlow()
 
     private val _allUserEntries: MutableStateFlow<Map<String, MediaData>> =
         MutableStateFlow(LinkedHashMap())
@@ -62,9 +64,9 @@
         return mediaData
     }
 
-    fun addSelectedUserMediaEntry(key: String, data: MediaData) {
-        val entries = LinkedHashMap<String, MediaData>(_selectedUserEntries.value)
-        entries[key] = data
+    fun addSelectedUserMediaEntry(data: MediaData) {
+        val entries = LinkedHashMap<InstanceId, MediaData>(_selectedUserEntries.value)
+        entries[data.instanceId] = data
         _selectedUserEntries.value = entries
     }
 
@@ -73,8 +75,8 @@
      *
      * @return media data if an entry is actually removed, `null` otherwise.
      */
-    fun removeSelectedUserMediaEntry(key: String): MediaData? {
-        val entries = LinkedHashMap<String, MediaData>(_selectedUserEntries.value)
+    fun removeSelectedUserMediaEntry(key: InstanceId): MediaData? {
+        val entries = LinkedHashMap<InstanceId, MediaData>(_selectedUserEntries.value)
         val mediaData = entries.remove(key)
         _selectedUserEntries.value = entries
         return mediaData
@@ -85,8 +87,8 @@
      *
      * @return true if media data is removed, false otherwise.
      */
-    fun removeSelectedUserMediaEntry(key: String, data: MediaData): Boolean {
-        val entries = LinkedHashMap<String, MediaData>(_selectedUserEntries.value)
+    fun removeSelectedUserMediaEntry(key: InstanceId, data: MediaData): Boolean {
+        val entries = LinkedHashMap<InstanceId, MediaData>(_selectedUserEntries.value)
         val succeed = entries.remove(key, data)
         if (!succeed) {
             return false
@@ -105,7 +107,7 @@
     }
 
     /** Updates media control key that recommendations card reactivated. */
-    fun setReactivatedKey(key: String?) {
-        _reactivatedKey.value = key
+    fun setReactivatedId(instanceId: InstanceId?) {
+        _reactivatedId.value = instanceId
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
index a65db35..d40069c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImpl.kt
@@ -22,6 +22,7 @@
 import android.util.Log
 import com.android.internal.annotations.KeepForWeakReference
 import com.android.internal.annotations.VisibleForTesting
+import com.android.internal.logging.InstanceId
 import com.android.systemui.broadcast.BroadcastSender
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.media.controls.data.repository.MediaFilterRepository
@@ -66,8 +67,8 @@
     private val mediaFlags: MediaFlags,
     private val mediaFilterRepository: MediaFilterRepository,
 ) : MediaDataManager.Listener {
-    private val _listeners: MutableSet<MediaDataManager.Listener> = mutableSetOf()
-    val listeners: Set<MediaDataManager.Listener>
+    private val _listeners: MutableSet<Listener> = mutableSetOf()
+    val listeners: Set<Listener>
         get() = _listeners.toSet()
     lateinit var mediaDataManager: MediaDataManager
 
@@ -108,13 +109,10 @@
             return
         }
 
-        if (oldKey != null && oldKey != key) {
-            mediaFilterRepository.removeSelectedUserMediaEntry(oldKey)
-        }
-        mediaFilterRepository.addSelectedUserMediaEntry(key, data)
+        mediaFilterRepository.addSelectedUserMediaEntry(data)
 
         // Notify listeners
-        listeners.forEach { it.onMediaDataLoaded(key, oldKey, data) }
+        listeners.forEach { it.onMediaDataLoaded(data.instanceId) }
     }
 
     override fun onSmartspaceMediaDataLoaded(
@@ -160,11 +158,11 @@
             // It could happen there are existing active media resume cards, then we don't need to
             // reactivate.
             if (shouldReactivate) {
-                val lastActiveKey = sorted.lastKey() // most recently active
+                val lastActiveId = sorted.lastKey() // most recently active id
                 // Notify listeners to consider this media active
-                Log.d(TAG, "reactivating $lastActiveKey instead of smartspace")
-                mediaFilterRepository.setReactivatedKey(lastActiveKey)
-                val mediaData = sorted[lastActiveKey]!!.copy(active = true)
+                Log.d(TAG, "reactivating $lastActiveId instead of smartspace")
+                mediaFilterRepository.setReactivatedId(lastActiveId)
+                val mediaData = sorted[lastActiveId]!!.copy(active = true)
                 logger.logRecommendationActivated(
                     mediaData.appUid,
                     mediaData.packageName,
@@ -172,9 +170,7 @@
                 )
                 listeners.forEach {
                     it.onMediaDataLoaded(
-                        lastActiveKey,
-                        lastActiveKey,
-                        mediaData,
+                        lastActiveId,
                         receivedSmartspaceCardLatency =
                             (systemClock.currentTimeMillis() - data.headphoneConnectionTimeMillis)
                                 .toInt(),
@@ -196,27 +192,28 @@
             smartspaceMediaData.packageName,
             smartspaceMediaData.instanceId
         )
-        listeners.forEach { it.onSmartspaceMediaDataLoaded(key, data, shouldPrioritizeMutable) }
+        listeners.forEach { it.onSmartspaceMediaDataLoaded(key, shouldPrioritizeMutable) }
     }
 
     override fun onMediaDataRemoved(key: String) {
-        mediaFilterRepository.removeMediaEntry(key)
-        mediaFilterRepository.removeSelectedUserMediaEntry(key)?.let {
-            // Only notify listeners if something actually changed
-            listeners.forEach { it.onMediaDataRemoved(key) }
+        mediaFilterRepository.removeMediaEntry(key)?.let { mediaData ->
+            val instanceId = mediaData.instanceId
+            mediaFilterRepository.removeSelectedUserMediaEntry(instanceId)?.let {
+                // Only notify listeners if something actually changed
+                listeners.forEach { it.onMediaDataRemoved(instanceId) }
+            }
         }
     }
 
     override fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean) {
         // First check if we had reactivated media instead of forwarding smartspace
-        mediaFilterRepository.reactivatedKey.value?.let {
-            val lastActiveKey = it
-            mediaFilterRepository.setReactivatedKey(null)
-            Log.d(TAG, "expiring reactivated key $lastActiveKey")
+        mediaFilterRepository.reactivatedId.value?.let { lastActiveId ->
+            mediaFilterRepository.setReactivatedId(null)
+            Log.d(TAG, "expiring reactivated key $lastActiveId")
             // Notify listeners to update with actual active value
-            mediaFilterRepository.selectedUserEntries.value[lastActiveKey]?.let { mediaData ->
+            mediaFilterRepository.selectedUserEntries.value[lastActiveId]?.let {
                 listeners.forEach { listener ->
-                    listener.onMediaDataLoaded(lastActiveKey, lastActiveKey, mediaData, immediately)
+                    listener.onMediaDataLoaded(lastActiveId, immediately)
                 }
             }
         }
@@ -240,8 +237,8 @@
             if (!lockscreenUserManager.isProfileAvailable(data.userId)) {
                 // Only remove media when the profile is unavailable.
                 if (DEBUG) Log.d(TAG, "Removing $key after profile change")
-                mediaFilterRepository.removeSelectedUserMediaEntry(key, data)
-                listeners.forEach { listener -> listener.onMediaDataRemoved(key) }
+                mediaFilterRepository.removeSelectedUserMediaEntry(data.instanceId, data)
+                listeners.forEach { listener -> listener.onMediaDataRemoved(data.instanceId) }
             }
         }
     }
@@ -254,16 +251,16 @@
         // Clear the list first, to make sure callbacks from listeners if we have any entries
         // are up to date
         mediaFilterRepository.clearSelectedUserMedia()
-        keyCopy.forEach {
-            if (DEBUG) Log.d(TAG, "Removing $it after user change")
-            listenersCopy.forEach { listener -> listener.onMediaDataRemoved(it) }
+        keyCopy.forEach { instanceId ->
+            if (DEBUG) Log.d(TAG, "Removing $instanceId after user change")
+            listenersCopy.forEach { listener -> listener.onMediaDataRemoved(instanceId) }
         }
 
         mediaFilterRepository.allUserEntries.value.forEach { (key, data) ->
             if (lockscreenUserManager.isCurrentProfile(data.userId)) {
                 if (DEBUG) Log.d(TAG, "Re-adding $key after user change")
-                mediaFilterRepository.addSelectedUserMediaEntry(key, data)
-                listenersCopy.forEach { listener -> listener.onMediaDataLoaded(key, null, data) }
+                mediaFilterRepository.addSelectedUserMediaEntry(data)
+                listenersCopy.forEach { listener -> listener.onMediaDataLoaded(data.instanceId) }
             }
         }
     }
@@ -271,10 +268,12 @@
     /** Invoked when the user has dismissed the media carousel */
     fun onSwipeToDismiss() {
         if (DEBUG) Log.d(TAG, "Media carousel swiped away")
-        val mediaKeys = mediaFilterRepository.selectedUserEntries.value.keys.toSet()
-        mediaKeys.forEach {
-            // Force updates to listeners, needed for re-activated card
-            mediaDataManager.setInactive(it, timedOut = true, forceUpdate = true)
+        val mediaEntries = mediaFilterRepository.allUserEntries.value.entries
+        mediaEntries.forEach { (key, data) ->
+            if (mediaFilterRepository.selectedUserEntries.value.containsKey(data.instanceId)) {
+                // Force updates to listeners, needed for re-activated card
+                mediaDataManager.setInactive(key, timedOut = true, forceUpdate = true)
+            }
         }
         val smartspaceMediaData = mediaFilterRepository.smartspaceMediaData.value
         if (smartspaceMediaData.isActive) {
@@ -312,10 +311,10 @@
     }
 
     /** Add a listener for filtered [MediaData] changes */
-    fun addListener(listener: MediaDataManager.Listener) = _listeners.add(listener)
+    fun addListener(listener: Listener) = _listeners.add(listener)
 
     /** Remove a listener that was registered with addListener */
-    fun removeListener(listener: MediaDataManager.Listener) = _listeners.remove(listener)
+    fun removeListener(listener: Listener) = _listeners.remove(listener)
 
     /**
      * Return the time since last active for the most-recent media.
@@ -325,15 +324,57 @@
      *   the present. MAX_VALUE will be returned if there is no media.
      */
     private fun timeSinceActiveForMostRecentMedia(
-        sortedEntries: SortedMap<String, MediaData>
+        sortedEntries: SortedMap<InstanceId, MediaData>
     ): Long {
         if (sortedEntries.isEmpty()) {
             return Long.MAX_VALUE
         }
 
         val now = systemClock.elapsedRealtime()
-        val lastActiveKey = sortedEntries.lastKey() // most recently active
-        return sortedEntries[lastActiveKey]?.let { now - it.lastActive } ?: Long.MAX_VALUE
+        val lastActiveInstanceId = sortedEntries.lastKey() // most recently active
+        return sortedEntries[lastActiveInstanceId]?.let { now - it.lastActive } ?: Long.MAX_VALUE
+    }
+
+    interface Listener {
+        /**
+         * Called whenever there's new MediaData Loaded for the consumption in views.
+         *
+         * @param immediately indicates should apply the UI changes immediately, otherwise wait
+         *   until the next refresh-round before UI becomes visible. True by default to take in
+         *   place immediately.
+         * @param receivedSmartspaceCardLatency is the latency between headphone connects and sysUI
+         *   displays Smartspace media targets. Will be 0 if the data is not activated by Smartspace
+         *   signal.
+         * @param isSsReactivated indicates resume media card is reactivated by Smartspace
+         *   recommendation signal
+         */
+        fun onMediaDataLoaded(
+            instanceId: InstanceId,
+            immediately: Boolean = true,
+            receivedSmartspaceCardLatency: Int = 0,
+            isSsReactivated: Boolean = false,
+        )
+
+        /**
+         * Called whenever there's new Smartspace media data loaded.
+         *
+         * @param shouldPrioritize indicates the sorting priority of the Smartspace card. If true,
+         *   it will be prioritized as the first card. Otherwise, it will show up as the last card
+         *   as default.
+         */
+        fun onSmartspaceMediaDataLoaded(key: String, shouldPrioritize: Boolean = false)
+
+        /** Called whenever a previously existing Media notification was removed. */
+        fun onMediaDataRemoved(instanceId: InstanceId)
+
+        /**
+         * Called whenever a previously existing Smartspace media data was removed.
+         *
+         * @param immediately indicates should apply the UI changes immediately, otherwise wait
+         *   until the next refresh-round before UI becomes visible. True by default to take in
+         *   place immediately.
+         */
+        fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean = true)
     }
 
     companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataManager.kt
index 2b1070c..2331aa21 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/MediaDataManager.kt
@@ -27,10 +27,10 @@
 interface MediaDataManager {
 
     /** Add a listener for changes in this class */
-    fun addListener(listener: Listener)
+    fun addListener(listener: Listener) {}
 
     /** Remove a listener for changes in this class */
-    fun removeListener(listener: Listener)
+    fun removeListener(listener: Listener) {}
 
     /**
      * Called whenever the player has been paused or stopped for a while, or swiped from QQS. This
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
index 4a92b71..7dbca0a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaCarouselInteractor.kt
@@ -70,7 +70,7 @@
         combine(
                 mediaFilterRepository.selectedUserEntries,
                 mediaFilterRepository.smartspaceMediaData,
-                mediaFilterRepository.reactivatedKey
+                mediaFilterRepository.reactivatedId
             ) { entries, smartspaceMediaData, reactivatedKey ->
                 entries.any { it.value.active } ||
                     (smartspaceMediaData.isActive &&
@@ -142,14 +142,6 @@
         mediaDataFilter.mediaDataManager = this
     }
 
-    override fun addListener(listener: MediaDataManager.Listener) {
-        mediaDataFilter.addListener(listener)
-    }
-
-    override fun removeListener(listener: MediaDataManager.Listener) {
-        mediaDataFilter.removeListener(listener)
-    }
-
     override fun setInactive(key: String, timedOut: Boolean, forceUpdate: Boolean) {
         mediaDataProcessor.setInactive(key, timedOut, forceUpdate)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt
new file mode 100644
index 0000000..5a0388d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractor.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.domain.pipeline.interactor
+
+import com.android.internal.logging.InstanceId
+import com.android.systemui.media.controls.data.repository.MediaFilterRepository
+import com.android.systemui.media.controls.domain.pipeline.MediaDataProcessor
+import com.android.systemui.media.controls.shared.model.MediaControlModel
+import com.android.systemui.media.controls.shared.model.MediaData
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+
+/** Encapsulates business logic for single media control. */
+class MediaControlInteractor(
+    instanceId: InstanceId,
+    repository: MediaFilterRepository,
+    private val mediaDataProcessor: MediaDataProcessor,
+) {
+
+    val mediaControl: Flow<MediaControlModel?> =
+        repository.selectedUserEntries
+            .map { entries -> entries[instanceId]?.let { toMediaControlModel(it) } }
+            .distinctUntilChanged()
+
+    fun removeMediaControl(key: String, delayMs: Long): Boolean {
+        return mediaDataProcessor.dismissMediaData(key, delayMs)
+    }
+
+    private fun toMediaControlModel(data: MediaData): MediaControlModel {
+        return with(data) {
+            MediaControlModel(
+                uid = appUid,
+                packageName = packageName,
+                instanceId = instanceId,
+                token = token,
+                appIcon = appIcon,
+                clickIntent = clickIntent,
+                appName = app,
+                songName = song,
+                artistName = artist,
+                artwork = artwork,
+                deviceData = device,
+                semanticActionButtons = semanticActions,
+                notificationActionButtons = actions,
+                actionsToShowInCollapsed = actionsToShowInCompact,
+                isResume = resumption,
+                resumeProgress = resumeProgress,
+            )
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt
new file mode 100644
index 0000000..d57b049
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractor.kt
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.domain.pipeline.interactor
+
+import android.content.Context
+import android.content.Intent
+import android.provider.Settings
+import android.util.Log
+import androidx.annotation.VisibleForTesting
+import com.android.internal.jank.InteractionJankMonitor
+import com.android.systemui.animation.Expandable
+import com.android.systemui.broadcast.BroadcastSender
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.media.controls.data.repository.MediaFilterRepository
+import com.android.systemui.media.controls.domain.pipeline.MediaDataProcessor
+import com.android.systemui.media.controls.shared.model.MediaRecModel
+import com.android.systemui.media.controls.shared.model.MediaRecommendationsModel
+import com.android.systemui.media.controls.shared.model.SmartspaceMediaData
+import com.android.systemui.plugins.ActivityStarter
+import java.net.URISyntaxException
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+/** Encapsulates business logic for media recommendation */
+@SysUISingleton
+class MediaRecommendationsInteractor
+@Inject
+constructor(
+    @Application applicationScope: CoroutineScope,
+    @Application private val applicationContext: Context,
+    repository: MediaFilterRepository,
+    private val mediaDataProcessor: MediaDataProcessor,
+    private val broadcastSender: BroadcastSender,
+    private val activityStarter: ActivityStarter,
+) {
+
+    val recommendations: Flow<MediaRecommendationsModel> =
+        repository.smartspaceMediaData.map { toRecommendationsModel(it) }.distinctUntilChanged()
+
+    /** Indicates whether the recommendations card is active. */
+    val isActive: StateFlow<Boolean> =
+        repository.smartspaceMediaData
+            .map { it.isActive }
+            .distinctUntilChanged()
+            .stateIn(applicationScope, SharingStarted.WhileSubscribed(), false)
+
+    fun removeMediaRecommendations(key: String, dismissIntent: Intent?, delayMs: Long) {
+        mediaDataProcessor.dismissSmartspaceRecommendation(key, delayMs)
+        if (dismissIntent == null) {
+            Log.w(TAG, "Cannot create dismiss action click action: extras missing dismiss_intent.")
+            return
+        }
+
+        val className = dismissIntent.component?.className
+        if (className == EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME) {
+            // Dismiss the card Smartspace data through Smartspace trampoline activity.
+            applicationContext.startActivity(dismissIntent)
+        } else {
+            broadcastSender.sendBroadcast(dismissIntent)
+        }
+    }
+
+    fun startSettings() {
+        activityStarter.startActivity(SETTINGS_INTENT, /* dismissShade= */ true)
+    }
+
+    fun startClickIntent(expandable: Expandable, intent: Intent) {
+        if (shouldActivityOpenInForeground(intent)) {
+            // Request to unlock the device if the activity needs to be opened in foreground.
+            activityStarter.postStartActivityDismissingKeyguard(
+                intent,
+                0 /* delay */,
+                expandable.activityTransitionController(
+                    InteractionJankMonitor.CUJ_SHADE_APP_LAUNCH_FROM_MEDIA_PLAYER
+                )
+            )
+        } else {
+            // Otherwise, open the activity in background directly.
+            applicationContext.startActivity(intent)
+        }
+    }
+
+    /** Returns if the action will open the activity in foreground. */
+    private fun shouldActivityOpenInForeground(intent: Intent): Boolean {
+        val intentString = intent.extras?.getString(EXTRAS_SMARTSPACE_INTENT) ?: return false
+        try {
+            val wrapperIntent = Intent.parseUri(intentString, Intent.URI_INTENT_SCHEME)
+            return wrapperIntent.getBooleanExtra(KEY_SMARTSPACE_OPEN_IN_FOREGROUND, false)
+        } catch (e: URISyntaxException) {
+            Log.wtf(TAG, "Failed to create intent from URI: $intentString")
+            e.printStackTrace()
+        }
+        return false
+    }
+
+    private fun toRecommendationsModel(data: SmartspaceMediaData): MediaRecommendationsModel {
+        val mediaRecs = ArrayList<MediaRecModel>()
+        data.recommendations.forEach {
+            with(it) { mediaRecs.add(MediaRecModel(intent, title, subtitle, icon, extras)) }
+        }
+        return with(data) {
+            MediaRecommendationsModel(
+                key = targetId,
+                uid = getUid(applicationContext),
+                packageName = packageName,
+                instanceId = instanceId,
+                appName = getAppName(applicationContext),
+                dismissIntent = dismissIntent,
+                areRecommendationsValid = isValid(),
+                mediaRecs = mediaRecs,
+            )
+        }
+    }
+
+    companion object {
+
+        private const val TAG = "MediaRecommendationsInteractor"
+
+        // TODO (b/237284176) : move AGSA reference out.
+        private const val EXTRAS_SMARTSPACE_INTENT =
+            "com.google.android.apps.gsa.smartspace.extra.SMARTSPACE_INTENT"
+        @VisibleForTesting
+        const val EXPORTED_SMARTSPACE_TRAMPOLINE_ACTIVITY_NAME =
+            "com.google.android.apps.gsa.staticplugins.opa.smartspace." +
+                "ExportedSmartspaceTrampolineActivity"
+
+        private const val KEY_SMARTSPACE_OPEN_IN_FOREGROUND = "KEY_OPEN_IN_FOREGROUND"
+
+        private val SETTINGS_INTENT = Intent(Settings.ACTION_MEDIA_CONTROLS_SETTINGS)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaControlModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaControlModel.kt
new file mode 100644
index 0000000..d4e34b5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaControlModel.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.shared.model
+
+import android.app.Notification
+import android.app.PendingIntent
+import android.graphics.drawable.Icon
+import android.media.session.MediaSession
+import android.os.Process
+import com.android.internal.logging.InstanceId
+
+data class MediaControlModel(
+    val uid: Int = Process.INVALID_UID,
+    val packageName: String,
+    val instanceId: InstanceId,
+    val token: MediaSession.Token?,
+    val appIcon: Icon?,
+    val clickIntent: PendingIntent?,
+    val appName: String?,
+    val songName: CharSequence?,
+    val artistName: CharSequence?,
+    val artwork: Icon?,
+    val deviceData: MediaDeviceData?,
+    /** [MediaButton] contains [MediaAction] objects which represent specific buttons in the UI */
+    val semanticActionButtons: MediaButton?,
+    val notificationActionButtons: List<MediaAction>,
+    /**
+     * List of [notificationActionButtons] indices shown on smaller version of media player. Check
+     * [Notification.MediaStyle.setShowActionsInCompactView].
+     */
+    val actionsToShowInCollapsed: List<Int>,
+    /** Whether player is in resumption state. */
+    val isResume: Boolean,
+    /** Track seek bar progress (0 - 1) when [isResume] is true. */
+    val resumeProgress: Double?,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaRecommendationsModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaRecommendationsModel.kt
new file mode 100644
index 0000000..43bd32d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/MediaRecommendationsModel.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.shared.model
+
+import android.content.Intent
+import android.graphics.drawable.Icon
+import android.os.Bundle
+import android.os.Process
+import com.android.internal.logging.InstanceId
+
+data class MediaRecommendationsModel(
+    val key: String,
+    val uid: Int = Process.INVALID_UID,
+    val packageName: String,
+    val instanceId: InstanceId? = null,
+    val appName: CharSequence? = null,
+    val dismissIntent: Intent? = null,
+    /** Whether the model contains enough number of valid recommendations. */
+    val areRecommendationsValid: Boolean = false,
+    val mediaRecs: List<MediaRecModel>,
+)
+
+/** Represents smartspace media recommendation action */
+data class MediaRecModel(
+    val intent: Intent? = null,
+    val title: CharSequence? = null,
+    val subtitle: CharSequence? = null,
+    val icon: Icon? = null,
+    val extras: Bundle? = null,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/SmartspaceMediaData.kt b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/SmartspaceMediaData.kt
index b446585..9e15dbb 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/SmartspaceMediaData.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/shared/model/SmartspaceMediaData.kt
@@ -20,6 +20,7 @@
 import android.content.Context
 import android.content.Intent
 import android.content.pm.PackageManager
+import android.os.Process
 import android.text.TextUtils
 import android.util.Log
 import androidx.annotation.VisibleForTesting
@@ -87,6 +88,15 @@
             null
         }
     }
+
+    fun getUid(context: Context): Int {
+        return try {
+            context.packageManager.getApplicationInfo(packageName, 0 /* flags */).uid
+        } catch (e: PackageManager.NameNotFoundException) {
+            Log.w(TAG, "Fail to get media recommendation's app info", e)
+            Process.INVALID_UID
+        }
+    }
 }
 
 /** Key to indicate whether this card should be used to re-show recent media */
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt
new file mode 100644
index 0000000..eec43a6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.ui.util
+
+import android.app.WallpaperColors
+import android.content.Context
+import android.graphics.Rect
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.GradientDrawable
+import android.graphics.drawable.Icon
+import android.graphics.drawable.LayerDrawable
+import android.util.Log
+import com.android.systemui.media.controls.ui.animation.backgroundEndFromScheme
+import com.android.systemui.media.controls.ui.animation.backgroundStartFromScheme
+import com.android.systemui.monet.ColorScheme
+import com.android.systemui.util.getColorWithAlpha
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.withContext
+
+object MediaArtworkHelper {
+
+    /**
+     * This method should be called from a background thread. WallpaperColors.fromBitmap takes a
+     * good amount of time. We do that work on the background executor to avoid stalling animations
+     * on the UI Thread.
+     */
+    suspend fun getWallpaperColor(
+        applicationContext: Context,
+        backgroundDispatcher: CoroutineDispatcher,
+        artworkIcon: Icon?,
+        tag: String,
+    ): WallpaperColors? =
+        withContext(backgroundDispatcher) {
+            return@withContext artworkIcon?.let {
+                if (it.type == Icon.TYPE_BITMAP || it.type == Icon.TYPE_ADAPTIVE_BITMAP) {
+                    // Avoids extra processing if this is already a valid bitmap
+                    it.bitmap.let { artworkBitmap ->
+                        if (artworkBitmap.isRecycled) {
+                            Log.d(tag, "Cannot load wallpaper color from a recycled bitmap")
+                            null
+                        } else {
+                            WallpaperColors.fromBitmap(artworkBitmap)
+                        }
+                    }
+                } else {
+                    it.loadDrawable(applicationContext)?.let { artworkDrawable ->
+                        WallpaperColors.fromDrawable(artworkDrawable)
+                    }
+                }
+            }
+        }
+
+    /**
+     * Returns a scaled [Drawable] of a given [Icon] centered in [width]x[height] background size.
+     */
+    fun getScaledBackground(context: Context, icon: Icon, width: Int, height: Int): Drawable? {
+        val drawable = icon.loadDrawable(context)
+        val bounds = Rect(0, 0, width, height)
+        if (bounds.width() > width || bounds.height() > height) {
+            val offsetX = (bounds.width() - width) / 2.0f
+            val offsetY = (bounds.height() - height) / 2.0f
+            bounds.offset(-offsetX.toInt(), -offsetY.toInt())
+        }
+        drawable?.bounds = bounds
+        return drawable
+    }
+
+    /** Adds [gradient] on a given [albumArt] drawable using [colorScheme]. */
+    fun setUpGradientColorOnDrawable(
+        albumArt: Drawable?,
+        gradient: GradientDrawable,
+        colorScheme: ColorScheme,
+        startAlpha: Float,
+        endAlpha: Float
+    ): LayerDrawable {
+        gradient.colors =
+            intArrayOf(
+                getColorWithAlpha(backgroundStartFromScheme(colorScheme), startAlpha),
+                getColorWithAlpha(backgroundEndFromScheme(colorScheme), endAlpha)
+            )
+        return LayerDrawable(arrayOf(albumArt, gradient))
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/GutsViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/GutsViewModel.kt
new file mode 100644
index 0000000..e508e1b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/GutsViewModel.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.ui.viewmodel
+
+import android.annotation.ColorInt
+import android.graphics.drawable.Drawable
+
+/** Models UI state for media guts menu */
+data class GutsViewModel(
+    val gutsText: CharSequence,
+    @ColorInt val textColor: Int,
+    @ColorInt val buttonBackgroundColor: Int,
+    @ColorInt val buttonTextColor: Int,
+    val isDismissEnabled: Boolean = true,
+    val onDismissClicked: () -> Unit,
+    val cancelTextBackground: Drawable?,
+    val onSettingsClicked: () -> Unit,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecViewModel.kt
new file mode 100644
index 0000000..2f9fc9b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecViewModel.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.ui.viewmodel
+
+import android.annotation.ColorInt
+import android.graphics.drawable.Drawable
+import com.android.systemui.animation.Expandable
+
+/** Models UI state for media recommendation item */
+data class MediaRecViewModel(
+    val contentDescription: CharSequence,
+    val title: CharSequence = "",
+    @ColorInt val titleColor: Int,
+    val subtitle: CharSequence = "",
+    @ColorInt val subtitleColor: Int,
+    /** track progress [0 - 100] for the recommendation album. */
+    val progress: Int = 0,
+    @ColorInt val progressColor: Int,
+    val albumIcon: Drawable? = null,
+    val appIcon: Drawable? = null,
+    val onClicked: ((Expandable, Int) -> Unit),
+)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
new file mode 100644
index 0000000..19ea00d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.ui.viewmodel
+
+import android.app.WallpaperColors
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.graphics.Bitmap
+import android.graphics.Color
+import android.graphics.drawable.BitmapDrawable
+import android.graphics.drawable.ColorDrawable
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.GradientDrawable
+import android.graphics.drawable.Icon
+import android.graphics.drawable.LayerDrawable
+import android.os.Process
+import android.util.Log
+import androidx.appcompat.content.res.AppCompatResources
+import com.android.internal.logging.InstanceId
+import com.android.systemui.animation.Expandable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.media.controls.domain.pipeline.interactor.MediaRecommendationsInteractor
+import com.android.systemui.media.controls.shared.model.MediaRecModel
+import com.android.systemui.media.controls.shared.model.MediaRecommendationsModel
+import com.android.systemui.media.controls.ui.animation.accentPrimaryFromScheme
+import com.android.systemui.media.controls.ui.animation.surfaceFromScheme
+import com.android.systemui.media.controls.ui.animation.textPrimaryFromScheme
+import com.android.systemui.media.controls.ui.animation.textSecondaryFromScheme
+import com.android.systemui.media.controls.ui.controller.MediaViewController.Companion.GUTS_ANIMATION_DURATION
+import com.android.systemui.media.controls.ui.util.MediaArtworkHelper
+import com.android.systemui.media.controls.util.MediaDataUtils
+import com.android.systemui.media.controls.util.MediaUiEventLogger
+import com.android.systemui.monet.ColorScheme
+import com.android.systemui.monet.Style
+import com.android.systemui.res.R
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.withContext
+
+/** Models UI state and handles user input for media recommendations */
+@SysUISingleton
+class MediaRecommendationsViewModel
+@Inject
+constructor(
+    @Application private val applicationContext: Context,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+    private val interactor: MediaRecommendationsInteractor,
+    private val logger: MediaUiEventLogger,
+) {
+
+    val mediaRecsCard: Flow<MediaRecsCardViewModel?> =
+        interactor.recommendations
+            .map { recsCard -> toRecsViewModel(recsCard) }
+            .distinctUntilChanged()
+            .flowOn(backgroundDispatcher)
+
+    /**
+     * Called whenever the recommendation has been expired or removed by the user. This method
+     * removes the recommendation card entirely from the carousel.
+     */
+    private fun onMediaRecommendationsDismissed(
+        key: String,
+        uid: Int,
+        packageName: String,
+        dismissIntent: Intent?,
+        instanceId: InstanceId?
+    ) {
+        // TODO (b/330897926) log smartspace card reported (SMARTSPACE_CARD_DISMISS_EVENT).
+        logger.logLongPressDismiss(uid, packageName, instanceId)
+        interactor.removeMediaRecommendations(key, dismissIntent, GUTS_DISMISS_DELAY_MS_DURATION)
+    }
+
+    private fun onClicked(
+        expandable: Expandable,
+        intent: Intent?,
+        packageName: String,
+        instanceId: InstanceId?,
+        index: Int
+    ) {
+        if (intent == null || intent.extras == null) {
+            Log.e(TAG, "No tap action can be set up")
+            return
+        }
+
+        if (index == -1) {
+            logger.logRecommendationCardTap(packageName, instanceId)
+        } else {
+            logger.logRecommendationItemTap(packageName, instanceId, index)
+        }
+        // TODO (b/330897926) log smartspace card reported (SMARTSPACE_CARD_CLICK_EVENT).
+        interactor.startClickIntent(expandable, intent)
+    }
+
+    private suspend fun toRecsViewModel(model: MediaRecommendationsModel): MediaRecsCardViewModel? {
+        if (!model.areRecommendationsValid) {
+            Log.e(TAG, "Received an invalid recommendation list")
+            return null
+        }
+        if (model.appName == null || model.uid == Process.INVALID_UID) {
+            Log.w(TAG, "Fail to get media recommendation's app info")
+            return null
+        }
+
+        val scheme = getColorScheme(model.packageName) ?: return null
+
+        // Capture width & height from views in foreground for artwork scaling in background
+        val width =
+            applicationContext.resources.getDimensionPixelSize(R.dimen.qs_media_rec_album_width)
+        val height =
+            applicationContext.resources.getDimensionPixelSize(
+                R.dimen.qs_media_rec_album_height_expanded
+            )
+
+        val appIcon = applicationContext.packageManager.getApplicationIcon(model.packageName)
+        val textPrimaryColor = textPrimaryFromScheme(scheme)
+        val textSecondaryColor = textSecondaryFromScheme(scheme)
+        val backgroundColor = surfaceFromScheme(scheme)
+
+        var areTitlesVisible = false
+        var areSubtitlesVisible = false
+        val mediaRecs =
+            model.mediaRecs.map { mediaRecModel ->
+                areTitlesVisible = areTitlesVisible || !mediaRecModel.title.isNullOrEmpty()
+                areSubtitlesVisible = areSubtitlesVisible || !mediaRecModel.subtitle.isNullOrEmpty()
+                val progress = MediaDataUtils.getDescriptionProgress(mediaRecModel.extras) ?: 0.0
+                MediaRecViewModel(
+                    contentDescription =
+                        setUpMediaRecContentDescription(mediaRecModel, model.appName),
+                    title = mediaRecModel.title ?: "",
+                    titleColor = textPrimaryColor,
+                    subtitle = mediaRecModel.subtitle ?: "",
+                    subtitleColor = textSecondaryColor,
+                    progress = (progress * 100).toInt(),
+                    progressColor = textPrimaryColor,
+                    albumIcon =
+                        getRecCoverBackground(
+                            mediaRecModel.icon,
+                            width,
+                            height,
+                        ),
+                    appIcon = appIcon,
+                    onClicked = { expandable, index ->
+                        onClicked(
+                            expandable,
+                            mediaRecModel.intent,
+                            model.packageName,
+                            model.instanceId,
+                            index,
+                        )
+                    }
+                )
+            }
+        // Subtitles should only be visible if titles are visible.
+        areSubtitlesVisible = areTitlesVisible && areSubtitlesVisible
+
+        return MediaRecsCardViewModel(
+            contentDescription = { gutsVisible ->
+                if (gutsVisible) {
+                    applicationContext.getString(
+                        R.string.controls_media_close_session,
+                        model.appName
+                    )
+                } else {
+                    applicationContext.getString(R.string.controls_media_smartspace_rec_header)
+                }
+            },
+            cardColor = backgroundColor,
+            cardTitleColor = textPrimaryColor,
+            onClicked = { expandable ->
+                onClicked(
+                    expandable,
+                    model.dismissIntent,
+                    model.packageName,
+                    model.instanceId,
+                    index = -1
+                )
+            },
+            onLongClicked = {
+                logger.logLongPressOpen(model.uid, model.packageName, model.instanceId)
+            },
+            mediaRecs = mediaRecs,
+            areTitlesVisible = areTitlesVisible,
+            areSubtitlesVisible = areSubtitlesVisible,
+            gutsMenu = toGutsViewModel(model, scheme),
+        )
+    }
+
+    private fun toGutsViewModel(
+        model: MediaRecommendationsModel,
+        scheme: ColorScheme
+    ): GutsViewModel {
+        return GutsViewModel(
+            gutsText =
+                applicationContext.getString(R.string.controls_media_close_session, model.appName),
+            textColor = textPrimaryFromScheme(scheme),
+            buttonBackgroundColor = accentPrimaryFromScheme(scheme),
+            buttonTextColor = surfaceFromScheme(scheme),
+            onDismissClicked = {
+                onMediaRecommendationsDismissed(
+                    model.key,
+                    model.uid,
+                    model.packageName,
+                    model.dismissIntent,
+                    model.instanceId
+                )
+            },
+            cancelTextBackground =
+                applicationContext.getDrawable(R.drawable.qs_media_outline_button),
+            onSettingsClicked = {
+                logger.logLongPressSettings(model.uid, model.packageName, model.instanceId)
+                interactor.startSettings()
+            },
+        )
+    }
+
+    /** Returns the recommendation album cover of [width]x[height] size. */
+    private suspend fun getRecCoverBackground(icon: Icon?, width: Int, height: Int): Drawable =
+        withContext(backgroundDispatcher) {
+            return@withContext MediaArtworkHelper.getWallpaperColor(
+                    applicationContext,
+                    backgroundDispatcher,
+                    icon,
+                    TAG,
+                )
+                ?.let { wallpaperColors ->
+                    addGradientToRecommendationAlbum(
+                        icon!!,
+                        ColorScheme(wallpaperColors, true, Style.CONTENT),
+                        width,
+                        height
+                    )
+                }
+                ?: ColorDrawable(Color.TRANSPARENT)
+        }
+
+    private fun addGradientToRecommendationAlbum(
+        artworkIcon: Icon,
+        mutableColorScheme: ColorScheme,
+        width: Int,
+        height: Int
+    ): LayerDrawable {
+        // First try scaling rec card using bitmap drawable.
+        // If returns null, set drawable bounds.
+        val albumArt =
+            getScaledRecommendationCover(artworkIcon, width, height)
+                ?: MediaArtworkHelper.getScaledBackground(
+                    applicationContext,
+                    artworkIcon,
+                    width,
+                    height
+                )
+        val gradient =
+            AppCompatResources.getDrawable(applicationContext, R.drawable.qs_media_rec_scrim)
+                ?.mutate() as GradientDrawable
+        return MediaArtworkHelper.setUpGradientColorOnDrawable(
+            albumArt,
+            gradient,
+            mutableColorScheme,
+            MEDIA_REC_SCRIM_START_ALPHA,
+            MEDIA_REC_SCRIM_END_ALPHA
+        )
+    }
+
+    private fun setUpMediaRecContentDescription(
+        mediaRec: MediaRecModel,
+        appName: CharSequence?
+    ): CharSequence {
+        // Set up the accessibility label for the media item.
+        val artistName = mediaRec.extras?.getString(KEY_SMARTSPACE_ARTIST_NAME, "")
+        return if (artistName.isNullOrEmpty()) {
+            applicationContext.getString(
+                R.string.controls_media_smartspace_rec_item_no_artist_description,
+                mediaRec.title,
+                appName
+            )
+        } else {
+            applicationContext.getString(
+                R.string.controls_media_smartspace_rec_item_description,
+                mediaRec.title,
+                artistName,
+                appName
+            )
+        }
+    }
+
+    private fun getColorScheme(packageName: String): ColorScheme? {
+        // Set up recommendation card's header.
+        return try {
+            val packageManager = applicationContext.packageManager
+            val applicationInfo = packageManager.getApplicationInfo(packageName, 0 /* flags */)
+            // Set up media source app's logo.
+            val icon = packageManager.getApplicationIcon(applicationInfo)
+            ColorScheme(WallpaperColors.fromDrawable(icon), darkTheme = true)
+        } catch (e: PackageManager.NameNotFoundException) {
+            Log.w(TAG, "Fail to get media recommendation's app info", e)
+            null
+        }
+    }
+
+    /** Returns a [Drawable] of a given [artworkIcon] scaled to [width]x[height] size, . */
+    private fun getScaledRecommendationCover(
+        artworkIcon: Icon,
+        width: Int,
+        height: Int
+    ): Drawable? {
+        check(width > 0) { "Width must be a positive number but was $width" }
+        check(height > 0) { "Height must be a positive number but was $height" }
+
+        return if (
+            artworkIcon.type == Icon.TYPE_BITMAP || artworkIcon.type == Icon.TYPE_ADAPTIVE_BITMAP
+        ) {
+            artworkIcon.bitmap?.let {
+                val bitmap = Bitmap.createScaledBitmap(it, width, height, false)
+                BitmapDrawable(applicationContext.resources, bitmap)
+            }
+        } else {
+            null
+        }
+    }
+
+    companion object {
+        private const val TAG = "MediaRecommendationsViewModel"
+        private const val KEY_SMARTSPACE_ARTIST_NAME = "artist_name"
+        private const val MEDIA_REC_SCRIM_START_ALPHA = 0.15f
+        private const val MEDIA_REC_SCRIM_END_ALPHA = 1.0f
+        /**
+         * Delay duration is based on [GUTS_ANIMATION_DURATION], it should have 100 ms increase in
+         * order to let the animation end.
+         */
+        private const val GUTS_DISMISS_DELAY_MS_DURATION = 334L
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt
new file mode 100644
index 0000000..d1713b5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.ui.viewmodel
+
+import android.annotation.ColorInt
+import com.android.systemui.animation.Expandable
+
+/** Models UI state for media recommendations card. */
+data class MediaRecsCardViewModel(
+    val contentDescription: (Boolean) -> CharSequence,
+    @ColorInt val cardColor: Int,
+    @ColorInt val cardTitleColor: Int,
+    val onClicked: (Expandable) -> Unit,
+    val onLongClicked: () -> Unit,
+    val mediaRecs: List<MediaRecViewModel>,
+    val areTitlesVisible: Boolean,
+    val areSubtitlesVisible: Boolean,
+    val gutsMenu: GutsViewModel,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt
index 2c25fe2..09f973c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/util/MediaUiEventLogger.kt
@@ -99,15 +99,15 @@
         logger.log(MediaUiEvent.DISMISS_SWIPE)
     }
 
-    fun logLongPressOpen(uid: Int, packageName: String, instanceId: InstanceId) {
+    fun logLongPressOpen(uid: Int, packageName: String, instanceId: InstanceId?) {
         logger.logWithInstanceId(MediaUiEvent.OPEN_LONG_PRESS, uid, packageName, instanceId)
     }
 
-    fun logLongPressDismiss(uid: Int, packageName: String, instanceId: InstanceId) {
+    fun logLongPressDismiss(uid: Int, packageName: String, instanceId: InstanceId?) {
         logger.logWithInstanceId(MediaUiEvent.DISMISS_LONG_PRESS, uid, packageName, instanceId)
     }
 
-    fun logLongPressSettings(uid: Int, packageName: String, instanceId: InstanceId) {
+    fun logLongPressSettings(uid: Int, packageName: String, instanceId: InstanceId?) {
         logger.logWithInstanceId(
             MediaUiEvent.OPEN_SETTINGS_LONG_PRESS,
             uid,
@@ -188,7 +188,7 @@
         )
     }
 
-    fun logRecommendationItemTap(packageName: String, instanceId: InstanceId, position: Int) {
+    fun logRecommendationItemTap(packageName: String, instanceId: InstanceId?, position: Int) {
         logger.logWithInstanceIdAndPosition(
             MediaUiEvent.MEDIA_RECOMMENDATION_ITEM_TAP,
             0,
@@ -198,7 +198,7 @@
         )
     }
 
-    fun logRecommendationCardTap(packageName: String, instanceId: InstanceId) {
+    fun logRecommendationCardTap(packageName: String, instanceId: InstanceId?) {
         logger.logWithInstanceId(
             MediaUiEvent.MEDIA_RECOMMENDATION_CARD_TAP,
             0,
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialogDelegate.kt
index 8aed535..d87b612 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/devicepolicy/ScreenCaptureDisabledDialogDelegate.kt
@@ -15,6 +15,8 @@
  */
 package com.android.systemui.mediaprojection.devicepolicy
 
+import android.app.AlertDialog
+import android.content.Context
 import android.content.DialogInterface.BUTTON_POSITIVE
 import android.content.res.Resources
 import com.android.systemui.dagger.qualifiers.Main
@@ -23,22 +25,33 @@
 import javax.inject.Inject
 
 /** Dialog that shows that screen capture is disabled on this device. */
-class ScreenCaptureDisabledDialogDelegate @Inject constructor(
-        @Main private val resources: Resources,
-        private val systemUIDialogFactory: SystemUIDialog.Factory
-) : SystemUIDialog.Delegate {
+class ScreenCaptureDisabledDialogDelegate
+@Inject
+constructor(
+    private val context: Context,
+    @Main private val resources: Resources,
+) {
 
-    override fun createDialog(): SystemUIDialog {
-        val dialog = systemUIDialogFactory.create(this)
-        dialog.setTitle(resources.getString(R.string.screen_capturing_disabled_by_policy_dialog_title))
+    fun createPlainDialog(): AlertDialog {
+        return AlertDialog.Builder(context, R.style.Theme_SystemUI_Dialog).create().also {
+            initDialog(it)
+        }
+    }
+
+    fun createSysUIDialog(): AlertDialog {
+        return SystemUIDialog(context).also { initDialog(it) }
+    }
+
+    private fun initDialog(dialog: AlertDialog) {
+        dialog.setTitle(
+            resources.getString(R.string.screen_capturing_disabled_by_policy_dialog_title)
+        )
         dialog.setMessage(
             resources.getString(R.string.screen_capturing_disabled_by_policy_dialog_description)
         )
         dialog.setIcon(R.drawable.ic_cast)
-        dialog.setButton(BUTTON_POSITIVE, resources.getString(android.R.string.ok)) {
-            _, _ -> dialog.cancel()
+        dialog.setButton(BUTTON_POSITIVE, resources.getString(android.R.string.ok)) { _, _ ->
+            dialog.cancel()
         }
-
-        return dialog
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionDialogDelegate.kt
index 1983a67..6224170 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionDialogDelegate.kt
@@ -47,25 +47,25 @@
     private val mediaProjectionMetricsLogger: MediaProjectionMetricsLogger,
     @DrawableRes private val dialogIconDrawable: Int? = null,
     @ColorRes private val dialogIconTint: Int? = null,
+    @ScreenShareMode val defaultSelectedMode: Int = screenShareOptions.first().mode,
 ) : DialogDelegate<T>, AdapterView.OnItemSelectedListener {
     private lateinit var dialogTitle: TextView
     private lateinit var startButton: TextView
     private lateinit var cancelButton: TextView
     private lateinit var warning: TextView
     private lateinit var screenShareModeSpinner: Spinner
-    private var hasCancelBeenLogged: Boolean = false
     protected lateinit var dialog: AlertDialog
-    var selectedScreenShareOption: ScreenShareOption = screenShareOptions.first()
+    private var shouldLogCancel: Boolean = true
+    var selectedScreenShareOption: ScreenShareOption =
+        screenShareOptions.first { it.mode == defaultSelectedMode }
 
     @CallSuper
     override fun onStop(dialog: T) {
         // onStop can be called multiple times and we only want to log once.
-        if (hasCancelBeenLogged) {
-            return
+        if (shouldLogCancel) {
+            mediaProjectionMetricsLogger.notifyProjectionRequestCancelled(hostUid)
+            shouldLogCancel = false
         }
-
-        mediaProjectionMetricsLogger.notifyProjectionRequestCancelled(hostUid)
-        hasCancelBeenLogged = true
     }
 
     @CallSuper
@@ -94,7 +94,7 @@
     }
 
     private fun initScreenShareOptions() {
-        selectedScreenShareOption = screenShareOptions.first()
+        selectedScreenShareOption = screenShareOptions.first { it.mode == defaultSelectedMode }
         warning.text = warningText
         initScreenShareSpinner()
     }
@@ -120,6 +120,8 @@
                 }
             }
         screenShareModeSpinner.isLongClickable = false
+        val defaultModePosition = screenShareOptions.indexOfFirst { it.mode == defaultSelectedMode }
+        screenShareModeSpinner.setSelection(defaultModePosition, /* animate= */ false)
     }
 
     override fun onItemSelected(adapterView: AdapterView<*>?, view: View, pos: Int, id: Long) {
@@ -140,7 +142,10 @@
     }
 
     protected fun setStartButtonOnClickListener(listener: View.OnClickListener?) {
-        startButton.setOnClickListener(listener)
+        startButton.setOnClickListener { view ->
+            shouldLogCancel = false
+            listener?.onClick(view)
+        }
     }
 
     protected fun setCancelButtonOnClickListener(listener: View.OnClickListener?) {
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
index 17f9caf..da9e00d 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
@@ -319,7 +319,7 @@
         final UserHandle hostUserHandle = getHostUserHandle();
         if (mScreenCaptureDevicePolicyResolver.get()
                 .isScreenCaptureCompletelyDisabled(hostUserHandle)) {
-            AlertDialog dialog = mScreenCaptureDisabledDialogDelegate.createDialog();
+            AlertDialog dialog = mScreenCaptureDisabledDialogDelegate.createPlainDialog();
             setUpDialog(dialog);
             dialog.show();
             return true;
diff --git a/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt b/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
index e7b6e63..1704812 100644
--- a/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
+++ b/packages/SystemUI/src/com/android/systemui/model/SceneContainerPlugin.kt
@@ -19,6 +19,7 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.compose.animation.scene.SceneKey
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.scene.shared.model.Scenes
@@ -27,6 +28,7 @@
 import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE
 import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED
 import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
+import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED
 import dagger.Lazy
 import javax.inject.Inject
 
@@ -38,8 +40,10 @@
 class SceneContainerPlugin
 @Inject
 constructor(
-    private val interactor: Lazy<SceneInteractor>,
+    private val sceneInteractor: Lazy<SceneInteractor>,
+    private val occlusionInteractor: Lazy<SceneContainerOcclusionInteractor>,
 ) {
+
     /**
      * Returns an override value for the given [flag] or `null` if the scene framework isn't enabled
      * or if the flag value doesn't need to be overridden.
@@ -49,10 +53,18 @@
             return null
         }
 
-        val transitionState = interactor.get().transitionState.value
+        val transitionState = sceneInteractor.get().transitionState.value
         val idleTransitionStateOrNull = transitionState as? ObservableTransitionState.Idle
         val currentSceneOrNull = idleTransitionStateOrNull?.scene
-        return currentSceneOrNull?.let { sceneKey -> EvaluatorByFlag[flag]?.invoke(sceneKey) }
+        val invisibleDueToOcclusion = occlusionInteractor.get().invisibleDueToOcclusion.value
+        return currentSceneOrNull?.let { sceneKey ->
+            EvaluatorByFlag[flag]?.invoke(
+                SceneContainerPluginState(
+                    scene = sceneKey,
+                    invisibleDueToOcclusion = invisibleDueToOcclusion,
+                )
+            )
+        }
     }
 
     companion object {
@@ -67,12 +79,24 @@
          * to be overridden by the scene framework.
          */
         val EvaluatorByFlag =
-            mapOf<Int, (SceneKey) -> Boolean>(
-                SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE to { it != Scenes.Gone },
-                SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED to { it == Scenes.Shade },
-                SYSUI_STATE_QUICK_SETTINGS_EXPANDED to { it == Scenes.QuickSettings },
-                SYSUI_STATE_BOUNCER_SHOWING to { it == Scenes.Bouncer },
-                SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING to { it == Scenes.Lockscreen },
+            mapOf<Int, (SceneContainerPluginState) -> Boolean>(
+                SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE to { it.scene != Scenes.Gone },
+                SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED to { it.scene == Scenes.Shade },
+                SYSUI_STATE_QUICK_SETTINGS_EXPANDED to { it.scene == Scenes.QuickSettings },
+                SYSUI_STATE_BOUNCER_SHOWING to { it.scene == Scenes.Bouncer },
+                SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING to
+                    {
+                        it.scene == Scenes.Lockscreen && !it.invisibleDueToOcclusion
+                    },
+                SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED to
+                    {
+                        it.scene == Scenes.Lockscreen && it.invisibleDueToOcclusion
+                    },
             )
     }
+
+    data class SceneContainerPluginState(
+        val scene: SceneKey,
+        val invisibleDueToOcclusion: Boolean,
+    )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
index d49a513..63989ef 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavBarHelper.java
@@ -56,6 +56,7 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.internal.accessibility.common.ShortcutConstants;
 import com.android.systemui.Dumpable;
 import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
 import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
@@ -380,7 +381,7 @@
             // permission
             final List<String> a11yButtonTargets =
                     mAccessibilityManager.getAccessibilityShortcutTargets(
-                            AccessibilityManager.ACCESSIBILITY_BUTTON);
+                            ShortcutConstants.UserShortcutType.SOFTWARE);
             final int requestingServices = a11yButtonTargets.size();
 
             clickable = requestingServices >= 1;
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
index 4fe3a11..ade56c4 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
@@ -85,6 +85,7 @@
 import android.view.MotionEvent;
 import android.view.Surface;
 import android.view.View;
+import android.view.ViewConfiguration;
 import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.InternalInsetsInfo;
 import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
@@ -186,6 +187,7 @@
     /** Allow some time inbetween the long press for back and recents. */
     private static final int LOCK_TO_APP_GESTURE_TOLERANCE = 200;
     private static final long AUTODIM_TIMEOUT_MS = 2250;
+    private static final float QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON = 3f;
 
     private final Context mContext;
     private final Bundle mSavedState;
@@ -223,6 +225,7 @@
     private final int mNavColorSampleMargin;
     private EdgeBackGestureHandler mEdgeBackGestureHandler;
     private NavigationBarFrame mFrame;
+    private MotionEvent mCurrentDownEvent;
 
     private @WindowVisibleState int mNavigationBarWindowState = WINDOW_STATE_SHOWING;
 
@@ -238,6 +241,8 @@
     private int mLayoutDirection;
 
     private Optional<Long> mHomeButtonLongPressDurationMs;
+    private Optional<Long> mOverrideHomeButtonLongPressDurationMs = Optional.empty();
+    private Optional<Float> mOverrideHomeButtonLongPressSlopMultiplier = Optional.empty();
 
     /** @see android.view.WindowInsetsController#setSystemBarsAppearance(int, int) */
     private @Appearance int mAppearance;
@@ -405,6 +410,25 @@
         }
 
         @Override
+        public void setOverrideHomeButtonLongPress(long duration, float slopMultiplier) {
+            mOverrideHomeButtonLongPressDurationMs = Optional.of(duration)
+                    .filter(value -> value > 0);
+            mOverrideHomeButtonLongPressSlopMultiplier = Optional.of(slopMultiplier)
+                    .filter(value -> value > 0);
+            if (mOverrideHomeButtonLongPressDurationMs.isPresent()) {
+                Log.d(TAG, "Receive duration override: "
+                        + mOverrideHomeButtonLongPressDurationMs.get());
+            }
+            if (mOverrideHomeButtonLongPressSlopMultiplier.isPresent()) {
+                Log.d(TAG, "Receive slop multiplier override: "
+                        + mOverrideHomeButtonLongPressSlopMultiplier.get());
+            }
+            if (mView != null) {
+                reconfigureHomeLongClick();
+            }
+        }
+
+        @Override
         public void onHomeRotationEnabled(boolean enabled) {
             mView.getRotationButtonController().setHomeRotationEnabled(enabled);
         }
@@ -1016,7 +1040,10 @@
         if (mView.getHomeButton().getCurrentView() == null) {
             return;
         }
-        if (mHomeButtonLongPressDurationMs.isPresent() || !mLongPressHomeEnabled) {
+        if (mHomeButtonLongPressDurationMs.isPresent()
+                || mOverrideHomeButtonLongPressDurationMs.isPresent()
+                || mOverrideHomeButtonLongPressSlopMultiplier.isPresent()
+                || !mLongPressHomeEnabled) {
             mView.getHomeButton().getCurrentView().setLongClickable(false);
             mView.getHomeButton().getCurrentView().setHapticFeedbackEnabled(false);
             mView.getHomeButton().setOnLongClickListener(null);
@@ -1038,6 +1065,10 @@
         pw.println("  mStartingQuickSwitchRotation=" + mStartingQuickSwitchRotation);
         pw.println("  mCurrentRotation=" + mCurrentRotation);
         pw.println("  mHomeButtonLongPressDurationMs=" + mHomeButtonLongPressDurationMs);
+        pw.println("  mOverrideHomeButtonLongPressDurationMs="
+                + mOverrideHomeButtonLongPressDurationMs);
+        pw.println("  mOverrideHomeButtonLongPressSlopMultiplier="
+                + mOverrideHomeButtonLongPressSlopMultiplier);
         pw.println("  mLongPressHomeEnabled=" + mLongPressHomeEnabled);
         pw.println("  mNavigationBarWindowState="
                 + windowStateToString(mNavigationBarWindowState));
@@ -1331,6 +1362,10 @@
         final Optional<CentralSurfaces> centralSurfacesOptional = mCentralSurfacesOptionalLazy.get();
         switch (event.getAction()) {
             case MotionEvent.ACTION_DOWN:
+                if (mCurrentDownEvent != null) {
+                    mCurrentDownEvent.recycle();
+                }
+                mCurrentDownEvent = MotionEvent.obtain(event);
                 mHomeBlockedThisTouch = false;
                 if (mTelecomManagerOptional.isPresent()
                         && mTelecomManagerOptional.get().isRinging()) {
@@ -1342,9 +1377,45 @@
                     }
                 }
                 if (mLongPressHomeEnabled) {
-                    mHomeButtonLongPressDurationMs.ifPresent(longPressDuration -> {
-                        mHandler.postDelayed(mOnVariableDurationHomeLongClick, longPressDuration);
-                    });
+                    if (mOverrideHomeButtonLongPressDurationMs.isPresent()) {
+                        Log.d(TAG, "ACTION_DOWN Launcher override duration: "
+                                + mOverrideHomeButtonLongPressDurationMs.get());
+                        mHandler.postDelayed(mOnVariableDurationHomeLongClick,
+                                mOverrideHomeButtonLongPressDurationMs.get());
+                    } else if (mOverrideHomeButtonLongPressSlopMultiplier.isPresent()) {
+                        // If override timeout doesn't exist but override touch slop exists, we use
+                        // system default long press duration
+                        Log.d(TAG, "ACTION_DOWN default duration: "
+                                + ViewConfiguration.getLongPressTimeout());
+                        mHandler.postDelayed(mOnVariableDurationHomeLongClick,
+                                ViewConfiguration.getLongPressTimeout());
+                    } else {
+                        mHomeButtonLongPressDurationMs.ifPresent(longPressDuration -> {
+                            Log.d(TAG, "ACTION_DOWN original duration: " + longPressDuration);
+                            mHandler.postDelayed(mOnVariableDurationHomeLongClick,
+                                    longPressDuration);
+                        });
+                    }
+                }
+                break;
+            case MotionEvent.ACTION_MOVE:
+                if (!mHandler.hasCallbacks(mOnVariableDurationHomeLongClick)) {
+                    Log.w(TAG, "No callback. Don't handle touch slop.");
+                    break;
+                }
+                float customSlopMultiplier = mOverrideHomeButtonLongPressSlopMultiplier.orElse(1f);
+                float touchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
+                float calculatedTouchSlop =
+                        customSlopMultiplier * QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON * touchSlop;
+                float touchSlopSquared = calculatedTouchSlop * calculatedTouchSlop;
+
+                float dx = event.getX() - mCurrentDownEvent.getX();
+                float dy = event.getY() - mCurrentDownEvent.getY();
+                double distanceSquared = (dx * dx) + (dy * dy);
+                if (distanceSquared > touchSlopSquared) {
+                    Log.i(TAG, "Touch slop passed. Abort.");
+                    mView.abortCurrentGesture();
+                    mHandler.removeCallbacks(mOnVariableDurationHomeLongClick);
                 }
                 break;
             case MotionEvent.ACTION_UP:
diff --git a/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt b/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt
index 3f8834a..9380d44 100644
--- a/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/power/domain/interactor/PowerInteractor.kt
@@ -281,5 +281,10 @@
                 powerButtonLaunchGestureTriggeredDuringSleep = false,
             )
         }
+
+        /** Helper method for tests to simulate the device screen state change event. */
+        fun PowerInteractor.setScreenPowerState(screenPowerState: ScreenPowerState) {
+            this.onScreenPowerStateUpdated(screenPowerState)
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/flags/NewQsUI.kt b/packages/SystemUI/src/com/android/systemui/qs/flags/NewQsUI.kt
new file mode 100644
index 0000000..8af5665
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/flags/NewQsUI.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.flags
+
+import com.android.systemui.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for reading or using the notification avalanche suppression flag state. */
+@Suppress("NOTHING_TO_INLINE")
+object NewQsUI {
+    /** The aconfig flag name */
+    const val FLAG_NAME = Flags.FLAG_QS_UI_REFACTOR
+
+    /** A token used for dependency declaration */
+    val token: FlagToken
+        get() = FlagToken(FLAG_NAME, isEnabled)
+
+    /** Is the refactor enabled */
+    @JvmStatic
+    inline val isEnabled
+        get() = Flags.qsUiRefactor()
+
+    /**
+     * Called to ensure code is only run when the flag is enabled. This protects users from the
+     * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+     * build to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun isUnexpectedlyInLegacyMode() =
+        RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+    /**
+     * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+     * the flag is enabled to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index 2360f27..3004485 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -620,7 +620,7 @@
                 showRippleEffect = false
                 setOnTouchListener(longPressEffect)
                 if (!longPressEffectViewBinder.isBound) {
-                    longPressEffectViewBinder.bind(this, longPressEffect)
+                    longPressEffectViewBinder.bind(this, state.spec, longPressEffect)
                 }
             } else {
                 // Long-press effects might have been enabled before but the new state does not
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index dc42b5c..b27b974 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -63,6 +63,7 @@
 import com.android.systemui.statusbar.policy.CastController.CastDevice;
 import com.android.systemui.statusbar.policy.HotspotController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.util.DialogKt;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -245,6 +246,10 @@
                             new DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
                                     INTERACTION_JANK_TAG));
                 } else {
+                    if (dialog.getWindow() != null) {
+                        DialogKt.registerAnimationOnBackInvoked(dialog,
+                                dialog.getWindow().getDecorView());
+                    }
                     dialog.show();
                 }
             });
@@ -272,7 +277,7 @@
                 state.secondaryLabel = getDeviceName(device);
                 state.stateDescription = state.stateDescription + ","
                         + mContext.getString(
-                                R.string.accessibility_cast_name, state.label);
+                        R.string.accessibility_cast_name, state.label);
                 connecting = false;
                 break;
             } else if (device.state == CastDevice.STATE_CONNECTING) {
@@ -342,14 +347,14 @@
     };
 
     private final SignalCallback mSignalCallback = new SignalCallback() {
-                @Override
-                public void setWifiIndicators(@NonNull WifiIndicators indicators) {
-                    // statusIcon.visible has the connected status information
-                    boolean enabledAndConnected = indicators.enabled
-                            && (indicators.qsIcon != null && indicators.qsIcon.visible);
-                    setCastTransportAllowed(enabledAndConnected);
-                }
-            };
+        @Override
+        public void setWifiIndicators(@NonNull WifiIndicators indicators) {
+            // statusIcon.visible has the connected status information
+            boolean enabledAndConnected = indicators.enabled
+                    && (indicators.qsIcon != null && indicators.qsIcon.visible);
+            setCastTransportAllowed(enabledAndConnected);
+        }
+    };
 
     private final HotspotController.Callback mHotspotCallback =
             new HotspotController.Callback() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HearingDevicesTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HearingDevicesTile.java
index 1fb701e..81a2026 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HearingDevicesTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HearingDevicesTile.java
@@ -26,6 +26,7 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.Flags;
+import com.android.systemui.accessibility.hearingaid.HearingDevicesDialogManager;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.ActivityStarter;
@@ -45,6 +46,8 @@
 
     public static final String TILE_SPEC = "hearing_devices";
 
+    private final HearingDevicesDialogManager mDialogManager;
+
     @Inject
     public HearingDevicesTile(
             QSHost host,
@@ -55,10 +58,12 @@
             MetricsLogger metricsLogger,
             StatusBarStateController statusBarStateController,
             ActivityStarter activityStarter,
-            QSLogger qsLogger
+            QSLogger qsLogger,
+            HearingDevicesDialogManager hearingDevicesDialogManager
     ) {
         super(host, uiEventLogger, backgroundLooper, mainHandler, falsingManager, metricsLogger,
                 statusBarStateController, activityStarter, qsLogger);
+        mDialogManager = hearingDevicesDialogManager;
     }
 
     @Override
@@ -68,7 +73,7 @@
 
     @Override
     protected void handleClick(@Nullable View view) {
-
+        mUiHandler.post(() -> mDialogManager.showDialog(view));
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
index 1b73225..e1b742e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java
@@ -182,12 +182,19 @@
 
     @Override
     public boolean isAvailable() {
+        if (isWalletRoleAvailable()) {
+            return !mPackageManager.hasSystemFeature(FEATURE_CHROME_OS);
+        }
         return mPackageManager.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
                 && !mPackageManager.hasSystemFeature(FEATURE_CHROME_OS)
                 && mSecureSettings.getStringForUser(NFC_PAYMENT_DEFAULT_COMPONENT,
                     UserHandle.USER_CURRENT) != null;
     }
 
+    private boolean isWalletRoleAvailable() {
+        return mHost.getUserId() == UserHandle.USER_SYSTEM && mController.isWalletRoleAvailable();
+    }
+
     @Nullable
     @Override
     public Intent getLongClickIntent() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java
index 2f8fe42..3eeb2a3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/SensorPrivacyToggleTile.java
@@ -25,6 +25,7 @@
 import android.provider.Settings;
 import android.safetycenter.SafetyCenterManager;
 import android.service.quicksettings.Tile;
+import android.text.TextUtils;
 import android.view.View;
 import android.widget.Switch;
 
@@ -127,7 +128,7 @@
         } else {
             state.secondaryLabel = mContext.getString(R.string.quick_settings_camera_mic_available);
         }
-        state.contentDescription = state.label;
+        state.contentDescription = TextUtils.concat(state.label, ", ", state.secondaryLabel);
         state.expandedAccessibilityClassName = Switch.class.getName();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt
index bc016bd..065e89f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt
@@ -88,6 +88,7 @@
     fun logUserActionRejectedByPolicy(
         userAction: QSTileUserAction,
         tileSpec: TileSpec,
+        restriction: String,
     ) {
         tileSpec
             .getLogBuffer()
@@ -95,7 +96,7 @@
                 tileSpec.getLogTag(),
                 LogLevel.DEBUG,
                 { str1 = userAction.toLogString() },
-                { "tile $str1: rejected by policy" }
+                { "tile $str1: rejected by policy, restriction: $restriction" }
             )
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
index 45c6fff..8782524 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
@@ -178,7 +178,8 @@
     /**
      * Creates a user input flow which:
      * - filters false inputs with [falsingManager]
-     * - takes care of a tile being disable by policy using [disabledByPolicyInteractor]
+     * - takes care of a tile being disable by policy using [disabledByPolicyInteractor]. The
+     *   restrictions will be checked sequentially and the first one to block will be considered.
      * - notifies [userActionInteractor] about the action
      * - logs it accordingly using [qsTileLogger] and [qsTileAnalytics]
      *
@@ -201,18 +202,22 @@
             .onEach { userActionInteractor().handleInput(it.input) }
             .flowOn(backgroundDispatcher)
 
+    /**
+     * The restrictions will be checked sequentially and the first one to block will be considered.
+     */
     private fun Flow<QSTileUserAction>.filterByPolicy(user: UserHandle): Flow<QSTileUserAction> =
         config.policy.let { policy ->
             when (policy) {
                 is QSTilePolicy.NoRestrictions -> this@filterByPolicy
                 is QSTilePolicy.Restricted ->
                     filter { action ->
-                        val result =
-                            disabledByPolicyInteractor.isDisabled(user, policy.userRestriction)
-                        !disabledByPolicyInteractor.handlePolicyResult(result).also { isDisabled ->
-                            if (isDisabled) {
-                                qsTileLogger.logUserActionRejectedByPolicy(action, spec)
+                        policy.userRestrictions.none {
+                            val result = disabledByPolicyInteractor.isDisabled(user, it)
+                            val handleResult = disabledByPolicyInteractor.handlePolicyResult(result)
+                            if (handleResult) {
+                                qsTileLogger.logUserActionRejectedByPolicy(action, spec, it)
                             }
+                            handleResult
                         }
                     }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
index 1410473..a531ee6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java
@@ -1450,7 +1450,8 @@
 
     Intent getConfiguratorQrCodeGeneratorIntentOrNull(WifiEntry wifiEntry) {
         if (!mFeatureFlags.isEnabled(Flags.SHARE_WIFI_QS_BUTTON) || wifiEntry == null
-                || mWifiManager == null || !wifiEntry.canShare()) {
+                || mWifiManager == null || !wifiEntry.canShare()
+                || wifiEntry.getWifiConfiguration() == null) {
             return null;
         }
         Intent intent = new Intent();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt
index f13ecf3..56ba079 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemFactory.kt
@@ -45,7 +45,7 @@
     abstract fun create(context: Context, cachedDevice: CachedBluetoothDevice): DeviceItem
 }
 
-internal class ActiveMediaDeviceItemFactory : DeviceItemFactory() {
+internal open class ActiveMediaDeviceItemFactory : DeviceItemFactory() {
     override fun isFilterMatched(
         context: Context,
         cachedDevice: CachedBluetoothDevice,
@@ -72,7 +72,18 @@
     }
 }
 
-internal class AvailableMediaDeviceItemFactory : DeviceItemFactory() {
+internal class ActiveHearingDeviceItemFactory : ActiveMediaDeviceItemFactory() {
+    override fun isFilterMatched(
+        context: Context,
+        cachedDevice: CachedBluetoothDevice,
+        audioManager: AudioManager?
+    ): Boolean {
+        return BluetoothUtils.isActiveMediaDevice(cachedDevice) &&
+            BluetoothUtils.isAvailableHearingDevice(cachedDevice)
+    }
+}
+
+internal open class AvailableMediaDeviceItemFactory : DeviceItemFactory() {
     override fun isFilterMatched(
         context: Context,
         cachedDevice: CachedBluetoothDevice,
@@ -101,6 +112,17 @@
     }
 }
 
+internal class AvailableHearingDeviceItemFactory : ActiveMediaDeviceItemFactory() {
+    override fun isFilterMatched(
+        context: Context,
+        cachedDevice: CachedBluetoothDevice,
+        audioManager: AudioManager?
+    ): Boolean {
+        return !BluetoothUtils.isActiveMediaDevice(cachedDevice) &&
+            BluetoothUtils.isAvailableHearingDevice(cachedDevice)
+    }
+}
+
 internal class ConnectedDeviceItemFactory : DeviceItemFactory() {
     override fun isFilterMatched(
         context: Context,
@@ -135,7 +157,7 @@
     }
 }
 
-internal class SavedDeviceItemFactory : DeviceItemFactory() {
+internal open class SavedDeviceItemFactory : DeviceItemFactory() {
     override fun isFilterMatched(
         context: Context,
         cachedDevice: CachedBluetoothDevice,
@@ -168,3 +190,25 @@
         )
     }
 }
+
+internal class SavedHearingDeviceItemFactory : SavedDeviceItemFactory() {
+    override fun isFilterMatched(
+        context: Context,
+        cachedDevice: CachedBluetoothDevice,
+        audioManager: AudioManager?
+    ): Boolean {
+        return if (Flags.enableHideExclusivelyManagedBluetoothDevice()) {
+            !BluetoothUtils.isExclusivelyManagedBluetoothDevice(
+                context,
+                cachedDevice.getDevice()
+            ) &&
+                cachedDevice.isHearingAidDevice &&
+                cachedDevice.bondState == BluetoothDevice.BOND_BONDED &&
+                !cachedDevice.isConnected
+        } else {
+            cachedDevice.isHearingAidDevice &&
+                cachedDevice.bondState == BluetoothDevice.BOND_BONDED &&
+                !cachedDevice.isConnected
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt
index 1df496b..fce25ec 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/bluetooth/DeviceItemInteractor.kt
@@ -137,7 +137,6 @@
                             ?.create(context, cachedDevice)
                     }
                     .sort(displayPriority, bluetoothAdapter?.mostRecentlyConnectedDevices)
-
             // Only emit when the job is not cancelled
             if (isActive) {
                 mutableDeviceItemUpdate.tryEmit(deviceItems)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/SensorPrivacyToggleTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/SensorPrivacyToggleTileDataInteractor.kt
new file mode 100644
index 0000000..7117629
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/SensorPrivacyToggleTileDataInteractor.kt
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.sensorprivacy
+
+import android.hardware.SensorPrivacyManager.Sensors.CAMERA
+import android.hardware.SensorPrivacyManager.Sensors.MICROPHONE
+import android.hardware.SensorPrivacyManager.Sensors.Sensor
+import android.os.UserHandle
+import android.provider.DeviceConfig
+import android.util.Log
+import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel
+import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlin.coroutines.CoroutineContext
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.withContext
+
+/** Observes SensorPrivacyToggle mode state changes providing the [SensorPrivacyToggleTileModel]. */
+class SensorPrivacyToggleTileDataInteractor
+@AssistedInject
+constructor(
+    @Background private val bgCoroutineContext: CoroutineContext,
+    private val privacyController: IndividualSensorPrivacyController,
+    @Assisted @Sensor private val sensorId: Int,
+) : QSTileDataInteractor<SensorPrivacyToggleTileModel> {
+    @AssistedFactory
+    interface Factory {
+        fun create(@Sensor id: Int): SensorPrivacyToggleTileDataInteractor
+    }
+
+    override fun tileData(
+        user: UserHandle,
+        triggers: Flow<DataUpdateTrigger>
+    ): Flow<SensorPrivacyToggleTileModel> =
+        conflatedCallbackFlow {
+                val callback =
+                    IndividualSensorPrivacyController.Callback { sensor, blocked ->
+                        if (sensor == sensorId) trySend(SensorPrivacyToggleTileModel(blocked))
+                    }
+                privacyController.addCallback(callback) // does not emit an initial state
+                awaitClose { privacyController.removeCallback(callback) }
+            }
+            .onStart {
+                emit(SensorPrivacyToggleTileModel(privacyController.isSensorBlocked(sensorId)))
+            }
+            .distinctUntilChanged()
+            .flowOn(bgCoroutineContext)
+
+    override fun availability(user: UserHandle) =
+        flow { emit(isAvailable()) }.flowOn(bgCoroutineContext)
+
+    private suspend fun isAvailable(): Boolean {
+        return privacyController.supportsSensorToggle(sensorId) && isSensorDeviceConfigSet()
+    }
+
+    private suspend fun isSensorDeviceConfigSet(): Boolean =
+        withContext(bgCoroutineContext) {
+            try {
+                val deviceConfigName = getDeviceConfigName(sensorId)
+                return@withContext DeviceConfig.getBoolean(
+                    DeviceConfig.NAMESPACE_PRIVACY,
+                    deviceConfigName,
+                    true
+                )
+            } catch (exception: IllegalArgumentException) {
+                Log.w(
+                    TAG,
+                    "isDeviceConfigSet for sensorId $sensorId: " +
+                        "Defaulting to true due to exception. ",
+                    exception
+                )
+                return@withContext true
+            }
+        }
+
+    private fun getDeviceConfigName(sensorId: Int): String {
+        if (sensorId == MICROPHONE) {
+            return "mic_toggle_enabled"
+        } else if (sensorId == CAMERA) {
+            return "camera_toggle_enabled"
+        } else {
+            throw IllegalArgumentException("getDeviceConfigName: unexpected sensorId: $sensorId")
+        }
+    }
+
+    private companion object {
+        const val TAG = "SensorPrivacyToggleTileException"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/SensorPrivacyToggleTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/SensorPrivacyToggleTileUserActionInteractor.kt
new file mode 100644
index 0000000..9711cb8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/SensorPrivacyToggleTileUserActionInteractor.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.sensorprivacy.domain
+
+import android.content.Intent
+import android.hardware.SensorPrivacyManager.Sensors.Sensor
+import android.hardware.SensorPrivacyManager.Sources.QS_TILE
+import android.provider.Settings
+import android.safetycenter.SafetyCenterManager
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.plugins.ActivityStarter
+import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.interactor.QSTileInput
+import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel
+import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+/** Handles sensor privacy toggle tile clicks and long clicks. */
+class SensorPrivacyToggleTileUserActionInteractor
+@AssistedInject
+constructor(
+    private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler,
+    private val keyguardInteractor: KeyguardInteractor,
+    private val activityStarter: ActivityStarter,
+    private val sensorPrivacyController: IndividualSensorPrivacyController,
+    private val safetyCenterManager: SafetyCenterManager,
+    @Assisted @Sensor private val sensorId: Int,
+) : QSTileUserActionInteractor<SensorPrivacyToggleTileModel> {
+    @AssistedFactory
+    interface Factory {
+        fun create(@Sensor id: Int): SensorPrivacyToggleTileUserActionInteractor
+    }
+
+    // should only be initialized in code known to run in background thread
+    private lateinit var longClickIntent: Intent
+
+    override suspend fun handleInput(input: QSTileInput<SensorPrivacyToggleTileModel>) =
+        with(input) {
+            when (action) {
+                is QSTileUserAction.Click -> {
+                    val blocked = input.data.isBlocked
+                    if (
+                        sensorPrivacyController.requiresAuthentication() &&
+                            keyguardInteractor.isKeyguardDismissible.value &&
+                            keyguardInteractor.isKeyguardShowing()
+                    ) {
+                        activityStarter.postQSRunnableDismissingKeyguard {
+                            sensorPrivacyController.setSensorBlocked(QS_TILE, sensorId, !blocked)
+                        }
+                        return
+                    }
+                    sensorPrivacyController.setSensorBlocked(QS_TILE, sensorId, !blocked)
+                }
+                is QSTileUserAction.LongClick -> {
+                    if (!::longClickIntent.isInitialized) {
+                        longClickIntent =
+                            Intent(
+                                if (safetyCenterManager.isSafetyCenterEnabled) {
+                                    Settings.ACTION_PRIVACY_CONTROLS
+                                } else {
+                                    Settings.ACTION_PRIVACY_SETTINGS
+                                }
+                            )
+                    }
+                    qsTileIntentUserActionHandler.handle(action.view, longClickIntent)
+                }
+            }
+        }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/model/SensorPrivacyToggleTileModel.kt
similarity index 70%
copy from packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
copy to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/model/SensorPrivacyToggleTileModel.kt
index 0c92b50..04719af 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/model/SensorPrivacyToggleTileModel.kt
@@ -14,7 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.notification.stack.shared.model
+package com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model
 
-/** Models the clipping rounded rectangle of the notification stack */
-data class StackClipping(val bounds: StackBounds, val rounding: StackRounding)
+/**
+ * Sensor privacy toggle tile model.
+ *
+ * @param isBlocked is true when the sensor is blocked
+ */
+@JvmInline value class SensorPrivacyToggleTileModel(val isBlocked: Boolean)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyTileResources.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyTileResources.kt
new file mode 100644
index 0000000..2a9fd07
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyTileResources.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.sensorprivacy.ui
+
+import com.android.systemui.res.R
+
+sealed interface SensorPrivacyTileResources {
+    fun getIconRes(isBlocked: Boolean): Int
+    fun getTileLabelRes(): Int
+
+    data object CameraPrivacyTileResources : SensorPrivacyTileResources {
+        override fun getIconRes(isBlocked: Boolean): Int {
+            return if (isBlocked) {
+                R.drawable.qs_camera_access_icon_off
+            } else {
+                R.drawable.qs_camera_access_icon_on
+            }
+        }
+
+        override fun getTileLabelRes(): Int {
+            return R.string.quick_settings_camera_label
+        }
+    }
+
+    data object MicrophonePrivacyTileResources : SensorPrivacyTileResources {
+        override fun getIconRes(isBlocked: Boolean): Int {
+            return if (isBlocked) {
+                R.drawable.qs_mic_access_off
+            } else {
+                R.drawable.qs_mic_access_on
+            }
+        }
+
+        override fun getTileLabelRes(): Int {
+            return R.string.quick_settings_mic_label
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapper.kt
new file mode 100644
index 0000000..52622d2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapper.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.sensorprivacy.ui
+
+import android.content.res.Resources
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel
+import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.res.R
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+
+/** Maps [SensorPrivacyToggleTileModel] to [QSTileState]. */
+class SensorPrivacyToggleTileMapper
+@AssistedInject
+constructor(
+    @Main private val resources: Resources,
+    private val theme: Resources.Theme,
+    @Assisted private val sensorPrivacyTileResources: SensorPrivacyTileResources,
+) : QSTileDataToStateMapper<SensorPrivacyToggleTileModel> {
+
+    @AssistedFactory
+    interface Factory {
+        fun create(
+            sensorPrivacyTileResources: SensorPrivacyTileResources
+        ): SensorPrivacyToggleTileMapper
+    }
+
+    override fun map(config: QSTileConfig, data: SensorPrivacyToggleTileModel): QSTileState =
+        QSTileState.build(resources, theme, config.uiConfig) {
+            label = resources.getString(sensorPrivacyTileResources.getTileLabelRes())
+            contentDescription = label
+            supportedActions =
+                setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK)
+            icon = {
+                Icon.Loaded(
+                    resources.getDrawable(
+                        sensorPrivacyTileResources.getIconRes(data.isBlocked),
+                        theme
+                    ),
+                    null
+                )
+            }
+
+            sideViewIcon = QSTileState.SideViewIcon.None
+
+            if (data.isBlocked) {
+                activationState = QSTileState.ActivationState.INACTIVE
+                secondaryLabel = resources.getString(R.string.quick_settings_camera_mic_blocked)
+            } else {
+                activationState = QSTileState.ActivationState.ACTIVE
+                secondaryLabel = resources.getString(R.string.quick_settings_camera_mic_available)
+            }
+        }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
index 18a4e2d..e9e9d8b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
@@ -65,10 +65,10 @@
     data object NoRestrictions : QSTilePolicy
 
     /**
-     * Tile might be disabled by policy. [userRestriction] is usually a constant from
+     * Tile might be disabled by policy. Each item in [userRestrictions] is usually a constant from
      * [android.os.UserManager] like [android.os.UserManager.DISALLOW_AIRPLANE_MODE].
      * [com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor] is commonly used
      * to resolve this and show user a message when needed.
      */
-    data class Restricted(val userRestriction: String) : QSTilePolicy
+    data class Restricted(val userRestrictions: List<String>) : QSTilePolicy
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
index 6710504..8d5aeab5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/adapter/QSSceneAdapter.kt
@@ -93,6 +93,9 @@
     val isQsFullyCollapsed: Boolean
         get() = true
 
+    /** Request that the customizer be closed. Possibly animating it. */
+    fun requestCloseCustomizer()
+
     sealed interface State {
 
         val isVisible: Boolean
@@ -277,6 +280,10 @@
         bottomNavBarSize.emit(padding)
     }
 
+    override fun requestCloseCustomizer() {
+        qsImpl.value?.closeCustomizer()
+    }
+
     private fun QSImpl.applyState(state: QSSceneAdapter.State) {
         setQsVisible(state.isVisible)
         setExpanded(state.isVisible && state.expansion > 0f)
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
similarity index 64%
copy from tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
copy to packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
index 4e64ab0..a3c2cbb 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsContainerViewModel.kt
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.systemui.qs.ui.viewmodel
 
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
+import com.android.systemui.brightness.ui.viewmodel.BrightnessSliderViewModel
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
 
-import java.util.List;
-
-public interface AslMarshallable {
-
-    /** Creates the on-device DOM element from the AslMarshallable Java Object. */
-    List<Element> toOdDomElements(Document doc);
-}
+@SysUISingleton
+class QuickSettingsContainerViewModel
+@Inject
+constructor(
+    val brightnessSliderViewModel: BrightnessSliderViewModel,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
index c695d4c..62ed491 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
@@ -20,7 +20,6 @@
 import com.android.compose.animation.scene.Back
 import com.android.compose.animation.scene.Swipe
 import com.android.compose.animation.scene.SwipeDirection
-import com.android.compose.animation.scene.UserAction
 import com.android.compose.animation.scene.UserActionResult
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.qs.FooterActionsController
@@ -47,7 +46,9 @@
     val destinationScenes =
         qsSceneAdapter.isCustomizing.map { customizing ->
             if (customizing) {
-                mapOf<UserAction, UserActionResult>(Back to UserActionResult(Scenes.QuickSettings))
+                // TODO(b/332749288) Empty map so there are no back handlers and back can close
+                // customizer
+                emptyMap()
                 // TODO(b/330200163) Add an Up from Bottom to be able to collapse the shade
                 // while customizing
             } else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 7c1a2c0..4ece7b6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -99,6 +99,7 @@
 import com.android.systemui.recents.OverviewProxyService.OverviewProxyListener;
 import com.android.systemui.scene.domain.interactor.SceneInteractor;
 import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.model.Scenes;
 import com.android.systemui.settings.DisplayTracker;
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.ShadeViewController;
@@ -239,6 +240,11 @@
                             } else {
                                 mShadeViewControllerLazy.get().finishInputFocusTransfer(velocity);
                             }
+                        } else if (action == ACTION_UP) {
+                            // Gesture was too short to be picked up by scene container touch
+                            // handling; programmatically start the transition to shade scene.
+                            mSceneInteractor.get().changeScene(
+                                    Scenes.Shade, "short launcher swipe");
                         }
                     }
                     event.recycle();
@@ -259,6 +265,12 @@
         }
 
         @Override
+        public void setOverrideHomeButtonLongPress(long duration, float slopMultiplier) {
+            verifyCallerAndClearCallingIdentityPostMain("setOverrideHomeButtonLongPress",
+                    () -> notifySetOverrideHomeButtonLongPress(duration, slopMultiplier));
+        }
+
+        @Override
         public void onBackPressed() {
             verifyCallerAndClearCallingIdentityPostMain("onBackPressed", () -> {
                 sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
@@ -947,6 +959,12 @@
         }
     }
 
+    private void notifySetOverrideHomeButtonLongPress(long duration, float slopMultiplier) {
+        for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
+            mConnectionCallbacks.get(i).setOverrideHomeButtonLongPress(duration, slopMultiplier);
+        }
+    }
+
     public void notifyAssistantVisibilityChanged(float visibility) {
         try {
             if (mOverviewProxy != null) {
@@ -1104,6 +1122,8 @@
         default void startAssistant(Bundle bundle) {}
         default void setAssistantOverridesRequested(int[] invocationTypes) {}
         default void animateNavBarLongPress(boolean isTouchDown, boolean shrink, long durationMs) {}
+        /** Set override of home button long press duration and touch slop multiplier. */
+        default void setOverrideHomeButtonLongPress(long override, float slopMultiplier) {}
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
index 832fc3f..dab61fa 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueDialogDelegate.kt
@@ -131,7 +131,7 @@
                     .isScreenCaptureCompletelyDisabled(UserHandle.of(userTracker.userId))
         ) {
             mainExecutor.execute {
-                screenCaptureDisabledDialogDelegate.createDialog().show()
+                screenCaptureDisabledDialogDelegate.createSysUIDialog().show()
                 screenRecordSwitch.isChecked = false
             }
             return
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
index a823916..5d60373 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractor.kt
@@ -19,45 +19,91 @@
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.compose.animation.scene.SceneKey
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.keyguard.domain.interactor.KeyguardOcclusionInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.scene.shared.model.Scenes
 import javax.inject.Inject
-import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.stateIn
 
 /** Encapsulates logic regarding the occlusion state of the scene container. */
 @SysUISingleton
 class SceneContainerOcclusionInteractor
 @Inject
 constructor(
+    @Application applicationScope: CoroutineScope,
     keyguardOcclusionInteractor: KeyguardOcclusionInteractor,
     sceneInteractor: SceneInteractor,
     keyguardTransitionInteractor: KeyguardTransitionInteractor,
 ) {
+    /** Whether a show-when-locked activity is at the top of the current activity stack. */
+    private val isOccludingActivityShown: StateFlow<Boolean> =
+        keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop.stateIn(
+            scope = applicationScope,
+            started = SharingStarted.WhileSubscribed(),
+            initialValue = false,
+        )
+
+    /**
+     * Whether AOD is fully shown (not transitioning) or partially shown during a transition to/from
+     * AOD.
+     */
+    private val isAodFullyOrPartiallyShown: StateFlow<Boolean> =
+        keyguardTransitionInteractor
+            .transitionValue(KeyguardState.AOD)
+            .onStart { emit(0f) }
+            .map { it > 0 }
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = false,
+            )
+
     /**
      * Whether the scene container should become invisible due to "occlusion" by an in-foreground
      * "show when locked" activity.
      */
-    val invisibleDueToOcclusion: Flow<Boolean> =
+    val invisibleDueToOcclusion: StateFlow<Boolean> =
         combine(
-                keyguardOcclusionInteractor.isShowWhenLockedActivityOnTop,
+                isOccludingActivityShown,
                 sceneInteractor.transitionState,
-                keyguardTransitionInteractor
-                    .transitionValue(KeyguardState.AOD)
-                    .onStart { emit(0f) }
-                    .map { it > 0 }
-                    .distinctUntilChanged(),
+                isAodFullyOrPartiallyShown,
             ) { isOccludingActivityShown, sceneTransitionState, isAodFullyOrPartiallyShown ->
-                isOccludingActivityShown &&
-                    !isAodFullyOrPartiallyShown &&
-                    sceneTransitionState.canBeOccluded
+                invisibleDueToOcclusion(
+                    isOccludingActivityShown = isOccludingActivityShown,
+                    sceneTransitionState = sceneTransitionState,
+                    isAodFullyOrPartiallyShown = isAodFullyOrPartiallyShown,
+                )
             }
-            .distinctUntilChanged()
+            .stateIn(
+                scope = applicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue =
+                    invisibleDueToOcclusion(
+                        isOccludingActivityShown = isOccludingActivityShown.value,
+                        sceneTransitionState = sceneInteractor.transitionState.value,
+                        isAodFullyOrPartiallyShown = isAodFullyOrPartiallyShown.value,
+                    ),
+            )
+
+    private fun invisibleDueToOcclusion(
+        isOccludingActivityShown: Boolean,
+        sceneTransitionState: ObservableTransitionState,
+        isAodFullyOrPartiallyShown: Boolean,
+    ): Boolean {
+        return isOccludingActivityShown &&
+            // Cannot be occluded in AOD.
+            !isAodFullyOrPartiallyShown &&
+            // Only some scenes can be occluded.
+            sceneTransitionState.canBeOccluded
+    }
 
     private val ObservableTransitionState.canBeOccluded: Boolean
         get() =
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
index 75bf131..2ccd3b9 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/interactor/SceneInteractor.kt
@@ -162,7 +162,9 @@
         loggingReason: String,
         transitionKey: TransitionKey? = null,
     ) {
-        check(toScene != Scenes.Gone || deviceUnlockedInteractor.isDeviceUnlocked.value) {
+        check(
+            toScene != Scenes.Gone || deviceUnlockedInteractor.deviceUnlockStatus.value.isUnlocked
+        ) {
             "Cannot change to the Gone scene while the device is locked. Logging reason for scene" +
                 " change was: $loggingReason"
         }
diff --git a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
index 0e4049b..32d72e0 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/domain/startable/SceneContainerStartable.kt
@@ -32,7 +32,9 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.DisplayId
+import com.android.systemui.deviceentry.domain.interactor.DeviceEntryFaceAuthInteractor
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.model.SceneContainerPlugin
 import com.android.systemui.model.SysUiState
@@ -50,6 +52,7 @@
 import com.android.systemui.statusbar.phone.CentralSurfaces
 import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
 import com.android.systemui.util.asIndenting
+import com.android.systemui.util.kotlin.sample
 import com.android.systemui.util.printSection
 import com.android.systemui.util.println
 import dagger.Lazy
@@ -63,6 +66,8 @@
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.distinctUntilChangedBy
 import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.flow.filter
+import kotlinx.coroutines.flow.filterIsInstance
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
@@ -80,6 +85,7 @@
     @Application private val applicationScope: CoroutineScope,
     private val sceneInteractor: SceneInteractor,
     private val deviceEntryInteractor: DeviceEntryInteractor,
+    private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
     private val bouncerInteractor: BouncerInteractor,
     private val keyguardInteractor: KeyguardInteractor,
     private val flags: SceneContainerFlags,
@@ -96,6 +102,7 @@
     private val centralSurfaces: CentralSurfaces,
     private val headsUpInteractor: HeadsUpNotificationInteractor,
     private val occlusionInteractor: SceneContainerOcclusionInteractor,
+    private val faceUnlockInteractor: DeviceEntryFaceAuthInteractor,
 ) : CoreStartable {
 
     override fun start() {
@@ -108,6 +115,7 @@
             respondToFalsingDetections()
             hydrateWindowFocus()
             hydrateInteractionState()
+            handleBouncerOverscroll()
         } else {
             sceneLogger.logFrameworkEnabled(
                 isEnabled = false,
@@ -189,51 +197,53 @@
             }
         }
         applicationScope.launch {
-            simBouncerInteractor.get().isAnySimSecure.collect { isAnySimLocked ->
-                val canSwipeToEnter = deviceEntryInteractor.canSwipeToEnter.value
-                val isUnlocked = deviceEntryInteractor.isUnlocked.value
-
-                when {
-                    isAnySimLocked -> {
-                        switchToScene(
-                            targetSceneKey = Scenes.Bouncer,
-                            loggingReason = "Need to authenticate locked SIM card."
-                        )
-                    }
-                    isUnlocked && canSwipeToEnter == false -> {
-                        switchToScene(
-                            targetSceneKey = Scenes.Gone,
-                            loggingReason =
-                                "All SIM cards unlocked and device already" +
-                                    " unlocked and lockscreen doesn't require a swipe to dismiss."
-                        )
-                    }
-                    else -> {
-                        switchToScene(
-                            targetSceneKey = Scenes.Lockscreen,
-                            loggingReason =
-                                "All SIM cards unlocked and device still locked" +
-                                    " or lockscreen still requires a swipe to dismiss."
-                        )
+            simBouncerInteractor
+                .get()
+                .isAnySimSecure
+                .sample(deviceUnlockedInteractor.deviceUnlockStatus, ::Pair)
+                .collect { (isAnySimLocked, unlockStatus) ->
+                    when {
+                        isAnySimLocked -> {
+                            switchToScene(
+                                targetSceneKey = Scenes.Bouncer,
+                                loggingReason = "Need to authenticate locked SIM card."
+                            )
+                        }
+                        unlockStatus.isUnlocked &&
+                            deviceEntryInteractor.canSwipeToEnter.value == false -> {
+                            switchToScene(
+                                targetSceneKey = Scenes.Gone,
+                                loggingReason =
+                                    "All SIM cards unlocked and device already unlocked and " +
+                                        "lockscreen doesn't require a swipe to dismiss."
+                            )
+                        }
+                        else -> {
+                            switchToScene(
+                                targetSceneKey = Scenes.Lockscreen,
+                                loggingReason =
+                                    "All SIM cards unlocked and device still locked" +
+                                        " or lockscreen still requires a swipe to dismiss."
+                            )
+                        }
                     }
                 }
-            }
         }
         applicationScope.launch {
-            deviceEntryInteractor.isUnlocked
-                .mapNotNull { isUnlocked ->
+            deviceUnlockedInteractor.deviceUnlockStatus
+                .mapNotNull { deviceUnlockStatus ->
                     val renderedScenes =
                         when (val transitionState = sceneInteractor.transitionState.value) {
                             is ObservableTransitionState.Idle -> setOf(transitionState.scene)
                             is ObservableTransitionState.Transition ->
                                 setOf(
-                                    transitionState.progress,
+                                    transitionState.fromScene,
                                     transitionState.toScene,
                                 )
                         }
                     val isOnLockscreen = renderedScenes.contains(Scenes.Lockscreen)
                     val isOnBouncer = renderedScenes.contains(Scenes.Bouncer)
-                    if (!isUnlocked) {
+                    if (!deviceUnlockStatus.isUnlocked) {
                         return@mapNotNull if (isOnLockscreen || isOnBouncer) {
                             // Already on lockscreen or bouncer, no need to change scenes.
                             null
@@ -245,8 +255,6 @@
                         }
                     }
 
-                    val isBypassEnabled = deviceEntryInteractor.isBypassEnabled.value
-                    val canSwipeToEnter = deviceEntryInteractor.canSwipeToEnter.value
                     when {
                         isOnBouncer ->
                             // When the device becomes unlocked in Bouncer, go to Gone.
@@ -261,14 +269,12 @@
                             //    when the unlock state changes indicates this is an active
                             //    authentication attempt.
                             when {
-                                isBypassEnabled ->
+                                deviceUnlockStatus.deviceUnlockSource?.dismissesLockscreen ==
+                                    true ->
                                     Scenes.Gone to
-                                        "device has been unlocked on lockscreen with bypass" +
-                                            " enabled"
-                                canSwipeToEnter == false ->
-                                    Scenes.Gone to
-                                        "device has been unlocked on lockscreen using an active" +
-                                            " authentication mechanism"
+                                        "device has been unlocked on lockscreen with bypass " +
+                                            "enabled or using an active authentication " +
+                                            "mechanism: ${deviceUnlockStatus.deviceUnlockSource}"
                                 else -> null
                             }
                         // Not on lockscreen or bouncer, so remain in the current scene.
@@ -292,14 +298,19 @@
                     )
                 } else {
                     val canSwipeToEnter = deviceEntryInteractor.canSwipeToEnter.value
-                    val isUnlocked = deviceEntryInteractor.isUnlocked.value
+                    val isUnlocked = deviceUnlockedInteractor.deviceUnlockStatus.value.isUnlocked
                     if (isUnlocked && canSwipeToEnter == false) {
-                        switchToScene(
-                            targetSceneKey = Scenes.Gone,
-                            loggingReason =
-                                "device is waking up while unlocked without the ability" +
-                                    " to swipe up on lockscreen to enter.",
-                        )
+                        val isTransitioningToLockscreen =
+                            sceneInteractor.transitioningTo.value == Scenes.Lockscreen
+                        if (!isTransitioningToLockscreen) {
+                            switchToScene(
+                                targetSceneKey = Scenes.Gone,
+                                loggingReason =
+                                    "device is waking up while unlocked without the ability to" +
+                                        " swipe up on lockscreen to enter and not on or" +
+                                        " transitioning to, the lockscreen scene.",
+                            )
+                        }
                     } else if (
                         authenticationInteractor.get().getAuthenticationMethod() ==
                             AuthenticationMethodModel.Sim
@@ -317,15 +328,23 @@
     /** Keeps [SysUiState] up-to-date */
     private fun hydrateSystemUiState() {
         applicationScope.launch {
-            sceneInteractor.transitionState
-                .mapNotNull { it as? ObservableTransitionState.Idle }
-                .map { it.scene }
-                .distinctUntilChanged()
-                .collect { sceneKey ->
+            combine(
+                    sceneInteractor.transitionState
+                        .mapNotNull { it as? ObservableTransitionState.Idle }
+                        .map { it.scene }
+                        .distinctUntilChanged(),
+                    occlusionInteractor.invisibleDueToOcclusion,
+                ) { sceneKey, invisibleDueToOcclusion ->
+                    SceneContainerPlugin.SceneContainerPluginState(
+                        scene = sceneKey,
+                        invisibleDueToOcclusion = invisibleDueToOcclusion,
+                    )
+                }
+                .collect { sceneContainerPluginState ->
                     sysUiState.updateFlags(
                         displayId,
                         *SceneContainerPlugin.EvaluatorByFlag.map { (flag, evaluator) ->
-                                flag to evaluator.invoke(sceneKey)
+                                flag to evaluator.invoke(sceneContainerPluginState)
                             }
                             .toTypedArray(),
                     )
@@ -411,8 +430,8 @@
     /** Keeps the interaction state of [CentralSurfaces] up-to-date. */
     private fun hydrateInteractionState() {
         applicationScope.launch {
-            deviceEntryInteractor.isUnlocked
-                .map { !it }
+            deviceUnlockedInteractor.deviceUnlockStatus
+                .map { !it.isUnlocked }
                 .flatMapLatest { isDeviceLocked ->
                     if (isDeviceLocked) {
                         sceneInteractor.transitionState
@@ -448,6 +467,33 @@
         }
     }
 
+    private fun handleBouncerOverscroll() {
+        applicationScope.launch {
+            sceneInteractor.transitionState
+                // Only consider transitions.
+                .filterIsInstance<ObservableTransitionState.Transition>()
+                // Only consider user-initiated (e.g. drags) that go from bouncer to lockscreen.
+                .filter { transition ->
+                    transition.fromScene == Scenes.Bouncer &&
+                        transition.toScene == Scenes.Lockscreen &&
+                        transition.isInitiatedByUserInput
+                }
+                .flatMapLatest { it.progress }
+                // Figure out the direction of scrolling.
+                .map { progress ->
+                    when {
+                        progress > 0 -> 1
+                        progress < 0 -> -1
+                        else -> 0
+                    }
+                }
+                .distinctUntilChanged()
+                // Only consider negative scrolling, AKA overscroll.
+                .filter { it == -1 }
+                .collect { faceUnlockInteractor.onSwipeUpOnBouncer() }
+        }
+    }
+
     private fun switchToScene(targetSceneKey: SceneKey, loggingReason: String) {
         sceneInteractor.changeScene(
             toScene = targetSceneKey,
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
index 54ec398..c929196 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/flag/SceneContainerFlags.kt
@@ -22,13 +22,14 @@
 import com.android.systemui.Flags.sceneContainer
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.flags.FlagToken
-import com.android.systemui.flags.Flags.SCENE_CONTAINER_ENABLED
 import com.android.systemui.flags.RefactorFlagUtils
 import com.android.systemui.keyguard.KeyguardBottomAreaRefactor
 import com.android.systemui.keyguard.KeyguardWmStateRefactor
 import com.android.systemui.keyguard.MigrateClocksToBlueprint
 import com.android.systemui.keyguard.shared.ComposeLockscreen
 import com.android.systemui.media.controls.util.MediaInSceneContainerFlag
+import com.android.systemui.statusbar.notification.shared.NotificationsHeadsUpRefactor
+import com.android.systemui.statusbar.phone.PredictiveBackSysUiFlag
 import dagger.Module
 import dagger.Provides
 
@@ -40,52 +41,41 @@
     @JvmStatic
     inline val isEnabled
         get() =
-            SCENE_CONTAINER_ENABLED && // mainStaticFlag
             sceneContainer() && // mainAconfigFlag
+            ComposeLockscreen.isEnabled &&
                 KeyguardBottomAreaRefactor.isEnabled &&
-                MigrateClocksToBlueprint.isEnabled &&
-                ComposeLockscreen.isEnabled &&
+                KeyguardWmStateRefactor.isEnabled &&
                 MediaInSceneContainerFlag.isEnabled &&
-                KeyguardWmStateRefactor.isEnabled
+                MigrateClocksToBlueprint.isEnabled &&
+                NotificationsHeadsUpRefactor.isEnabled &&
+                PredictiveBackSysUiFlag.isEnabled
     // NOTE: Changes should also be made in getSecondaryFlags and @EnableSceneContainer
 
-    /**
-     * The main static flag, SCENE_CONTAINER_ENABLED. This is an explicit static flag check that
-     * helps with downstream optimizations (like unused code stripping) in builds where aconfig
-     * flags are still writable. Do not remove!
-     */
-    inline fun getMainStaticFlag() =
-        FlagToken("Flags.SCENE_CONTAINER_ENABLED", SCENE_CONTAINER_ENABLED)
-
     /** The main aconfig flag. */
     inline fun getMainAconfigFlag() = FlagToken(FLAG_SCENE_CONTAINER, sceneContainer())
 
     /** The set of secondary flags which must be enabled for scene container to work properly */
     inline fun getSecondaryFlags(): Sequence<FlagToken> =
         sequenceOf(
-            KeyguardBottomAreaRefactor.token,
-            MigrateClocksToBlueprint.token,
-            KeyguardWmStateRefactor.token,
             ComposeLockscreen.token,
+            KeyguardBottomAreaRefactor.token,
+            KeyguardWmStateRefactor.token,
             MediaInSceneContainerFlag.token,
+            MigrateClocksToBlueprint.token,
+            NotificationsHeadsUpRefactor.token,
+            PredictiveBackSysUiFlag.token,
             // NOTE: Changes should also be made in isEnabled and @EnableSceneContainer
         )
 
     /** The full set of requirements for SceneContainer */
     inline fun getAllRequirements(): Sequence<FlagToken> {
-        return sequenceOf(getMainStaticFlag(), getMainAconfigFlag()) + getSecondaryFlags()
+        return sequenceOf(getMainAconfigFlag()) + getSecondaryFlags()
     }
 
     /** Return all dependencies of this flag in pairs where [Pair.first] depends on [Pair.second] */
     inline fun getFlagDependencies(): Sequence<Pair<FlagToken, FlagToken>> {
-        val mainStaticFlag = getMainStaticFlag()
         val mainAconfigFlag = getMainAconfigFlag()
-        return sequence {
-            // The static and aconfig flags should be equal; make them co-dependent
-            yield(mainAconfigFlag to mainStaticFlag)
-            yield(mainStaticFlag to mainAconfigFlag)
-            // all other flags depend on the static flag for brevity
-        } + getSecondaryFlags().map { mainStaticFlag to it }
+        return getSecondaryFlags().map { mainAconfigFlag to it }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
index 8fe84c9..3dc2070 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingController.java
@@ -164,7 +164,7 @@
         if (mFlags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING_ENTERPRISE_POLICIES)
                 && mDevicePolicyResolver.get()
                         .isScreenCaptureCompletelyDisabled(getHostUserHandle())) {
-            return mScreenCaptureDisabledDialogDelegate.createDialog();
+            return mScreenCaptureDisabledDialogDelegate.createSysUIDialog();
         }
 
         mMediaProjectionMetricsLogger.notifyProjectionInitiated(
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegate.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegate.kt
index ba775cd3..1c76b00 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegate.kt
@@ -18,6 +18,7 @@
 import android.annotation.SuppressLint
 import android.app.Activity
 import android.app.PendingIntent
+import android.content.Context
 import android.content.Intent
 import android.os.Bundle
 import android.os.Handler
@@ -35,12 +36,15 @@
 import android.widget.Spinner
 import android.widget.Switch
 import androidx.annotation.LayoutRes
+import androidx.annotation.StyleRes
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.mediaprojection.MediaProjectionCaptureTarget
 import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger
 import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelectorActivity
 import com.android.systemui.mediaprojection.permission.BaseMediaProjectionPermissionDialogDelegate
 import com.android.systemui.mediaprojection.permission.ENTIRE_SCREEN
 import com.android.systemui.mediaprojection.permission.SINGLE_APP
+import com.android.systemui.mediaprojection.permission.ScreenShareMode
 import com.android.systemui.mediaprojection.permission.ScreenShareOption
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.res.R
@@ -51,15 +55,18 @@
 import dagger.assisted.AssistedInject
 
 /** Dialog to select screen recording options */
-class ScreenRecordPermissionDialogDelegate @AssistedInject constructor(
-    @Assisted private val hostUserHandle: UserHandle,
-    @Assisted private val hostUid: Int,
-    @Assisted private val controller: RecordingController,
+class ScreenRecordPermissionDialogDelegate(
+    private val hostUserHandle: UserHandle,
+    private val hostUid: Int,
+    private val controller: RecordingController,
     private val activityStarter: ActivityStarter,
     private val userContextProvider: UserContextProvider,
-    @Assisted private val onStartRecordingClicked: Runnable?,
+    private val onStartRecordingClicked: Runnable?,
     mediaProjectionMetricsLogger: MediaProjectionMetricsLogger,
     private val systemUIDialogFactory: SystemUIDialog.Factory,
+    @ScreenShareMode defaultSelectedMode: Int,
+    @StyleRes private val theme: Int,
+    private val context: Context,
 ) :
     BaseMediaProjectionPermissionDialogDelegate<SystemUIDialog>(
         createOptionList(),
@@ -67,9 +74,34 @@
         hostUid = hostUid,
         mediaProjectionMetricsLogger,
         R.drawable.ic_screenrecord,
-        R.color.screenrecord_icon_color
-    ), SystemUIDialog.Delegate {
-
+        R.color.screenrecord_icon_color,
+        defaultSelectedMode,
+    ),
+    SystemUIDialog.Delegate {
+    @AssistedInject
+    constructor(
+        @Assisted hostUserHandle: UserHandle,
+        @Assisted hostUid: Int,
+        @Assisted controller: RecordingController,
+        activityStarter: ActivityStarter,
+        userContextProvider: UserContextProvider,
+        @Assisted onStartRecordingClicked: Runnable?,
+        mediaProjectionMetricsLogger: MediaProjectionMetricsLogger,
+        systemUIDialogFactory: SystemUIDialog.Factory,
+        @Application context: Context,
+    ) : this(
+        hostUserHandle,
+        hostUid,
+        controller,
+        activityStarter,
+        userContextProvider,
+        onStartRecordingClicked,
+        mediaProjectionMetricsLogger,
+        systemUIDialogFactory,
+        defaultSelectedMode = SINGLE_APP,
+        theme = SystemUIDialog.DEFAULT_THEME,
+        context,
+    )
 
     @AssistedFactory
     interface Factory {
@@ -77,7 +109,7 @@
             recordingController: RecordingController,
             hostUserHandle: UserHandle,
             hostUid: Int,
-            onStartRecordingClicked: Runnable?
+            onStartRecordingClicked: Runnable?,
         ): ScreenRecordPermissionDialogDelegate
     }
 
@@ -89,7 +121,7 @@
     private lateinit var options: Spinner
 
     override fun createDialog(): SystemUIDialog {
-        return systemUIDialogFactory.create(this)
+        return systemUIDialogFactory.create(this, context, theme)
     }
 
     override fun onCreate(dialog: SystemUIDialog, savedInstanceState: Bundle?) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotViewProxy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotViewProxy.kt
index a1481f6..4cf18fb 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotViewProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LegacyScreenshotViewProxy.kt
@@ -34,9 +34,9 @@
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.flags.FeatureFlags
 import com.android.systemui.res.R
-import com.android.systemui.screenshot.scroll.ScrollCaptureController
 import com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS
 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER
+import com.android.systemui.screenshot.scroll.ScrollCaptureController
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
@@ -113,7 +113,7 @@
     override fun setChipIntents(imageData: ScreenshotController.SavedImageData) =
         view.setChipIntents(imageData)
 
-    override fun requestDismissal(event: ScreenshotEvent) {
+    override fun requestDismissal(event: ScreenshotEvent?) {
         if (DEBUG_DISMISS) {
             Log.d(TAG, "screenshot dismissal requested")
         }
@@ -124,7 +124,7 @@
             }
             return
         }
-        logger.log(event, 0, packageName)
+        event?.let { logger.log(event, 0, packageName) }
         view.animateDismissal()
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
index bbf7ed5..4914409 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SaveImageInBackgroundTask.java
@@ -165,6 +165,7 @@
                     mQuickShareData.quickShareAction, mScreenshotId, uri, mImageTime, image,
                     mParams.owner);
             mImageData.subject = getSubjectString(mImageTime);
+            mImageData.imageTime = mImageTime;
 
             mParams.mActionsReadyListener.onActionsReady(mImageData);
             if (DEBUG_CALLBACK) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
index 97acccd..60c4430 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
@@ -16,78 +16,242 @@
 
 package com.android.systemui.screenshot
 
+import android.app.ActivityOptions
+import android.app.BroadcastOptions
+import android.app.ExitTransitionCoordinator
+import android.app.PendingIntent
+import android.app.assist.AssistContent
 import android.content.Context
 import android.content.Intent
-import android.graphics.drawable.Drawable
-import android.net.Uri
+import android.os.Process
 import android.os.UserHandle
+import android.provider.DeviceConfig
+import android.util.Log
+import android.util.Pair
 import androidx.appcompat.content.res.AppCompatResources
+import com.android.app.tracing.coroutines.launch
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.log.DebugLogger.debugLog
 import com.android.systemui.res.R
-import javax.inject.Inject
+import com.android.systemui.screenshot.ActionIntentCreator.createEdit
+import com.android.systemui.screenshot.ActionIntentCreator.createShareWithSubject
+import com.android.systemui.screenshot.ScreenshotController.SavedImageData
+import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_EDIT_TAPPED
+import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED
+import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_SHARE_TAPPED
+import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_SMART_ACTION_TAPPED
+import com.android.systemui.screenshot.ui.viewmodel.ActionButtonViewModel
+import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import java.text.DateFormat
+import java.util.Date
+import kotlinx.coroutines.CoroutineScope
 
 /**
  * Provides actions for screenshots. This class can be overridden by a vendor-specific SysUI
  * implementation.
  */
 interface ScreenshotActionsProvider {
-    data class ScreenshotAction(
-        val icon: Drawable? = null,
-        val text: String? = null,
-        val description: String,
-        val overrideTransition: Boolean = false,
-        val retrieveIntent: (Uri) -> Intent
-    )
+    fun setCompletedScreenshot(result: SavedImageData)
+    fun isPendingSharedTransition(): Boolean
 
-    interface ScreenshotActionsCallback {
-        fun setPreviewAction(overrideTransition: Boolean = false, retrieveIntent: (Uri) -> Intent)
-        fun addAction(action: ScreenshotAction) = addActions(listOf(action))
-        fun addActions(actions: List<ScreenshotAction>)
-    }
+    fun onAssistContentAvailable(assistContent: AssistContent) {}
 
     interface Factory {
         fun create(
-            context: Context,
-            user: UserHandle?,
-            callback: ScreenshotActionsCallback
+            request: ScreenshotData,
+            requestId: String,
+            windowTransition: () -> Pair<ActivityOptions, ExitTransitionCoordinator>,
+            requestDismissal: () -> Unit,
         ): ScreenshotActionsProvider
     }
 }
 
-class DefaultScreenshotActionsProvider(
+class DefaultScreenshotActionsProvider
+@AssistedInject
+constructor(
     private val context: Context,
-    private val user: UserHandle?,
-    private val callback: ScreenshotActionsProvider.ScreenshotActionsCallback
+    private val viewModel: ScreenshotViewModel,
+    private val actionExecutor: ActionIntentExecutor,
+    private val smartActionsProvider: SmartActionsProvider,
+    private val uiEventLogger: UiEventLogger,
+    @Application private val applicationScope: CoroutineScope,
+    @Assisted val request: ScreenshotData,
+    @Assisted val requestId: String,
+    @Assisted val windowTransition: () -> Pair<ActivityOptions, ExitTransitionCoordinator>,
+    @Assisted val requestDismissal: () -> Unit,
 ) : ScreenshotActionsProvider {
+    private var pendingAction: ((SavedImageData) -> Unit)? = null
+    private var result: SavedImageData? = null
+    private var isPendingSharedTransition = false
+
     init {
-        callback.setPreviewAction(true) { ActionIntentCreator.createEdit(it, context) }
-        val editAction =
-            ScreenshotActionsProvider.ScreenshotAction(
+        viewModel.setPreviewAction {
+            debugLog(LogConfig.DEBUG_ACTIONS) { "Preview tapped" }
+            uiEventLogger.log(SCREENSHOT_PREVIEW_TAPPED, 0, request.packageNameString)
+            onDeferrableActionTapped { result ->
+                startSharedTransition(createEdit(result.uri, context), true)
+            }
+        }
+        viewModel.addAction(
+            ActionButtonViewModel(
                 AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_edit),
                 context.resources.getString(R.string.screenshot_edit_label),
                 context.resources.getString(R.string.screenshot_edit_description),
-                true
-            ) { uri ->
-                ActionIntentCreator.createEdit(uri, context)
+            ) {
+                debugLog(LogConfig.DEBUG_ACTIONS) { "Edit tapped" }
+                uiEventLogger.log(SCREENSHOT_EDIT_TAPPED, 0, request.packageNameString)
+                onDeferrableActionTapped { result ->
+                    startSharedTransition(createEdit(result.uri, context), true)
+                }
             }
-        val shareAction =
-            ScreenshotActionsProvider.ScreenshotAction(
+        )
+        viewModel.addAction(
+            ActionButtonViewModel(
                 AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_share),
                 context.resources.getString(R.string.screenshot_share_label),
                 context.resources.getString(R.string.screenshot_share_description),
-                false
-            ) { uri ->
-                ActionIntentCreator.createShare(uri)
+            ) {
+                debugLog(LogConfig.DEBUG_ACTIONS) { "Share tapped" }
+                uiEventLogger.log(SCREENSHOT_SHARE_TAPPED, 0, request.packageNameString)
+                onDeferrableActionTapped { result ->
+                    startSharedTransition(createShareWithSubject(result.uri, result.subject), false)
+                }
             }
-        callback.addActions(listOf(editAction, shareAction))
+        )
+        if (smartActionsEnabled(request.userHandle ?: Process.myUserHandle())) {
+            smartActionsProvider.requestQuickShare(request, requestId) { quickShare ->
+                if (!quickShare.actionIntent.isImmutable) {
+                    viewModel.addAction(
+                        ActionButtonViewModel(
+                            quickShare.getIcon().loadDrawable(context),
+                            quickShare.title,
+                            quickShare.title,
+                        ) {
+                            debugLog(LogConfig.DEBUG_ACTIONS) { "Quickshare tapped" }
+                            onDeferrableActionTapped { result ->
+                                uiEventLogger.log(
+                                    SCREENSHOT_SMART_ACTION_TAPPED,
+                                    0,
+                                    request.packageNameString
+                                )
+                                sendPendingIntent(
+                                    smartActionsProvider
+                                        .wrapIntent(
+                                            quickShare,
+                                            result.uri,
+                                            result.subject,
+                                            requestId
+                                        )
+                                        .actionIntent
+                                )
+                            }
+                        }
+                    )
+                } else {
+                    Log.w(TAG, "Received immutable quick share pending intent; ignoring")
+                }
+            }
+        }
     }
 
-    class Factory @Inject constructor() : ScreenshotActionsProvider.Factory {
-        override fun create(
-            context: Context,
-            user: UserHandle?,
-            callback: ScreenshotActionsProvider.ScreenshotActionsCallback
-        ): ScreenshotActionsProvider {
-            return DefaultScreenshotActionsProvider(context, user, callback)
+    override fun setCompletedScreenshot(result: SavedImageData) {
+        if (this.result != null) {
+            Log.e(TAG, "Got a second completed screenshot for existing request!")
+            return
         }
+        if (result.uri == null || result.owner == null || result.imageTime == null) {
+            Log.e(TAG, "Invalid result provided!")
+            return
+        }
+        if (result.subject == null) {
+            result.subject = getSubjectString(result.imageTime)
+        }
+        this.result = result
+        pendingAction?.invoke(result)
+        if (smartActionsEnabled(result.owner)) {
+            smartActionsProvider.requestSmartActions(request, requestId, result) { smartActions ->
+                viewModel.addActions(
+                    smartActions.map {
+                        ActionButtonViewModel(
+                            it.getIcon().loadDrawable(context),
+                            it.title,
+                            it.title,
+                        ) {
+                            sendPendingIntent(it.actionIntent)
+                        }
+                    }
+                )
+            }
+        }
+    }
+
+    override fun isPendingSharedTransition(): Boolean {
+        return isPendingSharedTransition
+    }
+
+    private fun onDeferrableActionTapped(onResult: (SavedImageData) -> Unit) {
+        result?.let { onResult.invoke(it) } ?: run { pendingAction = onResult }
+    }
+
+    private fun startSharedTransition(intent: Intent, overrideTransition: Boolean) {
+        val user =
+            result?.owner
+                ?: run {
+                    Log.wtf(TAG, "User handle not provided in screenshot result! Result: $result")
+                    return
+                }
+        isPendingSharedTransition = true
+        applicationScope.launch("$TAG#launchIntentAsync") {
+            actionExecutor.launchIntent(intent, windowTransition.invoke(), user, overrideTransition)
+        }
+    }
+
+    private fun sendPendingIntent(pendingIntent: PendingIntent) {
+        try {
+            val options = BroadcastOptions.makeBasic()
+            options.setInteractive(true)
+            options.setPendingIntentBackgroundActivityStartMode(
+                ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+            )
+            pendingIntent.send(options.toBundle())
+            requestDismissal.invoke()
+        } catch (e: PendingIntent.CanceledException) {
+            Log.e(TAG, "Intent cancelled", e)
+        }
+    }
+
+    private fun smartActionsEnabled(user: UserHandle): Boolean {
+        val savingToOtherUser = user != Process.myUserHandle()
+        return !savingToOtherUser &&
+            DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.ENABLE_SCREENSHOT_NOTIFICATION_SMART_ACTIONS,
+                true
+            )
+    }
+
+    private fun getSubjectString(imageTime: Long): String {
+        val subjectDate = DateFormat.getDateTimeInstance().format(Date(imageTime))
+        return String.format(SCREENSHOT_SHARE_SUBJECT_TEMPLATE, subjectDate)
+    }
+
+    @AssistedFactory
+    interface Factory : ScreenshotActionsProvider.Factory {
+        override fun create(
+            request: ScreenshotData,
+            requestId: String,
+            windowTransition: () -> Pair<ActivityOptions, ExitTransitionCoordinator>,
+            requestDismissal: () -> Unit,
+        ): DefaultScreenshotActionsProvider
+    }
+
+    companion object {
+        private const val TAG = "ScreenshotActionsProvider"
+        private const val SCREENSHOT_SHARE_SUBJECT_TEMPLATE = "Screenshot (%s)"
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 047ecb4..1e513b2 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -96,7 +96,10 @@
 import dagger.assisted.AssistedFactory;
 import dagger.assisted.AssistedInject;
 
+import kotlin.Unit;
+
 import java.util.List;
+import java.util.UUID;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
@@ -167,6 +170,7 @@
         public Notification.Action quickShareAction;
         public UserHandle owner;
         public String subject;  // Title for sharing
+        public Long imageTime; // Time at which screenshot was saved
 
         /**
          * Used to reset the return data on error
@@ -176,6 +180,7 @@
             smartActions = null;
             quickShareAction = null;
             subject = null;
+            imageTime = null;
         }
     }
 
@@ -261,11 +266,9 @@
     private SaveImageInBackgroundTask mSaveInBgTask;
     private boolean mScreenshotTakenInPortrait;
     private boolean mBlockAttach;
-
-    private ScreenshotActionsProvider mActionsProvider;
-
     private Animator mScreenshotAnimation;
     private RequestCallback mCurrentRequestCallback;
+    private ScreenshotActionsProvider mActionsProvider;
     private String mPackageName = "";
     private final BroadcastReceiver mCopyBroadcastReceiver;
 
@@ -317,6 +320,7 @@
             @Assisted boolean showUIOnExternalDisplay
     ) {
         mScreenshotSmartActions = screenshotSmartActions;
+        mActionsProviderFactory = actionsProviderFactory;
         mNotificationsController = screenshotNotificationsControllerFactory.create(displayId);
         mScrollCaptureClient = scrollCaptureClient;
         mUiEventLogger = uiEventLogger;
@@ -347,7 +351,6 @@
         mAssistContentRequester = assistContentRequester;
 
         mViewProxy = viewProxyFactory.getProxy(mContext, mDisplayId);
-        mActionsProviderFactory = actionsProviderFactory;
 
         mScreenshotHandler.setOnTimeoutRunnable(() -> {
             if (DEBUG_UI) {
@@ -441,8 +444,26 @@
             return;
         }
 
-        saveScreenshotInWorkerThread(screenshot.getUserHandle(), finisher,
-                this::showUiOnActionsReady, this::showUiOnQuickShareActionReady);
+        if (screenshotShelfUi()) {
+            final UUID requestId = UUID.randomUUID();
+            final String screenshotId = String.format("Screenshot_%s", requestId);
+            mActionsProvider = mActionsProviderFactory.create(screenshot, screenshotId,
+                    this::createWindowTransition, () -> {
+                        mViewProxy.requestDismissal(null);
+                        return Unit.INSTANCE;
+                    });
+            saveScreenshotInBackground(screenshot, requestId, finisher);
+
+            if (screenshot.getTaskId() >= 0) {
+                mAssistContentRequester.requestAssistContent(screenshot.getTaskId(),
+                        assistContent -> {
+                            mActionsProvider.onAssistContentAvailable(assistContent);
+                        });
+            }
+        } else {
+            saveScreenshotInWorkerThread(screenshot.getUserHandle(), finisher,
+                    this::showUiOnActionsReady, this::showUiOnQuickShareActionReady);
+        }
 
         // The window is focusable by default
         setWindowFocusable(true);
@@ -477,7 +498,9 @@
         // ignore system bar insets for the purpose of window layout
         mWindow.getDecorView().setOnApplyWindowInsetsListener(
                 (v, insets) -> WindowInsets.CONSUMED);
-        mScreenshotHandler.cancelTimeout(); // restarted after animation
+        if (!screenshotShelfUi()) {
+            mScreenshotHandler.cancelTimeout(); // restarted after animation
+        }
     }
 
     private boolean shouldShowUi() {
@@ -497,11 +520,6 @@
 
         mViewProxy.reset();
 
-        if (screenshotShelfUi()) {
-            mActionsProvider = mActionsProviderFactory.create(mContext, screenshot.getUserHandle(),
-                    ((ScreenshotActionsProvider.ScreenshotActionsCallback) mViewProxy));
-        }
-
         if (mViewProxy.isAttachedToWindow()) {
             // if we didn't already dismiss for another reason
             if (!mViewProxy.isDismissing()) {
@@ -529,7 +547,11 @@
     }
 
     boolean isPendingSharedTransition() {
-        return mViewProxy.isPendingSharedTransition();
+        if (screenshotShelfUi()) {
+            return mActionsProvider != null && mActionsProvider.isPendingSharedTransition();
+        } else {
+            return mViewProxy.isPendingSharedTransition();
+        }
     }
 
     // Any cleanup needed when the service is being destroyed.
@@ -682,7 +704,8 @@
                         mImageCapture.captureDisplay(mDisplayId, getFullScreenRect());
 
                 if (newScreenshot != null) {
-                    // delay starting scroll capture to make sure scrim is up before the app moves
+                    // delay starting scroll capture to make sure scrim is up before the app
+                    // moves
                     mViewProxy.prepareScrollingTransition(
                             response, mScreenBitmap, newScreenshot, mScreenshotTakenInPortrait,
                             () -> runBatchScrollCapture(response, owner));
@@ -916,6 +939,39 @@
         mScreenshotHandler.cancelTimeout();
     }
 
+    private void saveScreenshotInBackground(
+            ScreenshotData screenshot, UUID requestId, Consumer<Uri> finisher) {
+        ListenableFuture<ImageExporter.Result> future = mImageExporter.export(mBgExecutor,
+                requestId, screenshot.getBitmap(), screenshot.getUserHandle(), mDisplayId);
+        future.addListener(() -> {
+            try {
+                ImageExporter.Result result = future.get();
+                Log.d(TAG, "Saved screenshot: " + result);
+                logScreenshotResultStatus(result.uri, screenshot.getUserHandle());
+                mScreenshotHandler.resetTimeout();
+                if (result.uri != null) {
+                    final SavedImageData savedImageData = new SavedImageData();
+                    savedImageData.uri = result.uri;
+                    savedImageData.owner = screenshot.getUserHandle();
+                    savedImageData.imageTime = result.timestamp;
+                    mActionsProvider.setCompletedScreenshot(savedImageData);
+                    mViewProxy.setChipIntents(savedImageData);
+                }
+                if (DEBUG_CALLBACK) {
+                    Log.d(TAG, "finished background processing, Calling (Consumer<Uri>) "
+                            + "finisher.accept(\"" + result.uri + "\"");
+                }
+                finisher.accept(result.uri);
+            } catch (Exception e) {
+                Log.d(TAG, "Failed to store screenshot", e);
+                if (DEBUG_CALLBACK) {
+                    Log.d(TAG, "Calling (Consumer<Uri>) finisher.accept(null)");
+                }
+                finisher.accept(null);
+            }
+        }, mMainExecutor);
+    }
+
     /**
      * Creates a new worker thread and saves the screenshot to the media store.
      */
@@ -951,13 +1007,12 @@
      */
     private void showUiOnActionsReady(ScreenshotController.SavedImageData imageData) {
         logSuccessOnActionsReady(imageData);
-        if (DEBUG_UI) {
-            Log.d(TAG, "Showing UI actions");
-        }
-
         mScreenshotHandler.resetTimeout();
 
         if (imageData.uri != null) {
+            if (DEBUG_UI) {
+                Log.d(TAG, "Showing UI actions");
+            }
             if (!imageData.owner.equals(Process.myUserHandle())) {
                 Log.d(TAG, "Screenshot saved to user " + imageData.owner + " as "
                         + imageData.uri);
@@ -1005,20 +1060,27 @@
     /**
      * Logs success/failure of the screenshot saving task, and shows an error if it failed.
      */
-    private void logSuccessOnActionsReady(ScreenshotController.SavedImageData imageData) {
-        if (imageData.uri == null) {
+    private void logScreenshotResultStatus(Uri uri, UserHandle owner) {
+        if (uri == null) {
             mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_NOT_SAVED, 0, mPackageName);
             mNotificationsController.notifyScreenshotError(
                     R.string.screenshot_failed_to_save_text);
         } else {
             mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SAVED, 0, mPackageName);
-            if (mUserManager.isManagedProfile(imageData.owner.getIdentifier())) {
+            if (mUserManager.isManagedProfile(owner.getIdentifier())) {
                 mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SAVED_TO_WORK_PROFILE, 0,
                         mPackageName);
             }
         }
     }
 
+    /**
+     * Logs success/failure of the screenshot saving task, and shows an error if it failed.
+     */
+    private void logSuccessOnActionsReady(ScreenshotController.SavedImageData imageData) {
+        logScreenshotResultStatus(imageData.uri, imageData.owner);
+    }
+
     private boolean isUserSetupComplete(UserHandle owner) {
         return Settings.Secure.getInt(mContext.createContextAsUser(owner, 0)
                 .getContentResolver(), SETTINGS_SECURE_USER_SETUP_COMPLETE, 0) == 1;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt
index 88bca95..6b9332b 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotShelfViewProxy.kt
@@ -20,10 +20,8 @@
 import android.animation.AnimatorListenerAdapter
 import android.app.Notification
 import android.content.Context
-import android.content.Intent
 import android.graphics.Bitmap
 import android.graphics.Rect
-import android.net.Uri
 import android.view.KeyEvent
 import android.view.LayoutInflater
 import android.view.ScrollCaptureResponse
@@ -35,7 +33,6 @@
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.log.DebugLogger.debugLog
 import com.android.systemui.res.R
-import com.android.systemui.screenshot.LogConfig.DEBUG_ACTIONS
 import com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS
 import com.android.systemui.screenshot.LogConfig.DEBUG_INPUT
 import com.android.systemui.screenshot.LogConfig.DEBUG_WINDOW
@@ -45,7 +42,6 @@
 import com.android.systemui.screenshot.ui.ScreenshotAnimationController
 import com.android.systemui.screenshot.ui.ScreenshotShelfView
 import com.android.systemui.screenshot.ui.binder.ScreenshotShelfViewBinder
-import com.android.systemui.screenshot.ui.viewmodel.ActionButtonViewModel
 import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
@@ -59,7 +55,7 @@
     private val viewModel: ScreenshotViewModel,
     @Assisted private val context: Context,
     @Assisted private val displayId: Int
-) : ScreenshotViewProxy, ScreenshotActionsProvider.ScreenshotActionsCallback {
+) : ScreenshotViewProxy {
     override val view: ScreenshotShelfView =
         LayoutInflater.from(context).inflate(R.layout.screenshot_shelf, null) as ScreenshotShelfView
     override val screenshotPreview: View
@@ -77,8 +73,6 @@
     override var isPendingSharedTransition = false
 
     private val animationController = ScreenshotAnimationController(view)
-    private var imageData: SavedImageData? = null
-    private var runOnImageDataAcquired: ((SavedImageData) -> Unit)? = null
 
     init {
         ScreenshotShelfViewBinder.bind(view, viewModel, LayoutInflater.from(context))
@@ -91,9 +85,7 @@
     override fun reset() {
         animationController.cancel()
         isPendingSharedTransition = false
-        imageData = null
         viewModel.reset()
-        runOnImageDataAcquired = null
     }
     override fun updateInsets(insets: WindowInsets) {}
     override fun updateOrientation(insets: WindowInsets) {}
@@ -104,12 +96,9 @@
 
     override fun addQuickShareChip(quickShareAction: Notification.Action) {}
 
-    override fun setChipIntents(data: SavedImageData) {
-        imageData = data
-        runOnImageDataAcquired?.invoke(data)
-    }
+    override fun setChipIntents(imageData: SavedImageData) {}
 
-    override fun requestDismissal(event: ScreenshotEvent) {
+    override fun requestDismissal(event: ScreenshotEvent?) {
         debugLog(DEBUG_DISMISS) { "screenshot dismissal requested: $event" }
 
         // If we're already animating out, don't restart the animation
@@ -117,7 +106,7 @@
             debugLog(DEBUG_DISMISS) { "Already dismissing, ignoring duplicate command $event" }
             return
         }
-        logger.log(event, 0, packageName)
+        event?.let { logger.log(it, 0, packageName) }
         val animator = animationController.getExitAnimation()
         animator.addListener(
             object : AnimatorListenerAdapter() {
@@ -143,13 +132,18 @@
         newScreenshot: Bitmap,
         screenshotTakenInPortrait: Boolean,
         onTransitionPrepared: Runnable,
-    ) {}
+    ) {
+        onTransitionPrepared.run()
+    }
 
     override fun startLongScreenshotTransition(
         transitionDestination: Rect,
         onTransitionEnd: Runnable,
         longScreenshot: ScrollCaptureController.LongScreenshot
-    ) {}
+    ) {
+        onTransitionEnd.run()
+        callbacks?.onDismiss()
+    }
 
     override fun restoreNonScrollingUi() {}
 
@@ -219,41 +213,4 @@
     interface Factory : ScreenshotViewProxy.Factory {
         override fun getProxy(context: Context, displayId: Int): ScreenshotShelfViewProxy
     }
-
-    override fun setPreviewAction(overrideTransition: Boolean, retrieveIntent: (Uri) -> Intent) {
-        viewModel.setPreviewAction {
-            imageData?.let {
-                val intent = retrieveIntent(it.uri)
-                debugLog(DEBUG_ACTIONS) { "Preview tapped: $intent" }
-                isPendingSharedTransition = true
-                callbacks?.onAction(intent, it.owner, overrideTransition)
-            }
-        }
-    }
-
-    override fun addActions(actions: List<ScreenshotActionsProvider.ScreenshotAction>) {
-        viewModel.addActions(
-            actions.map { action ->
-                ActionButtonViewModel(action.icon, action.text, action.description) {
-                    val actionRunnable =
-                        getActionRunnable(action.retrieveIntent, action.overrideTransition)
-                    imageData?.let { actionRunnable(it) }
-                        ?: run { runOnImageDataAcquired = actionRunnable }
-                }
-            }
-        )
-    }
-
-    private fun getActionRunnable(
-        retrieveIntent: (Uri) -> Intent,
-        overrideTransition: Boolean
-    ): (SavedImageData) -> Unit {
-        val onClick: (SavedImageData) -> Unit = {
-            val intent = retrieveIntent(it.uri)
-            debugLog(DEBUG_ACTIONS) { "Action tapped: $intent" }
-            isPendingSharedTransition = true
-            callbacks!!.onAction(intent, it.owner, overrideTransition)
-        }
-        return onClick
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotViewProxy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotViewProxy.kt
index 6be32a9..a4069d1 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotViewProxy.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotViewProxy.kt
@@ -46,7 +46,7 @@
     fun createScreenshotDropInAnimation(screenRect: Rect, showFlash: Boolean): Animator
     fun addQuickShareChip(quickShareAction: Notification.Action)
     fun setChipIntents(imageData: ScreenshotController.SavedImageData)
-    fun requestDismissal(event: ScreenshotEvent)
+    fun requestDismissal(event: ScreenshotEvent?)
 
     fun showScrollChip(packageName: String, onClick: Runnable)
     fun hideScrollChip()
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsProvider.kt b/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsProvider.kt
new file mode 100644
index 0000000..2eaff86
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsProvider.kt
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.screenshot
+
+import android.app.Notification
+import android.app.PendingIntent
+import android.content.ClipData
+import android.content.ClipDescription
+import android.content.ComponentName
+import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.net.Uri
+import android.os.Bundle
+import android.os.Process
+import android.os.SystemClock
+import android.os.UserHandle
+import android.provider.DeviceConfig
+import android.util.Log
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
+import com.android.systemui.log.DebugLogger.debugLog
+import com.android.systemui.screenshot.LogConfig.DEBUG_ACTIONS
+import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider.ScreenshotSmartActionType.QUICK_SHARE_ACTION
+import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider.ScreenshotSmartActionType.REGULAR_SMART_ACTIONS
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.TimeUnit
+import java.util.concurrent.TimeoutException
+import javax.inject.Inject
+import kotlin.random.Random
+
+/**
+ * Handle requesting smart/quickshare actions from the provider and executing an action when the
+ * action futures complete.
+ */
+class SmartActionsProvider
+@Inject
+constructor(
+    private val context: Context,
+    private val smartActions: ScreenshotNotificationSmartActionsProvider,
+) {
+    /**
+     * Requests quick share action for a given screenshot.
+     *
+     * @param data the ScreenshotData request
+     * @param id the request id for the screenshot
+     * @param onAction callback to run when quick share action is returned
+     */
+    fun requestQuickShare(
+        data: ScreenshotData,
+        id: String,
+        onAction: (Notification.Action) -> Unit
+    ) {
+        val bitmap = data.bitmap ?: return
+        val user = data.userHandle ?: return
+        val component = data.topComponent ?: ComponentName("", "")
+        requestQuickShareAction(id, bitmap, component, user) { quickShareAction ->
+            onAction(quickShareAction)
+        }
+    }
+
+    /**
+     * Requests smart actions for a given screenshot.
+     *
+     * @param data the ScreenshotData request
+     * @param id the request id for the screenshot
+     * @param result the data for the saved image
+     * @param onActions callback to run when actions are returned
+     */
+    fun requestSmartActions(
+        data: ScreenshotData,
+        id: String,
+        result: ScreenshotController.SavedImageData,
+        onActions: (List<Notification.Action>) -> Unit
+    ) {
+        val bitmap = data.bitmap ?: return
+        val user = data.userHandle ?: return
+        val uri = result.uri ?: return
+        val component = data.topComponent ?: ComponentName("", "")
+        requestSmartActions(id, bitmap, component, user, uri, REGULAR_SMART_ACTIONS) { actions ->
+            onActions(actions)
+        }
+    }
+
+    /**
+     * Wraps the given quick share action in a broadcast intent.
+     *
+     * @param quickShare the quick share action to wrap
+     * @param uri the URI of the saved screenshot
+     * @param subject the subject/title for the screenshot
+     * @param id the request ID of the screenshot
+     * @return the wrapped action
+     */
+    fun wrapIntent(
+        quickShare: Notification.Action,
+        uri: Uri,
+        subject: String,
+        id: String
+    ): Notification.Action {
+        val wrappedIntent: Intent =
+            Intent(context, SmartActionsReceiver::class.java)
+                .putExtra(ScreenshotController.EXTRA_ACTION_INTENT, quickShare.actionIntent)
+                .putExtra(
+                    ScreenshotController.EXTRA_ACTION_INTENT_FILLIN,
+                    createFillInIntent(uri, subject)
+                )
+                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
+        val extras: Bundle = quickShare.extras
+        val actionType =
+            extras.getString(
+                ScreenshotNotificationSmartActionsProvider.ACTION_TYPE,
+                ScreenshotNotificationSmartActionsProvider.DEFAULT_ACTION_TYPE
+            )
+        // We only query for quick share actions when smart actions are enabled, so we can assert
+        // that it's true here.
+        wrappedIntent
+            .putExtra(ScreenshotController.EXTRA_ACTION_TYPE, actionType)
+            .putExtra(ScreenshotController.EXTRA_ID, id)
+            .putExtra(ScreenshotController.EXTRA_SMART_ACTIONS_ENABLED, true)
+        val broadcastIntent =
+            PendingIntent.getBroadcast(
+                context,
+                Random.nextInt(),
+                wrappedIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE
+            )
+        return Notification.Action.Builder(quickShare.getIcon(), quickShare.title, broadcastIntent)
+            .setContextual(true)
+            .addExtras(extras)
+            .build()
+    }
+
+    private fun createFillInIntent(uri: Uri, subject: String): Intent {
+        val fillIn = Intent()
+        fillIn.setType("image/png")
+        fillIn.putExtra(Intent.EXTRA_STREAM, uri)
+        fillIn.putExtra(Intent.EXTRA_SUBJECT, subject)
+        // Include URI in ClipData also, so that grantPermission picks it up.
+        // We don't use setData here because some apps interpret this as "to:".
+        val clipData =
+            ClipData(ClipDescription("content", arrayOf("image/png")), ClipData.Item(uri))
+        fillIn.clipData = clipData
+        fillIn.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+        return fillIn
+    }
+
+    private fun requestQuickShareAction(
+        id: String,
+        image: Bitmap,
+        component: ComponentName,
+        user: UserHandle,
+        timeoutMs: Long = 500,
+        onAction: (Notification.Action) -> Unit
+    ) {
+        requestSmartActions(id, image, component, user, null, QUICK_SHARE_ACTION, timeoutMs) {
+            it.firstOrNull()?.let { action -> onAction(action) }
+        }
+    }
+
+    private fun requestSmartActions(
+        id: String,
+        image: Bitmap,
+        component: ComponentName,
+        user: UserHandle,
+        uri: Uri?,
+        actionType: ScreenshotNotificationSmartActionsProvider.ScreenshotSmartActionType,
+        timeoutMs: Long = 500,
+        onActions: (List<Notification.Action>) -> Unit
+    ) {
+        val enabled = isSmartActionsEnabled(user)
+        debugLog(DEBUG_ACTIONS) {
+            ("getSmartActionsFuture id=$id, uri=$uri, provider=$smartActions, " +
+                "actionType=$actionType, smartActionsEnabled=$enabled, userHandle=$user")
+        }
+        if (!enabled) {
+            debugLog(DEBUG_ACTIONS) { "Screenshot Intelligence not enabled, returning empty list" }
+            onActions(listOf())
+            return
+        }
+        if (image.config != Bitmap.Config.HARDWARE) {
+            debugLog(DEBUG_ACTIONS) {
+                "Bitmap expected: Hardware, Bitmap found: ${image.config}. Returning empty list."
+            }
+            onActions(listOf())
+            return
+        }
+        var smartActionsFuture: CompletableFuture<List<Notification.Action>>
+        val startTimeMs = SystemClock.uptimeMillis()
+        try {
+            smartActionsFuture =
+                smartActions.getActions(id, uri, image, component, actionType, user)
+        } catch (e: Throwable) {
+            val waitTimeMs = SystemClock.uptimeMillis() - startTimeMs
+            debugLog(DEBUG_ACTIONS, error = e) {
+                "Failed to get future for screenshot notification smart actions."
+            }
+            notifyScreenshotOp(
+                id,
+                ScreenshotNotificationSmartActionsProvider.ScreenshotOp.REQUEST_SMART_ACTIONS,
+                ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.ERROR,
+                waitTimeMs
+            )
+            onActions(listOf())
+            return
+        }
+        try {
+            val actions = smartActionsFuture.get(timeoutMs, TimeUnit.MILLISECONDS)
+            val waitTimeMs = SystemClock.uptimeMillis() - startTimeMs
+            debugLog(DEBUG_ACTIONS) {
+                ("Got ${actions.size} smart actions. Wait time: $waitTimeMs ms, " +
+                    "actionType=$actionType")
+            }
+            notifyScreenshotOp(
+                id,
+                ScreenshotNotificationSmartActionsProvider.ScreenshotOp.WAIT_FOR_SMART_ACTIONS,
+                ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.SUCCESS,
+                waitTimeMs
+            )
+            onActions(actions)
+        } catch (e: Throwable) {
+            val waitTimeMs = SystemClock.uptimeMillis() - startTimeMs
+            debugLog(DEBUG_ACTIONS, error = e) {
+                "Error getting smart actions. Wait time: $waitTimeMs ms, actionType=$actionType"
+            }
+            val status =
+                if (e is TimeoutException) {
+                    ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.TIMEOUT
+                } else {
+                    ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus.ERROR
+                }
+            notifyScreenshotOp(
+                id,
+                ScreenshotNotificationSmartActionsProvider.ScreenshotOp.WAIT_FOR_SMART_ACTIONS,
+                status,
+                waitTimeMs
+            )
+            onActions(listOf())
+        }
+    }
+
+    private fun notifyScreenshotOp(
+        screenshotId: String,
+        op: ScreenshotNotificationSmartActionsProvider.ScreenshotOp,
+        status: ScreenshotNotificationSmartActionsProvider.ScreenshotOpStatus,
+        durationMs: Long
+    ) {
+        debugLog(DEBUG_ACTIONS) {
+            "$smartActions notifyOp: $op id=$screenshotId, status=$status, durationMs=$durationMs"
+        }
+        try {
+            smartActions.notifyOp(screenshotId, op, status, durationMs)
+        } catch (e: Throwable) {
+            Log.e(TAG, "Error in notifyScreenshotOp: ", e)
+        }
+    }
+    private fun isSmartActionsEnabled(user: UserHandle): Boolean {
+        // Smart actions don't yet work for cross-user saves.
+        val savingToOtherUser = user !== Process.myUserHandle()
+        val actionsEnabled =
+            DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.ENABLE_SCREENSHOT_NOTIFICATION_SMART_ACTIONS,
+                true
+            )
+        return !savingToOtherUser && actionsEnabled
+    }
+
+    companion object {
+        private const val TAG = "SmartActionsProvider"
+        private const val SCREENSHOT_SHARE_SUBJECT_TEMPLATE = "Screenshot (%s)"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/data/repository/ProfileTypeRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/screenshot/data/repository/ProfileTypeRepositoryImpl.kt
index 42ad21bd..17ddf80 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/data/repository/ProfileTypeRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/data/repository/ProfileTypeRepositoryImpl.kt
@@ -13,11 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@file:SuppressLint("MissingPermission")
+@file:Suppress("MissingPermission")
 
 package com.android.systemui.screenshot.data.repository
 
-import android.annotation.SuppressLint
 import android.annotation.UserIdInt
 import android.os.UserManager
 import com.android.systemui.dagger.qualifiers.Background
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt
index c7fe3f6..a6374ae 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt
@@ -36,6 +36,7 @@
         } else {
             view.setOnClickListener(null)
         }
+        view.tag = viewModel.id
         view.contentDescription = viewModel.description
         view.visibility = View.VISIBLE
         view.alpha = 1f
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt
index d878200..32e9296 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ScreenshotShelfViewBinder.kt
@@ -60,7 +60,7 @@
                     }
                     launch {
                         viewModel.previewAction.collect { onClick ->
-                            previewView.setOnClickListener { onClick?.run() }
+                            previewView.setOnClickListener { onClick?.invoke() }
                         }
                     }
                     launch {
@@ -70,21 +70,36 @@
                                     .requireViewById<View>(R.id.actions_container_background)
                                     .visibility = View.VISIBLE
                             }
-                            val viewPool = actionsContainer.children.toList()
-                            actionsContainer.removeAllViews()
-                            val actionButtons =
-                                List(actions.size) {
-                                    viewPool.getOrElse(it) {
+
+                            // Remove any buttons not in the new list, then do another pass to add
+                            // any new actions and update any that are already there.
+                            // This assumes that actions can never change order and that each action
+                            // ID is unique.
+                            val newIds = actions.map { it.id }
+
+                            for (view in actionsContainer.children.toList()) {
+                                if (view.tag !in newIds) {
+                                    actionsContainer.removeView(view)
+                                }
+                            }
+
+                            for ((index, action) in actions.withIndex()) {
+                                val currentView: View? = actionsContainer.getChildAt(index)
+                                if (action.id == currentView?.tag) {
+                                    // Same ID, update the display
+                                    ActionButtonViewBinder.bind(currentView, action)
+                                } else {
+                                    // Different ID. Removals have already happened so this must
+                                    // mean that the new action must be inserted here.
+                                    val actionButton =
                                         layoutInflater.inflate(
                                             R.layout.overlay_action_chip,
                                             actionsContainer,
                                             false
                                         )
-                                    }
+                                    actionsContainer.addView(actionButton, index)
+                                    ActionButtonViewBinder.bind(actionButton, action)
                                 }
-                            actionButtons.zip(actions).forEach {
-                                actionsContainer.addView(it.first)
-                                ActionButtonViewBinder.bind(it.first, it.second)
                             }
                         }
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonViewModel.kt
index 05bfed1..97b24c1 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonViewModel.kt
@@ -22,5 +22,13 @@
     val icon: Drawable?,
     val name: CharSequence?,
     val description: CharSequence,
-    val onClicked: (() -> Unit)?
-)
+    val onClicked: (() -> Unit)?,
+) {
+    val id: Int = getId()
+
+    companion object {
+        private var nextId = 0
+
+        private fun getId() = nextId.also { nextId += 1 }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt
index dc61d1e..ddfa69b 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt
@@ -24,8 +24,8 @@
 class ScreenshotViewModel(private val accessibilityManager: AccessibilityManager) {
     private val _preview = MutableStateFlow<Bitmap?>(null)
     val preview: StateFlow<Bitmap?> = _preview
-    private val _previewAction = MutableStateFlow<Runnable?>(null)
-    val previewAction: StateFlow<Runnable?> = _previewAction
+    private val _previewAction = MutableStateFlow<(() -> Unit)?>(null)
+    val previewAction: StateFlow<(() -> Unit)?> = _previewAction
     private val _actions = MutableStateFlow(emptyList<ActionButtonViewModel>())
     val actions: StateFlow<List<ActionButtonViewModel>> = _actions
     val showDismissButton: Boolean
@@ -35,8 +35,14 @@
         _preview.value = bitmap
     }
 
-    fun setPreviewAction(runnable: Runnable) {
-        _previewAction.value = runnable
+    fun setPreviewAction(onClick: () -> Unit) {
+        _previewAction.value = onClick
+    }
+
+    fun addAction(action: ActionButtonViewModel) {
+        val actionList = _actions.value.toMutableList()
+        actionList.add(action)
+        _actions.value = actionList
     }
 
     fun addActions(actions: List<ActionButtonViewModel>) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java b/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
index c42fdf8..b24edd9 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
@@ -25,6 +25,7 @@
 import android.graphics.drawable.Drawable;
 
 import com.android.keyguard.LockIconViewController;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
 
 import java.util.HashSet;
@@ -80,12 +81,14 @@
                         mNotificationPanelViewController.getClockPositionResult()
                                 .stackScrollerPadding),
                 Color.YELLOW, "calculatePanelHeightShade()");
-        drawDebugInfo(canvas,
-                (int) mQsController.calculateNotificationsTopPadding(
-                        mNotificationPanelViewController.isExpandingOrCollapsing(),
-                        mNotificationPanelViewController.getKeyguardNotificationStaticPadding(),
-                        mNotificationPanelViewController.getExpandedFraction()),
-                Color.MAGENTA, "calculateNotificationsTopPadding()");
+        if (!SceneContainerFlag.isEnabled()) {
+            drawDebugInfo(canvas,
+                    (int) mQsController.calculateNotificationsTopPadding(
+                            mNotificationPanelViewController.isExpandingOrCollapsing(),
+                            mNotificationPanelViewController.getKeyguardNotificationStaticPadding(),
+                            mNotificationPanelViewController.getExpandedFraction()),
+                    Color.MAGENTA, "calculateNotificationsTopPadding()");
+        }
         drawDebugInfo(canvas, mNotificationPanelViewController.getClockPositionResult().clockY,
                 Color.GRAY, "mClockPositionResult.clockY");
         drawDebugInfo(canvas, (int) mLockIconViewController.getTop(), Color.GRAY,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
index 33cf9ba..f6b1bcc 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
@@ -30,6 +30,7 @@
 import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.communal.ui.compose.CommunalContainer
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.res.R
@@ -52,6 +53,7 @@
     private val communalViewModel: CommunalViewModel,
     private val dialogFactory: SystemUIDialogFactory,
     private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
+    private val keyguardInteractor: KeyguardInteractor,
     private val shadeInteractor: ShadeInteractor,
     private val powerManager: PowerManager,
     @Communal private val dataSourceDelegator: SceneDataSourceDelegator,
@@ -89,6 +91,9 @@
     /** True if we are currently tracking a touch on the hub while it's open. */
     private var isTrackingHubTouch = false
 
+    /** True if we are tracking a top or bottom swipe gesture while the hub is open. */
+    private var isTrackingHubGesture = false
+
     /**
      * True if the hub UI is fully open, meaning it should receive touch input.
      *
@@ -111,6 +116,16 @@
      */
     private var shadeShowing = false
 
+    /**
+     * True if the device is dreaming, in which case we shouldn't do anything for top/bottom swipes
+     * and just let the dream overlay's touch handling deal with them.
+     *
+     * Tracks [KeyguardInteractor.isDreaming].
+     *
+     * TODO(b/328838259): figure out a proper solution for touch handling above the lock screen too
+     */
+    private var isDreaming = false
+
     /** Returns a flow that tracks whether communal hub is available. */
     fun communalAvailable(): Flow<Boolean> = communalInteractor.isCommunalAvailable
 
@@ -166,6 +181,7 @@
         )
         collectFlow(containerView, communalInteractor.isCommunalShowing, { hubShowing = it })
         collectFlow(containerView, shadeInteractor.isAnyFullyExpanded, { shadeShowing = it })
+        collectFlow(containerView, keyguardInteractor.isDreaming, { isDreaming = it })
 
         communalContainerView = containerView
 
@@ -194,61 +210,86 @@
     }
 
     private fun handleTouchEventOnCommunalView(view: View, ev: MotionEvent): Boolean {
+        // If the hub is fully visible, send all touch events to it, other than top and bottom edge
+        // swipes.
+        return if (hubShowing) {
+            handleHubOpenTouch(view, ev)
+        } else {
+            handleHubClosedTouch(view, ev)
+        }
+    }
+
+    private fun handleHubOpenTouch(view: View, ev: MotionEvent): Boolean {
         val isDown = ev.actionMasked == MotionEvent.ACTION_DOWN
         val isUp = ev.actionMasked == MotionEvent.ACTION_UP
         val isCancel = ev.actionMasked == MotionEvent.ACTION_CANCEL
 
-        // TODO(b/315207481): also account for opening animations of shade/bouncer and not just
-        //  fully showing state
         val hubOccluded = anyBouncerShowing || shadeShowing
 
-        // If the hub is fully visible, send all touch events to it, other than top and bottom edge
-        // swipes.
-        if (hubShowing && isDown) {
+        if (isDown && !hubOccluded) {
+            // Only intercept down events if the hub isn't occluded by the bouncer or
+            // notification shade.
             val y = ev.rawY
             val topSwipe: Boolean = y <= topEdgeSwipeRegionWidth
             val bottomSwipe = y >= view.height - bottomEdgeSwipeRegionWidth
 
             if (topSwipe || bottomSwipe) {
-                // Don't intercept touches at the top/bottom edge so that swipes can open the
-                // notification shade and bouncer.
-                return false
-            }
-
-            if (!hubOccluded) {
+                isTrackingHubGesture = true
+            } else {
                 isTrackingHubTouch = true
-                dispatchTouchEvent(view, ev)
-                // Return true regardless of dispatch result as some touches at the start of a
-                // gesture may return false from dispatchTouchEvent.
-                return true
             }
-        } else if (isTrackingHubTouch) {
+        }
+
+        if (isTrackingHubTouch) {
+            // Tracking a touch on the hub UI itself.
             if (isUp || isCancel) {
                 isTrackingHubTouch = false
             }
             dispatchTouchEvent(view, ev)
-            // Return true regardless of dispatch result as some touches at the start of a gesture
+            // Return true regardless of dispatch result as some touches at the start of a
+            // gesture
             // may return false from dispatchTouchEvent.
             return true
+        } else if (isTrackingHubGesture) {
+            // Tracking a top or bottom swipe on the hub UI.
+            if (isUp || isCancel) {
+                isTrackingHubGesture = false
+            }
+
+            // If we're dreaming, intercept touches so the hub UI doesn't receive them, but
+            // don't do anything so that the dream's touch handling takes care of opening
+            // the bouncer or shade.
+            //
+            // If we're not dreaming, we don't intercept touches at the top/bottom edge so that
+            // swipes can open the notification shade and bouncer.
+            return isDreaming
         }
 
+        return false
+    }
+
+    private fun handleHubClosedTouch(view: View, ev: MotionEvent): Boolean {
+        val isDown = ev.actionMasked == MotionEvent.ACTION_DOWN
+        val isUp = ev.actionMasked == MotionEvent.ACTION_UP
+        val isCancel = ev.actionMasked == MotionEvent.ACTION_CANCEL
+
+        val hubOccluded = anyBouncerShowing || shadeShowing
+
         if (rightEdgeSwipeRegionWidth == 0) {
             // If the edge region width has not been read yet for whatever reason, don't bother
             // intercepting touches to open the hub.
             return false
         }
 
-        if (!isTrackingOpenGesture && isDown) {
+        if (isDown && !hubOccluded) {
             val x = ev.rawX
             val inOpeningSwipeRegion: Boolean = x >= view.width - rightEdgeSwipeRegionWidth
-            if (inOpeningSwipeRegion && !hubOccluded) {
+            if (inOpeningSwipeRegion) {
                 isTrackingOpenGesture = true
-                dispatchTouchEvent(view, ev)
-                // Return true regardless of dispatch result as some touches at the start of a
-                // gesture may return false from dispatchTouchEvent.
-                return true
             }
-        } else if (isTrackingOpenGesture) {
+        }
+
+        if (isTrackingOpenGesture) {
             if (isUp || isCancel) {
                 isTrackingOpenGesture = false
             }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 0ddea30..4660831 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -437,7 +437,7 @@
     private final FalsingManager mFalsingManager;
     private final FalsingCollector mFalsingCollector;
     private final ShadeHeadsUpTrackerImpl mShadeHeadsUpTracker = new ShadeHeadsUpTrackerImpl();
-    private final ShadeFoldAnimator mShadeFoldAnimator = new ShadeFoldAnimatorImpl();
+    private final ShadeFoldAnimatorImpl mShadeFoldAnimator = new ShadeFoldAnimatorImpl();
 
     private boolean mShowIconsWhenExpanded;
     private int mIndicationBottomPadding;
@@ -772,6 +772,7 @@
             PowerInteractor powerInteractor,
             KeyguardClockPositionAlgorithm keyguardClockPositionAlgorithm,
             NaturalScrollingSettingObserver naturalScrollingSettingObserver) {
+        SceneContainerFlag.assertInLegacyMode();
         keyguardStateController.addCallback(new KeyguardStateController.Callback() {
             @Override
             public void onKeyguardFadingAwayChanged() {
@@ -982,7 +983,6 @@
                 });
         mAlternateBouncerInteractor = alternateBouncerInteractor;
         dumpManager.registerDumpable(this);
-        SceneContainerFlag.assertInLegacyMode();
     }
 
     private void unlockAnimationFinished() {
@@ -1588,7 +1588,8 @@
      * @param forceClockUpdate Should the clock be updated even when not on keyguard
      */
     private void positionClockAndNotifications(boolean forceClockUpdate) {
-        boolean animate = mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending();
+        boolean animate = !SceneContainerFlag.isEnabled()
+                && mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending();
         int stackScrollerPadding;
         boolean onKeyguard = isKeyguardShowing();
 
@@ -1675,7 +1676,8 @@
                 mClockPositionResult.clockX, mClockPositionResult.clockY);
         }
 
-        boolean animate = mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending();
+        boolean animate = !SceneContainerFlag.isEnabled()
+                && mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending();
         boolean animateClock = (animate || mAnimateNextPositionUpdate) && shouldAnimateClockChange;
 
         if (!MigrateClocksToBlueprint.isEnabled()) {
@@ -2483,6 +2485,7 @@
 
     /** Returns the topPadding of notifications when on keyguard not respecting QS expansion. */
     int getKeyguardNotificationStaticPadding() {
+        SceneContainerFlag.assertInLegacyMode();
         if (!isKeyguardShowing()) {
             return 0;
         }
@@ -2524,12 +2527,14 @@
     }
 
     void requestScrollerTopPaddingUpdate(boolean animate) {
-        float padding = mQsController.calculateNotificationsTopPadding(mIsExpandingOrCollapsing,
-                getKeyguardNotificationStaticPadding(), mExpandedFraction);
-        if (MigrateClocksToBlueprint.isEnabled()) {
-            mSharedNotificationContainerInteractor.setTopPosition(padding);
-        } else {
-            mNotificationStackScrollLayoutController.updateTopPadding(padding, animate);
+        if (!SceneContainerFlag.isEnabled()) {
+            float padding = mQsController.calculateNotificationsTopPadding(mIsExpandingOrCollapsing,
+                    getKeyguardNotificationStaticPadding(), mExpandedFraction);
+            if (MigrateClocksToBlueprint.isEnabled()) {
+                mSharedNotificationContainerInteractor.setTopPosition(padding);
+            } else {
+                mNotificationStackScrollLayoutController.updateTopPadding(padding, animate);
+            }
         }
 
         if (isKeyguardShowing()
@@ -3174,6 +3179,7 @@
             }
             notifyExpandingFinished();
         }
+        // TODO(b/332732878): replace this call when scene container is enabled
         mNotificationStackScrollLayoutController.setAnimationsEnabled(!disabled);
     }
 
@@ -3311,19 +3317,19 @@
     }
 
     @Override
-    public ShadeFoldAnimator getShadeFoldAnimator() {
+    public ShadeFoldAnimatorImpl getShadeFoldAnimator() {
         return mShadeFoldAnimator;
     }
 
-    private final class ShadeFoldAnimatorImpl implements ShadeFoldAnimator {
+    @Deprecated
+    public final class ShadeFoldAnimatorImpl implements ShadeFoldAnimator {
         /** Updates the views to the initial state for the fold to AOD animation. */
         @Override
         public void prepareFoldToAodAnimation() {
-            if (MigrateClocksToBlueprint.isEnabled()) {
-                return;
+            if (!MigrateClocksToBlueprint.isEnabled()) {
+                // Force show AOD UI even if we are not locked
+                showAodUi();
             }
-            // Force show AOD UI even if we are not locked
-            showAodUi();
 
             // Move the content of the AOD all the way to the left
             // so we can animate to the initial position
@@ -3341,14 +3347,29 @@
          * @param cancelAction invoked when the animation is cancelled, before endAction.
          */
         @Override
-        public void startFoldToAodAnimation(Runnable startAction, Runnable endAction,
-                Runnable cancelAction) {
+        public void startFoldToAodAnimation(
+                Runnable startAction, Runnable endAction, Runnable cancelAction) {
             if (MigrateClocksToBlueprint.isEnabled()) {
                 return;
             }
+
+            buildViewAnimator(startAction, endAction, cancelAction)
+                    .setUpdateListener(anim -> mKeyguardStatusViewController
+                            .animateFoldToAod(anim.getAnimatedFraction()))
+                    .start();
+        }
+
+        /**
+         * Builds the default NPVC fold animator
+         *
+         * @deprecated Temporary stop-gap. Do not use outside of keyguard fold transition.
+         */
+        @Deprecated
+        public ViewPropertyAnimator buildViewAnimator(
+                Runnable startAction, Runnable endAction, Runnable cancelAction) {
             final ViewPropertyAnimator viewAnimator = mView.animate();
             viewAnimator.cancel();
-            viewAnimator
+            return viewAnimator
                     .translationX(0)
                     .alpha(1f)
                     .setDuration(ANIMATION_DURATION_FOLD_TO_AOD)
@@ -3371,19 +3392,12 @@
                             viewAnimator.setListener(null);
                             viewAnimator.setUpdateListener(null);
                         }
-                    })
-                    .setUpdateListener(anim ->
-                            mKeyguardStatusViewController.animateFoldToAod(
-                                    anim.getAnimatedFraction()))
-                    .start();
+                    });
         }
 
         /** Cancels fold to AOD transition and resets view state. */
         @Override
         public void cancelFoldToAodAnimation() {
-            if (MigrateClocksToBlueprint.isEnabled()) {
-                return;
-            }
             cancelAnimation();
             resetAlpha();
             resetTranslation();
@@ -3955,7 +3969,9 @@
             mShadeRepository.setLegacyShadeExpansion(mExpandedFraction);
             mQsController.setShadeExpansion(mExpandedHeight, mExpandedFraction);
             mExpansionDragDownAmountPx = h;
-            mAmbientState.setExpansionFraction(mExpandedFraction);
+            if (!SceneContainerFlag.isEnabled()) {
+                mAmbientState.setExpansionFraction(mExpandedFraction);
+            }
             onHeightUpdated(mExpandedHeight);
             updateExpansionAndVisibility();
         });
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index f7fed53..fb32b9f 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -18,7 +18,6 @@
 
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_OPTIMIZE_MEASURE;
 
 import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
@@ -290,12 +289,6 @@
         mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
         mLp.privateFlags |= PRIVATE_FLAG_OPTIMIZE_MEASURE;
 
-        // We use BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE here, however, there is special logic in
-        // window manager which disables the transient show behavior.
-        // TODO: Clean this up once that behavior moves into the Shell.
-        mLp.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
-        mLp.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
-
         if (mSceneContainerFlags.isEnabled()) {
             // This prevents the appearance and disappearance of the software keyboard (also known
             // as the "IME") from scrolling/panning the window to make room for the keyboard.
@@ -307,6 +300,14 @@
 
         mWindowManager.addView(mWindowRootView, mLp);
 
+        // We use BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE here, however, there is special logic in
+        // window manager which disables the transient show behavior.
+        // TODO: Clean this up once that behavior moves into the Shell.
+        if (mWindowRootView.getWindowInsetsController() != null) {
+            mWindowRootView.getWindowInsetsController().setSystemBarsBehavior(
+                    BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
+        }
+
         mLpChanged.copyFrom(mLp);
         onThemeChanged();
 
@@ -416,6 +417,12 @@
         } else {
             mLpChanged.flags &= ~LayoutParams.FLAG_SECURE;
         }
+
+        if (state.bouncerShowing) {
+            mLpChanged.inputFeatures |= LayoutParams.INPUT_FEATURE_SENSITIVE_FOR_TRACING;
+        } else {
+            mLpChanged.inputFeatures &= ~LayoutParams.INPUT_FEATURE_SENSITIVE_FOR_TRACING;
+        }
     }
 
     protected boolean isDebuggable() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
index f9b4e67..903af61 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java
@@ -81,6 +81,8 @@
 
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
+        mInteractionEventHandler.collectKeyEvent(event);
+
         if (mInteractionEventHandler.interceptMediaKey(event)) {
             return true;
         }
@@ -301,6 +303,11 @@
         boolean dispatchKeyEvent(KeyEvent event);
 
         boolean dispatchKeyEventPreIme(KeyEvent event);
+
+        /**
+         * Collects the KeyEvent without intercepting it
+         */
+        void collectKeyEvent(KeyEvent event);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 324dfdf..6ac81d2 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -563,6 +563,11 @@
             public boolean dispatchKeyEvent(KeyEvent event) {
                 return mSysUIKeyEventHandler.dispatchKeyEvent(event);
             }
+
+            @Override
+            public void collectKeyEvent(KeyEvent event) {
+                mFalsingCollector.onKeyEvent(event);
+            }
         });
 
         mView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
index 243ea68..2507507 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerImpl.java
@@ -336,6 +336,7 @@
             SplitShadeStateController splitShadeStateController,
             Lazy<LargeScreenHeaderHelper> largeScreenHeaderHelperLazy
     ) {
+        SceneContainerFlag.assertInLegacyMode();
         mPanelViewControllerLazy = panelViewControllerLazy;
         mPanelView = panelView;
         mLargeScreenHeaderHelperLazy = largeScreenHeaderHelperLazy;
@@ -1370,6 +1371,7 @@
     @Override
     public float calculateNotificationsTopPadding(boolean isShadeExpanding,
             int keyguardNotificationStaticPadding, float expandedFraction) {
+        SceneContainerFlag.assertInLegacyMode();
         float topPadding;
         boolean keyguardShowing = mBarState == KEYGUARD;
         if (mSplitShadeEnabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerSceneImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerSceneImpl.kt
index b8250cc..3462993 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerSceneImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsControllerSceneImpl.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.shade
 
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.plugins.qs.QSContainerController
 import com.android.systemui.qs.ui.adapter.QSSceneAdapter
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import javax.inject.Inject
@@ -28,7 +27,6 @@
 constructor(
     private val shadeInteractor: ShadeInteractor,
     private val qsSceneAdapter: QSSceneAdapter,
-    private val qsContainerController: QSContainerController,
 ) : QuickSettingsController {
 
     override val expanded: Boolean
@@ -43,7 +41,7 @@
     }
 
     override fun closeQsCustomizer() {
-        qsContainerController.setCustomizerShowing(false)
+        qsSceneAdapter.requestCloseCustomizer()
     }
 
     @Deprecated("specific to legacy split shade")
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt
index c5e07e8..ebebbe6 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerSceneImpl.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
+import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.log.dagger.ShadeTouchLog
 import com.android.systemui.scene.domain.interactor.SceneInteractor
@@ -61,6 +62,7 @@
     private val shadeInteractor: ShadeInteractor,
     private val sceneInteractor: SceneInteractor,
     private val deviceEntryInteractor: DeviceEntryInteractor,
+    private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
     private val notificationStackScrollLayout: NotificationStackScrollLayout,
     @ShadeTouchLog private val touchLog: LogBuffer,
     private val vibratorHelper: VibratorHelper,
@@ -148,7 +150,11 @@
     }
 
     private fun getCollapseDestinationScene(): SceneKey {
-        return if (deviceEntryInteractor.isDeviceEntered.value) {
+        // Always check whether device is unlocked before transitioning to gone scene.
+        return if (
+            deviceUnlockedInteractor.deviceUnlockStatus.value.isUnlocked &&
+                deviceEntryInteractor.isDeviceEntered.value
+        ) {
             Scenes.Gone
         } else {
             Scenes.Lockscreen
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurfaceImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurfaceImpl.kt
index adb2928..ec4018c 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurfaceImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurfaceImpl.kt
@@ -46,7 +46,7 @@
     }
 
     override fun setTouchAndAnimationDisabled(disabled: Boolean) {
-        // TODO(b/322197941): determine if still needed
+        // TODO(b/332732878): determine if still needed
     }
 
     override fun setWillPlayDelayedDozeAmountAnimation(willPlay: Boolean) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
index 4e1edd3..4ec0b23 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewController.kt
@@ -54,6 +54,7 @@
     fun setQsScrimEnabled(qsScrimEnabled: Boolean)
 
     /** Sets the top spacing for the ambient indicator. */
+    @Deprecated("Does nothing when scene container is enabled.")
     fun setAmbientIndicationTop(ambientIndicationTop: Int, ambientTextVisible: Boolean)
 
     /** Updates notification panel-specific flags on [SysUiState]. */
@@ -71,6 +72,7 @@
      */
     fun handleExternalTouch(event: MotionEvent): Boolean
 
+    /** Sends an external (e.g. Status Bar) intercept touch event to the Shade touch handler. */
     fun handleExternalInterceptTouch(event: MotionEvent): Boolean
 
     /**
@@ -144,10 +146,11 @@
 }
 
 /** Handles the lifecycle of the shade's animation that happens when folding a foldable. */
-@Deprecated("This interface should not be used in scene container.")
+@Deprecated("This interface should not be used in scene container. Needs flexiglass equivalent.")
 interface ShadeFoldAnimator {
     /** Updates the views to the initial state for the fold to AOD animation. */
-    @Deprecated("Not used when migrateClocksToBlueprint enabled") fun prepareFoldToAodAnimation()
+    @Deprecated("Used by the Keyguard Fold Transition. Needs flexiglass equivalent.")
+    fun prepareFoldToAodAnimation()
 
     /**
      * Starts fold to AOD animation.
@@ -156,14 +159,15 @@
      * @param endAction invoked when the animation finishes, also if it was cancelled.
      * @param cancelAction invoked when the animation is cancelled, before endAction.
      */
-    @Deprecated("Not used when migrateClocksToBlueprint enabled")
+    @Deprecated("Not used when migrateClocksToBlueprint enabled.")
     fun startFoldToAodAnimation(startAction: Runnable, endAction: Runnable, cancelAction: Runnable)
 
     /** Cancels fold to AOD transition and resets view state. */
-    @Deprecated("Not used when migrateClocksToBlueprint enabled") fun cancelFoldToAodAnimation()
+    @Deprecated("Used by the Keyguard Fold Transition. Needs flexiglass equivalent.")
+    fun cancelFoldToAodAnimation()
 
     /** Returns the main view of the shade. */
-    @Deprecated("Not used in Scene Container") val view: ViewGroup?
+    @Deprecated("Not used when migrateClocksToBlueprint enabled.") val view: ViewGroup?
 }
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
index 2cb9f9a..f5dd5e4 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt
@@ -22,6 +22,7 @@
 import android.view.LayoutInflater
 import android.view.ViewStub
 import androidx.constraintlayout.motion.widget.MotionLayout
+import com.android.compose.animation.scene.SceneKey
 import com.android.keyguard.logging.ScrimLogger
 import com.android.systemui.battery.BatteryMeterView
 import com.android.systemui.battery.BatteryMeterViewController
@@ -43,6 +44,7 @@
 import com.android.systemui.statusbar.LightRevealScrim
 import com.android.systemui.statusbar.NotificationInsetsController
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
+import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
 import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
 import com.android.systemui.statusbar.phone.KeyguardBottomAreaView
 import com.android.systemui.statusbar.phone.StatusBarLocation
@@ -51,6 +53,7 @@
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.tuner.TunerService
+import dagger.Binds
 import dagger.Module
 import dagger.Provides
 import javax.inject.Named
@@ -59,6 +62,14 @@
 /** Module for providing views related to the shade. */
 @Module
 abstract class ShadeViewProviderModule {
+
+    @Binds
+    @SysUISingleton
+    // TODO(b/277762009): Only allow this view's binder to inject the view.
+    abstract fun bindsNotificationScrollView(
+        notificationStackScrollLayout: NotificationStackScrollLayout
+    ): NotificationScrollView
+
     companion object {
         const val SHADE_HEADER = "large_screen_shade_header"
 
@@ -76,6 +87,7 @@
             sceneDataSourceDelegator: Provider<SceneDataSourceDelegator>,
         ): WindowRootView {
             return if (sceneContainerFlags.isEnabled()) {
+                checkNoSceneDuplicates(scenesProvider.get())
                 val sceneWindowRootView =
                     layoutInflater.inflate(R.layout.scene_window_root, null) as SceneWindowRootView
                 sceneWindowRootView.init(
@@ -271,5 +283,21 @@
         ): StatusIconContainer {
             return header.requireViewById(R.id.statusIcons)
         }
+
+        private fun checkNoSceneDuplicates(scenes: Set<Scene>) {
+            val keys = mutableSetOf<SceneKey>()
+            val duplicates = mutableSetOf<SceneKey>()
+            scenes
+                .map { it.key }
+                .forEach { sceneKey ->
+                    if (keys.contains(sceneKey)) {
+                        duplicates.add(sceneKey)
+                    } else {
+                        keys.add(sceneKey)
+                    }
+                }
+
+            check(duplicates.isEmpty()) { "Duplicate scenes detected: $duplicates" }
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
index 3349345..c429329 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroupController.java
@@ -345,9 +345,7 @@
             }
         }
 
-        if (mStatusBarPipelineFlags.useNewShadeCarrierGroupMobileIcons()) {
-            Log.d(TAG, "ignoring old pipeline callback because new mobile icon is enabled");
-        } else {
+        if (!mStatusBarPipelineFlags.useNewShadeCarrierGroupMobileIcons()) {
             for (int i = 0; i < SIM_SLOTS; i++) {
                 mCarrierGroups[i].updateState(mInfos[i], singleCarrier);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
index 24b7533..9362cd0 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/ShadeSceneViewModel.kt
@@ -31,6 +31,7 @@
 import com.android.systemui.qs.FooterActionsController
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
 import com.android.systemui.qs.ui.adapter.QSSceneAdapter
+import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
@@ -52,7 +53,7 @@
 @Inject
 constructor(
     @Application private val applicationScope: CoroutineScope,
-    private val deviceEntryInteractor: DeviceEntryInteractor,
+    deviceEntryInteractor: DeviceEntryInteractor,
     val qsSceneAdapter: QSSceneAdapter,
     val shadeHeaderViewModel: ShadeHeaderViewModel,
     val notifications: NotificationsPlaceholderViewModel,
@@ -60,6 +61,7 @@
     shadeInteractor: ShadeInteractor,
     private val footerActionsViewModelFactory: FooterActionsViewModel.Factory,
     private val footerActionsController: FooterActionsController,
+    private val sceneInteractor: SceneInteractor,
 ) {
     val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
         combine(
@@ -103,7 +105,13 @@
     val shadeMode: StateFlow<ShadeMode> = shadeInteractor.shadeMode
 
     /** Notifies that some content in the shade was clicked. */
-    fun onContentClicked() = deviceEntryInteractor.attemptDeviceEntry()
+    fun onContentClicked() {
+        if (!isClickable.value) {
+            return
+        }
+
+        sceneInteractor.changeScene(Scenes.Lockscreen, "Shade empty content clicked")
+    }
 
     fun isMediaVisible(): Boolean {
         // TODO(b/296122467): handle updates to carousel visibility while scene is still visible
diff --git a/packages/SystemUI/src/com/android/systemui/startable/Dependencies.kt b/packages/SystemUI/src/com/android/systemui/startable/Dependencies.kt
index 5e57f1d..8eed097 100644
--- a/packages/SystemUI/src/com/android/systemui/startable/Dependencies.kt
+++ b/packages/SystemUI/src/com/android/systemui/startable/Dependencies.kt
@@ -27,4 +27,4 @@
 @MustBeDocumented
 @Target(AnnotationTarget.CLASS)
 @Retention(AnnotationRetention.RUNTIME)
-annotation class Dependencies(vararg val value: KClass<out CoreStartable> = [])
+annotation class Dependencies(vararg val value: KClass<*> = [])
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
index d6858ca..78e108d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
@@ -40,6 +40,7 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.text.Editable;
+import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.util.Log;
 import android.util.Pair;
@@ -57,6 +58,7 @@
 import android.view.View.AccessibilityDelegate;
 import android.view.ViewGroup;
 import android.view.Window;
+import android.view.WindowInsets;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.Button;
@@ -104,6 +106,7 @@
 
     private WindowManager mWindowManager;
     private EditText mSearchEditText;
+    private ImageButton mEditTextCancel;
     private String mQueryString;
     private int mCurrentCategoryIndex = 0;
     private Map<Integer, Boolean> mKeySearchResultMap = new HashMap<>();
@@ -143,7 +146,7 @@
     @VisibleForTesting
     KeyboardShortcutListSearch(Context context, WindowManager windowManager) {
         this.mContext = new ContextThemeWrapper(
-                context, android.R.style.Theme_DeviceDefault_Settings);
+                context, R.style.KeyboardShortcutHelper);
         this.mPackageManager = AppGlobals.getPackageManager();
         if (windowManager != null) {
             this.mWindowManager = windowManager;
@@ -853,13 +856,14 @@
             List<List<KeyboardShortcutMultiMappingGroup>> keyboardShortcutMultiMappingGroupList) {
         mQueryString = null;
         LayoutInflater inflater = mContext.getSystemService(LayoutInflater.class);
-        mKeyboardShortcutsBottomSheetDialog =
-                new BottomSheetDialog(mContext);
+        mKeyboardShortcutsBottomSheetDialog  = new BottomSheetDialog(mContext);
         final View keyboardShortcutsView = inflater.inflate(
                 R.layout.keyboard_shortcuts_search_view, null);
         LinearLayout shortcutsContainer = keyboardShortcutsView.findViewById(
                 R.id.keyboard_shortcuts_container);
         mNoSearchResults = keyboardShortcutsView.findViewById(R.id.shortcut_search_no_result);
+        Window keyboardShortcutsWindow = mKeyboardShortcutsBottomSheetDialog.getWindow();
+        setWindowProperties(keyboardShortcutsWindow);
         mKeyboardShortcutsBottomSheetDialog.setContentView(keyboardShortcutsView);
         setButtonsDefaultStatus(keyboardShortcutsView);
         populateCurrentAppButton();
@@ -874,25 +878,11 @@
         }
 
         BottomSheetBehavior<FrameLayout> behavior = BottomSheetBehavior.from(bottomSheet);
+        behavior.setDraggable(true);
         behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
         behavior.setSkipCollapsed(true);
-        behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
-                    @Override
-                    public void onStateChanged(@NonNull View bottomSheet, int newState) {
-                        if (newState == BottomSheetBehavior.STATE_DRAGGING) {
-                            behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
-                        }
-                    }
 
-                    @Override
-                    public void onSlide(@NonNull View bottomSheet, float slideOffset) {
-                        // Do nothing.
-                    }
-                });
 
-        mKeyboardShortcutsBottomSheetDialog.setCanceledOnTouchOutside(true);
-        Window keyboardShortcutsWindow = mKeyboardShortcutsBottomSheetDialog.getWindow();
-        keyboardShortcutsWindow.setType(TYPE_SYSTEM_DIALOG);
         synchronized (sLock) {
             // show KeyboardShortcutsBottomSheetDialog only if it has not been dismissed already
             if (sInstance != null) {
@@ -908,6 +898,8 @@
             }
         }
         mSearchEditText = keyboardShortcutsView.findViewById(R.id.keyboard_shortcuts_search);
+        mEditTextCancel = keyboardShortcutsView.findViewById(
+                R.id.keyboard_shortcuts_search_cancel);
         mSearchEditText.addTextChangedListener(
                 new TextWatcher() {
                     @Override
@@ -921,6 +913,8 @@
                             shortcutsContainer.setAccessibilityPaneTitle(mContext.getString(
                                     R.string.keyboard_shortcut_a11y_show_search_results));
                         }
+                        mEditTextCancel.setVisibility(
+                                TextUtils.isEmpty(mQueryString) ? View.GONE : View.VISIBLE);
                     }
 
                     @Override
@@ -933,9 +927,28 @@
                         // Do nothing.
                     }
                 });
-        ImageButton editTextCancel = keyboardShortcutsView.findViewById(
-                R.id.keyboard_shortcuts_search_cancel);
-        editTextCancel.setOnClickListener(v -> mSearchEditText.setText(null));
+
+        mEditTextCancel.setOnClickListener(v -> mSearchEditText.setText(null));
+    }
+
+    private static void setWindowProperties(Window keyboardShortcutsWindow) {
+        keyboardShortcutsWindow.setType(TYPE_SYSTEM_DIALOG);
+        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
+        params.copyFrom(keyboardShortcutsWindow.getAttributes());
+        // Allows the bottom sheet dialog to render all the way to the bottom of the screen,
+        // behind the gesture navigation bar.
+        params.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+        params.setFitInsetsTypes(WindowInsets.Type.statusBars());
+        keyboardShortcutsWindow.setAttributes(params);
+        keyboardShortcutsWindow.getDecorView().setOnApplyWindowInsetsListener((v, insets) -> {
+            int bottom = insets.getInsets(WindowInsets.Type.navigationBars()).bottom;
+            View container = v.findViewById(R.id.keyboard_shortcuts_container);
+            container.setPadding(container.getPaddingLeft(), container.getPaddingTop(),
+                    container.getPaddingRight(), bottom);
+            return WindowInsets.CONSUMED;
+        });
+        keyboardShortcutsWindow.setWindowAnimations(
+                R.style.KeyboardShortcutHelper_BottomSheetDialogAnimation);
     }
 
     private void populateKeyboardShortcutSearchList(LinearLayout keyboardShortcutsLayout) {
@@ -1256,10 +1269,10 @@
         if (mContext.getResources().getConfiguration().orientation
                 == Configuration.ORIENTATION_PORTRAIT) {
             lp.width = (int) (display.getWidth() * 0.8);
-            lp.height = (int) (display.getHeight() * 0.7);
+            lp.height = (int) (display.getHeight() * 0.8);
         } else {
             lp.width = (int) (display.getWidth() * 0.7);
-            lp.height = (int) (display.getHeight() * 0.8);
+            lp.height = (int) (display.getHeight() * 0.95);
         }
         window.setGravity(Gravity.BOTTOM);
         window.setAttributes(lp);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java
index 8d7fc98..acb5339 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameView.java
@@ -19,8 +19,6 @@
 import android.util.AttributeSet;
 import android.widget.TextView;
 
-import com.android.settingslib.WirelessUtils;
-
 /** Shows the operator name */
 public class OperatorNameView extends TextView {
     private boolean mDemoMode;
@@ -41,13 +39,14 @@
         mDemoMode = demoMode;
     }
 
-    void update(boolean showOperatorName,
+    void update(
+            boolean showOperatorName,
             boolean hasMobile,
+            boolean airplaneMode,
             OperatorNameViewController.SubInfo sub
     ) {
         setVisibility(showOperatorName ? VISIBLE : GONE);
 
-        boolean airplaneMode = WirelessUtils.isAirplaneModeOn(mContext);
         if (!hasMobile || airplaneMode) {
             setText(null);
             setVisibility(GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java
index 8afc72f..6e7d8f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/OperatorNameViewController.java
@@ -16,11 +16,9 @@
 
 package com.android.systemui.statusbar;
 
-import android.annotation.NonNull;
 import android.os.Bundle;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.view.View;
 
@@ -28,47 +26,60 @@
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.systemui.demomode.DemoModeCommandReceiver;
 import com.android.systemui.plugins.DarkIconDispatcher;
-import com.android.systemui.statusbar.connectivity.IconState;
-import com.android.systemui.statusbar.connectivity.NetworkController;
-import com.android.systemui.statusbar.connectivity.SignalCallback;
 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor;
+import com.android.systemui.statusbar.pipeline.mobile.util.SubscriptionManagerProxy;
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.util.CarrierConfigTracker;
 import com.android.systemui.util.ViewController;
+import com.android.systemui.util.kotlin.JavaAdapter;
 
 import javax.inject.Inject;
 
+import kotlinx.coroutines.Job;
+
 /** Controller for {@link OperatorNameView}. */
 public class OperatorNameViewController extends ViewController<OperatorNameView> {
     private static final String KEY_SHOW_OPERATOR_NAME = "show_operator_name";
 
     private final DarkIconDispatcher mDarkIconDispatcher;
-    private final NetworkController mNetworkController;
     private final TunerService mTunerService;
     private final TelephonyManager mTelephonyManager;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final CarrierConfigTracker mCarrierConfigTracker;
+    private final AirplaneModeInteractor mAirplaneModeInteractor;
+    private final SubscriptionManagerProxy mSubscriptionManagerProxy;
+    private final JavaAdapter mJavaAdapter;
+
+    private Job mAirplaneModeJob;
 
     private OperatorNameViewController(OperatorNameView view,
             DarkIconDispatcher darkIconDispatcher,
-            NetworkController networkController,
             TunerService tunerService,
             TelephonyManager telephonyManager,
             KeyguardUpdateMonitor keyguardUpdateMonitor,
-            CarrierConfigTracker carrierConfigTracker) {
+            CarrierConfigTracker carrierConfigTracker,
+            AirplaneModeInteractor airplaneModeInteractor,
+            SubscriptionManagerProxy subscriptionManagerProxy,
+            JavaAdapter javaAdapter) {
         super(view);
         mDarkIconDispatcher = darkIconDispatcher;
-        mNetworkController = networkController;
         mTunerService = tunerService;
         mTelephonyManager = telephonyManager;
         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
         mCarrierConfigTracker = carrierConfigTracker;
+        mAirplaneModeInteractor = airplaneModeInteractor;
+        mSubscriptionManagerProxy = subscriptionManagerProxy;
+        mJavaAdapter = javaAdapter;
     }
 
     @Override
     protected void onViewAttached() {
         mDarkIconDispatcher.addDarkReceiver(mDarkReceiver);
-        mNetworkController.addCallback(mSignalCallback);
+        mAirplaneModeJob =
+                mJavaAdapter.alwaysCollectFlow(
+                        mAirplaneModeInteractor.isAirplaneMode(),
+                        (isAirplaneMode) -> update());
         mTunerService.addTunable(mTunable, KEY_SHOW_OPERATOR_NAME);
         mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
     }
@@ -76,7 +87,7 @@
     @Override
     protected void onViewDetached() {
         mDarkIconDispatcher.removeDarkReceiver(mDarkReceiver);
-        mNetworkController.removeCallback(mSignalCallback);
+        mAirplaneModeJob.cancel(null);
         mTunerService.removeTunable(mTunable);
         mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback);
     }
@@ -87,11 +98,17 @@
                 mCarrierConfigTracker
                         .getShowOperatorNameInStatusBarConfig(defaultSubInfo.getSubId())
                         && (mTunerService.getValue(KEY_SHOW_OPERATOR_NAME, 1) != 0);
-        mView.update(showOperatorName, mTelephonyManager.isDataCapable(), getDefaultSubInfo());
+        mView.update(
+                showOperatorName,
+                mTelephonyManager.isDataCapable(),
+                mAirplaneModeInteractor.isAirplaneMode().getValue(),
+                getDefaultSubInfo()
+        );
     }
 
     private SubInfo getDefaultSubInfo() {
-        int defaultSubId = SubscriptionManager.getDefaultDataSubscriptionId();
+        int defaultSubId = mSubscriptionManagerProxy.getDefaultDataSubscriptionId();
+
         SubscriptionInfo sI = mKeyguardUpdateMonitor.getSubscriptionInfoForSubId(defaultSubId);
         return new SubInfo(
                 sI.getSubscriptionId(),
@@ -103,36 +120,44 @@
     /** Factory for constructing an {@link OperatorNameViewController}. */
     public static class Factory {
         private final DarkIconDispatcher mDarkIconDispatcher;
-        private final NetworkController mNetworkController;
         private final TunerService mTunerService;
         private final TelephonyManager mTelephonyManager;
         private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
         private final CarrierConfigTracker mCarrierConfigTracker;
+        private final AirplaneModeInteractor mAirplaneModeInteractor;
+        private final SubscriptionManagerProxy mSubscriptionManagerProxy;
+        private final JavaAdapter mJavaAdapter;
 
         @Inject
         public Factory(DarkIconDispatcher darkIconDispatcher,
-                NetworkController networkController,
                 TunerService tunerService,
                 TelephonyManager telephonyManager,
                 KeyguardUpdateMonitor keyguardUpdateMonitor,
-                CarrierConfigTracker carrierConfigTracker) {
+                CarrierConfigTracker carrierConfigTracker,
+                AirplaneModeInteractor airplaneModeInteractor,
+                SubscriptionManagerProxy subscriptionManagerProxy,
+                JavaAdapter javaAdapter) {
             mDarkIconDispatcher = darkIconDispatcher;
-            mNetworkController = networkController;
             mTunerService = tunerService;
             mTelephonyManager = telephonyManager;
             mKeyguardUpdateMonitor = keyguardUpdateMonitor;
             mCarrierConfigTracker = carrierConfigTracker;
+            mAirplaneModeInteractor = airplaneModeInteractor;
+            mSubscriptionManagerProxy = subscriptionManagerProxy;
+            mJavaAdapter = javaAdapter;
         }
 
         /** Create an {@link OperatorNameViewController}. */
         public OperatorNameViewController create(OperatorNameView view) {
             return new OperatorNameViewController(view,
                     mDarkIconDispatcher,
-                    mNetworkController,
                     mTunerService,
                     mTelephonyManager,
                     mKeyguardUpdateMonitor,
-                    mCarrierConfigTracker);
+                    mCarrierConfigTracker,
+                    mAirplaneModeInteractor,
+                    mSubscriptionManagerProxy,
+                    mJavaAdapter);
         }
     }
 
@@ -149,13 +174,6 @@
             (area, darkIntensity, tint) ->
                     mView.setTextColor(DarkIconDispatcher.getTint(area, mView, tint));
 
-    private final SignalCallback mSignalCallback = new SignalCallback() {
-        @Override
-        public void setIsAirplaneMode(@NonNull IconState icon) {
-            update();
-        }
-    };
-
     private final TunerService.Tunable mTunable = (key, newValue) -> update();
 
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index 9b2a6df..aa6bec1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -46,9 +46,9 @@
 import com.android.systemui.DejankUtils;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor;
+import com.android.systemui.deviceentry.shared.model.DeviceUnlockStatus;
 import com.android.systemui.keyguard.MigrateClocksToBlueprint;
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor;
-import com.android.systemui.plugins.clocks.ClockController;
 import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.res.R;
 import com.android.systemui.scene.domain.interactor.SceneInteractor;
@@ -199,7 +199,7 @@
         if (SceneContainerFlag.isEnabled()) {
             mJavaAdapter.alwaysCollectFlow(
                     combineFlows(
-                        mDeviceUnlockedInteractorLazy.get().isDeviceUnlocked(),
+                        mDeviceUnlockedInteractorLazy.get().getDeviceUnlockStatus(),
                         mSceneInteractorLazy.get().getCurrentScene(),
                         this::calculateStateFromSceneFramework),
                     this::onStatusBarStateChanged);
@@ -468,13 +468,7 @@
     /** Returns the id of the currently rendering clock */
     public String getClockId() {
         if (MigrateClocksToBlueprint.isEnabled()) {
-            ClockController clock = mKeyguardClockInteractorLazy.get()
-                    .getCurrentClock().getValue();
-            if (clock == null) {
-                Log.e(TAG, "No clock is available");
-                return KeyguardClockSwitch.MISSING_CLOCK_ID;
-            }
-            return clock.getConfig().getId();
+            return mKeyguardClockInteractorLazy.get().getRenderedClockId();
         }
 
         if (mClockSwitchView == null) {
@@ -653,11 +647,11 @@
     }
 
     private int calculateStateFromSceneFramework(
-            boolean isDeviceUnlocked,
+            DeviceUnlockStatus deviceUnlockStatus,
             SceneKey currentScene) {
         SceneContainerFlag.isUnexpectedlyInLegacyMode();
 
-        if (isDeviceUnlocked) {
+        if (deviceUnlockStatus.isUnlocked()) {
             return StatusBarState.SHADE;
         } else {
             return Preconditions.checkNotNull(sStatusBarStateByLockedSceneKey.get(currentScene));
@@ -680,7 +674,8 @@
             Scenes.Bouncer, StatusBarState.KEYGUARD,
             Scenes.Communal, StatusBarState.KEYGUARD,
             Scenes.Shade, StatusBarState.SHADE_LOCKED,
-            Scenes.QuickSettings, StatusBarState.SHADE_LOCKED
+            Scenes.QuickSettings, StatusBarState.SHADE_LOCKED,
+            Scenes.Gone, StatusBarState.SHADE
     );
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
index 8104755..d2fe20d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
@@ -23,6 +23,7 @@
 
 import com.android.systemui.CoreStartable;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.startable.Dependencies;
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 
 import java.lang.annotation.Retention;
@@ -30,6 +31,7 @@
 /**
  * Sends updates to {@link StateListener}s about changes to the status bar state and dozing state
  */
+@Dependencies(CentralSurfaces.class)
 public interface SysuiStatusBarStateController extends StatusBarStateController, CoreStartable {
 
     // TODO: b/115739177 (remove this explicit ordering if we can)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
index c4d9cbf..7a7cb7d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
@@ -123,7 +123,7 @@
                         labelRes = R.string.airplane_mode,
                     ),
                 instanceId = uiEventLogger.getNewInstanceId(),
-                policy = QSTilePolicy.Restricted(UserManager.DISALLOW_AIRPLANE_MODE),
+                policy = QSTilePolicy.Restricted(listOf(UserManager.DISALLOW_AIRPLANE_MODE)),
             )
 
         /** Inject AirplaneModeTile into tileViewModelMap in QSModule */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt
index eb0870a..2b7df7d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt
@@ -75,6 +75,8 @@
     private val notificationEntry = notification.entry
     private val notificationKey = notificationEntry.sbn.key
 
+    override val isLaunching: Boolean = true
+
     override var transitionContainer: ViewGroup
         get() = notification.rootView as ViewGroup
         set(ignored) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index 7c71864..4c66f66 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -23,7 +23,9 @@
 import com.android.app.animation.Interpolators
 import com.android.app.animation.InterpolatorsAndroidX
 import com.android.systemui.Dumpable
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.shade.ShadeExpansionChangeEvent
@@ -47,11 +49,14 @@
 import javax.inject.Inject
 import kotlin.math.max
 import kotlin.math.min
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
 
 @SysUISingleton
 class NotificationWakeUpCoordinator
 @Inject
 constructor(
+    @Application applicationScope: CoroutineScope,
     dumpManager: DumpManager,
     private val mHeadsUpManager: HeadsUpManager,
     private val statusBarStateController: StatusBarStateController,
@@ -60,6 +65,7 @@
     private val screenOffAnimationController: ScreenOffAnimationController,
     private val logger: NotificationWakeUpCoordinatorLogger,
     private val notifsKeyguardInteractor: NotificationsKeyguardInteractor,
+    private val communalInteractor: CommunalInteractor,
 ) :
     OnHeadsUpChangedListener,
     StatusBarStateController.StateListener,
@@ -201,6 +207,13 @@
                 }
             }
         )
+        applicationScope.launch {
+            communalInteractor.isIdleOnCommunal.collect {
+                if (!overrideDozeAmountIfCommunalShowing()) {
+                    maybeClearHardDozeAmountOverrideHidingNotifs()
+                }
+            }
+        }
     }
 
     fun setStackScroller(stackScrollerController: NotificationStackScrollLayoutController) {
@@ -302,6 +315,10 @@
             return
         }
 
+        if (overrideDozeAmountIfCommunalShowing()) {
+            return
+        }
+
         if (clearHardDozeAmountOverride()) {
             return
         }
@@ -311,9 +328,12 @@
 
     private fun setHardDozeAmountOverride(dozing: Boolean, source: String) {
         logger.logSetDozeAmountOverride(dozing = dozing, source = source)
+        val previousOverride = hardDozeAmountOverride
         hardDozeAmountOverride = if (dozing) 1f else 0f
         hardDozeAmountOverrideSource = source
-        updateDozeAmount()
+        if (previousOverride != hardDozeAmountOverride) {
+            updateDozeAmount()
+        }
     }
 
     private fun clearHardDozeAmountOverride(): Boolean {
@@ -434,6 +454,11 @@
             return
         }
 
+        if (overrideDozeAmountIfCommunalShowing()) {
+            this.state = newState
+            return
+        }
+
         maybeClearHardDozeAmountOverrideHidingNotifs()
 
         this.state = newState
@@ -471,6 +496,18 @@
         return false
     }
 
+    private fun overrideDozeAmountIfCommunalShowing(): Boolean {
+        if (communalInteractor.isIdleOnCommunal.value) {
+            if (statusBarStateController.state == StatusBarState.KEYGUARD) {
+                setHardDozeAmountOverride(dozing = true, source = "Override: communal (keyguard)")
+            } else {
+                setHardDozeAmountOverride(dozing = false, source = "Override: communal (shade)")
+            }
+            return true
+        }
+        return false
+    }
+
     /**
      * If the last [setDozeAmount] call was an override to hide notifications, then this call will
      * check for the set of states that may have caused that override, and if none of them still
@@ -483,20 +520,23 @@
             val onKeyguard = statusBarStateController.state == StatusBarState.KEYGUARD
             val dozing = statusBarStateController.isDozing
             val bypass = bypassController.bypassEnabled
+            val idleOnCommunal = communalInteractor.isIdleOnCommunal.value
             val animating =
                 screenOffAnimationController.overrideNotificationsFullyDozingOnKeyguard()
-            // Overrides are set by [overrideDozeAmountIfAnimatingScreenOff] and
-            // [overrideDozeAmountIfBypass] based on 'animating' and 'bypass' respectively, so only
-            // clear the override if both those conditions are cleared.  But also require either
+            // Overrides are set by [overrideDozeAmountIfAnimatingScreenOff],
+            // [overrideDozeAmountIfBypass] and [overrideDozeAmountIfCommunalShowing] based on
+            // 'animating', 'bypass' and 'idleOnCommunal' respectively, so only clear the override
+            // if all of those conditions are cleared.  But also require either
             // !dozing or !onKeyguard because those conditions should indicate that we intend
             // notifications to be visible, and thus it is safe to unhide them.
-            val willRemove = (!onKeyguard || !dozing) && !bypass && !animating
+            val willRemove = (!onKeyguard || !dozing) && !bypass && !animating && !idleOnCommunal
             logger.logMaybeClearHardDozeAmountOverrideHidingNotifs(
                 willRemove = willRemove,
                 onKeyguard = onKeyguard,
                 dozing = dozing,
                 bypass = bypass,
                 animating = animating,
+                idleOnCommunal = idleOnCommunal,
             )
             if (willRemove) {
                 clearHardDozeAmountOverride()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt
index 502e1d9..9619bea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorLogger.kt
@@ -95,6 +95,7 @@
         onKeyguard: Boolean,
         dozing: Boolean,
         bypass: Boolean,
+        idleOnCommunal: Boolean,
         animating: Boolean,
     ) {
         buffer.log(
@@ -103,7 +104,7 @@
             {
                 str1 =
                     "willRemove=$willRemove onKeyguard=$onKeyguard dozing=$dozing" +
-                        " bypass=$bypass animating=$animating"
+                        " bypass=$bypass animating=$animating idleOnCommunal=$idleOnCommunal"
             },
             { "maybeClearHardDozeAmountOverrideHidingNotifs() $str1" }
         )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SortBySectionTimeFlag.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SortBySectionTimeFlag.kt
new file mode 100644
index 0000000..09cb310
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SortBySectionTimeFlag.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.collection
+
+import android.app.Flags;
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/**
+ * Helper for android.app.Flags.FLAG_SORT_BY_SECTION_TIME
+ */
+@Suppress("NOTHING_TO_INLINE")
+object SortBySectionTimeFlag {
+    const val FLAG_NAME = Flags.FLAG_SORT_SECTION_BY_TIME
+
+    /** A token used for dependency declaration */
+    val token: FlagToken
+        get() = FlagToken(FLAG_NAME, isEnabled)
+
+    /** Are sections sorted by time? */
+    @JvmStatic
+    inline val isEnabled
+        get() = Flags.sortSectionByTime()
+
+    /**
+     * Called to ensure code is only run when the flag is enabled. This protects users from the
+     * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+     * build to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun isUnexpectedlyInLegacyMode() =
+            RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+    /**
+     * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+     * the flag is enabled to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt
index 1631ae2..3d0fd89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt
@@ -19,6 +19,7 @@
 import com.android.systemui.statusbar.notification.collection.ListEntry
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.SortBySectionTimeFlag
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator
@@ -80,11 +81,20 @@
         }
     }
 
+    // TODO(b/330193582): Rename to just "People"
     val peopleAlertingSectioner = object : NotifSectioner("People(alerting)", BUCKET_PEOPLE) {
-        override fun isInSection(entry: ListEntry): Boolean =
-               highPriorityProvider.isHighPriorityConversation(entry)
+        override fun isInSection(entry: ListEntry): Boolean  {
+            if (SortBySectionTimeFlag.isEnabled) {
+                return highPriorityProvider.isHighPriorityConversation(entry)
+                        || isConversation(entry)
+            } else {
+                return highPriorityProvider.isHighPriorityConversation(entry)
+            }
+        }
 
-        override fun getComparator(): NotifComparator = notifComparator
+        override fun getComparator(): NotifComparator? {
+            return if (SortBySectionTimeFlag.isEnabled) null else notifComparator
+        }
 
         override fun getHeaderNodeController(): NodeController? = conversationHeaderNodeController
     }
@@ -92,11 +102,20 @@
     val peopleSilentSectioner = object : NotifSectioner("People(silent)", BUCKET_PEOPLE) {
         // Because the peopleAlertingSectioner is above this one, it will claim all conversations that are alerting.
         // All remaining conversations must be silent.
-        override fun isInSection(entry: ListEntry): Boolean = isConversation(entry)
+        override fun isInSection(entry: ListEntry): Boolean {
+            SortBySectionTimeFlag.assertInLegacyMode()
+            return isConversation(entry)
+        }
 
-        override fun getComparator(): NotifComparator = notifComparator
+        override fun getComparator(): NotifComparator {
+            SortBySectionTimeFlag.assertInLegacyMode()
+            return notifComparator
+        }
 
-        override fun getHeaderNodeController(): NodeController? = conversationHeaderNodeController
+        override fun getHeaderNodeController(): NodeController? {
+            SortBySectionTimeFlag.assertInLegacyMode()
+            return conversationHeaderNodeController
+        }
     }
 
     override fun attach(pipeline: NotifPipeline) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
index 8531eaa..1a223c1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
@@ -18,6 +18,7 @@
 
 package com.android.systemui.statusbar.notification.collection.coordinator
 
+import android.os.SystemProperties
 import android.os.UserHandle
 import android.provider.Settings
 import androidx.annotation.VisibleForTesting
@@ -340,12 +341,41 @@
 
             var hasFilteredAnyNotifs = false
 
+            /**
+             * the [notificationMinimalismPrototype] will now show seen notifications on the locked
+             * shade by default, but this property read allows that to be quickly disabled for
+             * testing
+             */
+            private val minimalismShowOnLockedShade
+                get() =
+                    SystemProperties.getBoolean(
+                        "persist.notification_minimalism_prototype.show_on_locked_shade",
+                        true
+                    )
+
+            /**
+             * Encapsulates a definition of "being on the keyguard". Note that these two definitions
+             * are wildly different: [StatusBarState.KEYGUARD] is when on the lock screen and does
+             * not include shade or occluded states, whereas [KeyguardRepository.isKeyguardShowing]
+             * is any state where the keyguard has not been dismissed, including locked shade and
+             * occluded lock screen.
+             *
+             * Returning false for locked shade and occluded states means that this filter will
+             * allow seen notifications to appear in the locked shade.
+             */
+            private fun isOnKeyguard(): Boolean =
+                if (notificationMinimalismPrototype() && minimalismShowOnLockedShade) {
+                    statusBarStateController.state == StatusBarState.KEYGUARD
+                } else {
+                    keyguardRepository.isKeyguardShowing()
+                }
+
             override fun shouldFilterOut(entry: NotificationEntry, now: Long): Boolean =
                 when {
                     // Don't apply filter if the setting is disabled
                     !unseenFilterEnabled -> false
                     // Don't apply filter if the keyguard isn't currently showing
-                    !keyguardRepository.isKeyguardShowing() -> false
+                    !isOnKeyguard() -> false
                     // Don't apply the filter if the notification is unseen
                     unseenNotifications.contains(entry) -> false
                     // Don't apply the filter to (non-promoted) group summaries
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
index b9d1dde..36c12a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
@@ -20,6 +20,7 @@
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.PipelineDumpable
 import com.android.systemui.statusbar.notification.collection.PipelineDumper
+import com.android.systemui.statusbar.notification.collection.SortBySectionTimeFlag
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
 import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
@@ -114,17 +115,26 @@
         mOrderedSections.add(headsUpCoordinator.sectioner) // HeadsUp
         mOrderedSections.add(colorizedFgsCoordinator.sectioner) // ForegroundService
         mOrderedSections.add(conversationCoordinator.peopleAlertingSectioner) // People Alerting
-        mOrderedSections.add(conversationCoordinator.peopleSilentSectioner) // People Silent
+        if (!SortBySectionTimeFlag.isEnabled) {
+            mOrderedSections.add(conversationCoordinator.peopleSilentSectioner) // People Silent
+        }
         mOrderedSections.add(rankingCoordinator.alertingSectioner) // Alerting
         mOrderedSections.add(rankingCoordinator.silentSectioner) // Silent
         mOrderedSections.add(rankingCoordinator.minimizedSectioner) // Minimized
 
         sectionStyleProvider.setMinimizedSections(setOf(rankingCoordinator.minimizedSectioner))
-        sectionStyleProvider.setSilentSections(listOf(
-                conversationCoordinator.peopleSilentSectioner,
-                rankingCoordinator.silentSectioner,
-                rankingCoordinator.minimizedSectioner,
-        ))
+        if (SortBySectionTimeFlag.isEnabled) {
+            sectionStyleProvider.setSilentSections(listOf(
+                    rankingCoordinator.silentSectioner,
+                    rankingCoordinator.minimizedSectioner,
+            ))
+        } else {
+            sectionStyleProvider.setSilentSections(listOf(
+                    conversationCoordinator.peopleSilentSectioner,
+                    rankingCoordinator.silentSectioner,
+                    rankingCoordinator.minimizedSectioner,
+            ))
+        }
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
index c8ca63d..1511abd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
@@ -17,6 +17,8 @@
 package com.android.systemui.statusbar.notification.collection.coordinator
 
 import com.android.app.tracing.traceSection
+import com.android.server.notification.Flags.screenshareNotificationHiding
+import com.android.systemui.Flags.screenshareNotificationHidingBugFix
 import com.android.systemui.statusbar.notification.collection.ListEntry
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
@@ -29,6 +31,7 @@
 import com.android.systemui.statusbar.notification.shared.NotificationIconContainerRefactor
 import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
 import com.android.systemui.statusbar.phone.NotificationIconAreaController
+import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController
 import javax.inject.Inject
 
 /**
@@ -43,6 +46,8 @@
     private val notificationIconAreaController: NotificationIconAreaController,
     private val renderListInteractor: RenderNotificationListInteractor,
     private val activeNotificationsInteractor: ActiveNotificationsInteractor,
+    private val sensitiveNotificationProtectionController:
+        SensitiveNotificationProtectionController,
 ) : Coordinator {
 
     override fun attach(pipeline: NotifPipeline) {
@@ -71,13 +76,16 @@
         var hasClearableAlertingNotifs = false
         var hasNonClearableSilentNotifs = false
         var hasClearableSilentNotifs = false
+        val isSensitiveContentProtectionActive = screenshareNotificationHiding() &&
+            screenshareNotificationHidingBugFix() &&
+            sensitiveNotificationProtectionController.isSensitiveStateActive
         entries.forEach {
             val section = checkNotNull(it.section) { "Null section for ${it.key}" }
             val entry = checkNotNull(it.representativeEntry) { "Null notif entry for ${it.key}" }
             val isSilent = section.bucket == BUCKET_SILENT
             // NOTE: NotificationEntry.isClearable will internally check group children to ensure
             //  the group itself definitively clearable.
-            val isClearable = entry.isClearable
+            val isClearable = !isSensitiveContentProtectionActive && entry.isClearable
             when {
                 isSilent && isClearable -> hasClearableSilentNotifs = true
                 isSilent && !isClearable -> hasNonClearableSilentNotifs = true
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
index dfe6cd5..350e88e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
@@ -24,6 +24,7 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.systemui.Dumpable;
+import com.android.systemui.communal.domain.interactor.CommunalInteractor;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dump.DumpManager;
@@ -68,6 +69,7 @@
     private final VisibilityLocationProvider mVisibilityLocationProvider;
     private final VisualStabilityProvider mVisualStabilityProvider;
     private final WakefulnessLifecycle mWakefulnessLifecycle;
+    private final CommunalInteractor mCommunalInteractor;
 
     private boolean mSleepy = true;
     private boolean mFullyDozed;
@@ -75,6 +77,7 @@
     private boolean mPulsing;
     private boolean mNotifPanelCollapsing;
     private boolean mNotifPanelLaunchingActivity;
+    private boolean mCommunalShowing = false;
 
     private boolean mPipelineRunAllowed;
     private boolean mReorderingAllowed;
@@ -101,7 +104,8 @@
             StatusBarStateController statusBarStateController,
             VisibilityLocationProvider visibilityLocationProvider,
             VisualStabilityProvider visualStabilityProvider,
-            WakefulnessLifecycle wakefulnessLifecycle) {
+            WakefulnessLifecycle wakefulnessLifecycle,
+            CommunalInteractor communalInteractor) {
         mHeadsUpManager = headsUpManager;
         mShadeAnimationInteractor = shadeAnimationInteractor;
         mJavaAdapter = javaAdapter;
@@ -110,6 +114,7 @@
         mWakefulnessLifecycle = wakefulnessLifecycle;
         mStatusBarStateController = statusBarStateController;
         mDelayableExecutor = delayableExecutor;
+        mCommunalInteractor = communalInteractor;
 
         dumpManager.registerDumpable(this);
     }
@@ -126,6 +131,8 @@
                 this::onShadeOrQsClosingChanged);
         mJavaAdapter.alwaysCollectFlow(mShadeAnimationInteractor.isLaunchingActivity(),
                 this::onLaunchingActivityChanged);
+        mJavaAdapter.alwaysCollectFlow(mCommunalInteractor.isIdleOnCommunal(),
+                this::onCommunalShowingChanged);
 
         pipeline.setVisualStabilityManager(mNotifStabilityManager);
     }
@@ -231,7 +238,7 @@
     }
 
     private boolean isReorderingAllowed() {
-        return ((mFullyDozed && mSleepy) || !mPanelExpanded) && !mPulsing;
+        return ((mFullyDozed && mSleepy) || !mPanelExpanded || mCommunalShowing) && !mPulsing;
     }
 
     /**
@@ -315,6 +322,7 @@
         pw.println("  fullyDozed: " + mFullyDozed);
         pw.println("  panelExpanded: " + mPanelExpanded);
         pw.println("  pulsing: " + mPulsing);
+        pw.println("  communalShowing: " + mCommunalShowing);
         pw.println("isSuppressingPipelineRun: " + mIsSuppressingPipelineRun);
         pw.println("isSuppressingGroupChange: " + mIsSuppressingGroupChange);
         pw.println("isSuppressingEntryReorder: " + mIsSuppressingEntryReorder);
@@ -338,4 +346,9 @@
         mNotifPanelLaunchingActivity = isLaunchingActivity;
         updateAllowedStates("notifPanelLaunchingActivity", isLaunchingActivity);
     }
+
+    private void onCommunalShowingChanged(boolean isShowing) {
+        mCommunalShowing = isShowing;
+        updateAllowedStates("communalShowing", isShowing);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt
index 5a3edf4..ea9f295 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt
@@ -18,8 +18,10 @@
 
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.statusbar.notification.collection.ListEntry
+import com.android.systemui.statusbar.notification.collection.SortBySectionTimeFlag
 import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
+import com.android.systemui.statusbar.notification.stack.BUCKET_PEOPLE
 import javax.inject.Inject
 
 /**
@@ -27,7 +29,8 @@
  * NOTE: This class exists to avoid putting metadata like "isMinimized" on the NotifSection
  */
 @SysUISingleton
-class SectionStyleProvider @Inject constructor() {
+class SectionStyleProvider @Inject constructor(
+        private val highPriorityProvider: HighPriorityProvider) {
     private lateinit var silentSections: Set<NotifSectioner>
     private lateinit var lowPrioritySections: Set<NotifSectioner>
 
@@ -76,6 +79,13 @@
     @JvmOverloads
     fun isSilent(entry: ListEntry, ifNotInSection: Boolean = true): Boolean {
         val section = entry.section ?: return ifNotInSection
-        return isSilentSection(section)
+        if (SortBySectionTimeFlag.isEnabled) {
+            if (entry.section?.bucket == BUCKET_PEOPLE) {
+                return !highPriorityProvider.isHighPriorityConversation(entry)
+            }
+            return isSilentSection(section)
+        } else {
+            return isSilentSection(section)
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
index adcbbfb..968b591 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterView.java
@@ -45,6 +45,7 @@
 import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor;
 import com.android.systemui.statusbar.notification.row.FooterViewButton;
 import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
+import com.android.systemui.statusbar.notification.stack.AnimationProperties;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 import com.android.systemui.statusbar.notification.stack.ViewState;
 import com.android.systemui.util.DrawableDumpKt;
@@ -102,6 +103,11 @@
         setClearAllButtonVisible(visible, animate, /* onAnimationEnded = */ null);
     }
 
+    /** Set the visibility of the "Manage"/"History" button to {@code visible}. */
+    public void setManageOrHistoryButtonVisible(boolean visible) {
+        mManageOrHistoryButton.setVisibility(visible ? View.VISIBLE : View.GONE);
+    }
+
     /**
      * Set the visibility of the "Clear all" button to {@code visible}. Animate the change if
      * {@code animate} is true.
@@ -274,14 +280,23 @@
 
     /** Show a message instead of the footer buttons. */
     public void setFooterLabelVisible(boolean isVisible) {
-        if (isVisible) {
-            mManageOrHistoryButton.setVisibility(View.GONE);
-            mClearAllButton.setVisibility(View.GONE);
-            mSeenNotifsFooterTextView.setVisibility(View.VISIBLE);
+        // In the refactored code, hiding the buttons is handled in the FooterViewModel
+        if (FooterViewRefactor.isEnabled()) {
+            if (isVisible) {
+                mSeenNotifsFooterTextView.setVisibility(View.VISIBLE);
+            } else {
+                mSeenNotifsFooterTextView.setVisibility(View.GONE);
+            }
         } else {
-            mManageOrHistoryButton.setVisibility(View.VISIBLE);
-            mClearAllButton.setVisibility(View.VISIBLE);
-            mSeenNotifsFooterTextView.setVisibility(View.GONE);
+            if (isVisible) {
+                mManageOrHistoryButton.setVisibility(View.GONE);
+                mClearAllButton.setVisibility(View.GONE);
+                mSeenNotifsFooterTextView.setVisibility(View.VISIBLE);
+            } else {
+                mManageOrHistoryButton.setVisibility(View.VISIBLE);
+                mClearAllButton.setVisibility(View.VISIBLE);
+                mSeenNotifsFooterTextView.setVisibility(View.GONE);
+            }
         }
     }
 
@@ -443,6 +458,12 @@
          */
         public boolean hideContent;
 
+        /**
+         * When true, skip animating Y on the next #animateTo.
+         * Once true, remains true until reset in #animateTo.
+         */
+        public boolean resetY = false;
+
         @Override
         public void copyFrom(ViewState viewState) {
             super.copyFrom(viewState);
@@ -459,5 +480,17 @@
                 footerView.setContentVisibleAnimated(!hideContent);
             }
         }
+
+        @Override
+        public void animateTo(View child, AnimationProperties properties) {
+            if (child instanceof FooterView) {
+                // Must set animateY=false before super.animateTo, which checks for animateY
+                if (resetY) {
+                    properties.getAnimationFilter().animateY = false;
+                    resetY = false;
+                }
+            }
+            super.animateTo(child, properties);
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewbinder/FooterViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewbinder/FooterViewBinder.kt
index 65ab4fd..637cadd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewbinder/FooterViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewbinder/FooterViewBinder.kt
@@ -141,8 +141,12 @@
             }
         }
 
-        // NOTE: The manage/history button is always visible as long as the footer is visible, no
-        //  need to update the visibility here.
+        launch {
+            viewModel.manageOrHistoryButton.isVisible.collect { isVisible ->
+                // NOTE: This visibility change is never animated.
+                footer.setManageOrHistoryButtonVisible(isVisible.value)
+            }
+        }
     }
 
     private suspend fun bindMessage(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModel.kt
index b23ef35..90fb728 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModel.kt
@@ -34,6 +34,7 @@
 import javax.inject.Provider
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onStart
@@ -45,12 +46,33 @@
     seenNotificationsInteractor: SeenNotificationsInteractor,
     shadeInteractor: ShadeInteractor,
 ) {
+    /** A message to show instead of the footer buttons. */
+    val message: FooterMessageViewModel =
+        FooterMessageViewModel(
+            messageId = R.string.unlock_to_see_notif_text,
+            iconId = R.drawable.ic_friction_lock_closed,
+            isVisible = seenNotificationsInteractor.hasFilteredOutSeenNotifications,
+        )
+
+    private val clearAllButtonVisible =
+        activeNotificationsInteractor.hasClearableNotifications
+            .combine(message.isVisible) { hasClearableNotifications, isMessageVisible ->
+                if (isMessageVisible) {
+                    // If the message is visible, the button never is
+                    false
+                } else {
+                    hasClearableNotifications
+                }
+            }
+            .distinctUntilChanged()
+
+    /** The button for clearing notifications. */
     val clearAllButton: FooterButtonViewModel =
         FooterButtonViewModel(
             labelId = flowOf(R.string.clear_all_notifications_text),
             accessibilityDescriptionId = flowOf(R.string.accessibility_clear_all),
             isVisible =
-                activeNotificationsInteractor.hasClearableNotifications
+                clearAllButtonVisible
                     .sample(
                         // TODO(b/322167853): This check is currently duplicated in
                         //  NotificationListViewModel, but instead it should be a field in
@@ -61,9 +83,9 @@
                                 ::Pair
                             )
                             .onStart { emit(Pair(false, false)) }
-                    ) { hasClearableNotifications, (isShadeFullyExpanded, animationsEnabled) ->
+                    ) { clearAllButtonVisible, (isShadeFullyExpanded, animationsEnabled) ->
                         val shouldAnimate = isShadeFullyExpanded && animationsEnabled
-                        AnimatableEvent(hasClearableNotifications, shouldAnimate)
+                        AnimatableEvent(clearAllButtonVisible, shouldAnimate)
                     }
                     .toAnimatedValueFlow(),
         )
@@ -77,18 +99,16 @@
             else R.string.manage_notifications_text
         }
 
+    /** The button for managing notification settings or opening notification history. */
     val manageOrHistoryButton: FooterButtonViewModel =
         FooterButtonViewModel(
             labelId = manageOrHistoryButtonText,
             accessibilityDescriptionId = manageOrHistoryButtonText,
-            isVisible = flowOf(AnimatedValue.NotAnimating(true)),
-        )
-
-    val message: FooterMessageViewModel =
-        FooterMessageViewModel(
-            messageId = R.string.unlock_to_see_notif_text,
-            iconId = R.drawable.ic_friction_lock_closed,
-            isVisible = seenNotificationsInteractor.hasFilteredOutSeenNotifications,
+            isVisible =
+                // Hide the manage button if the message is visible
+                message.isVisible.map { messageVisible ->
+                    AnimatedValue.NotAnimating(!messageVisible)
+                },
         )
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationHeadsUpCycling.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationHeadsUpCycling.kt
new file mode 100644
index 0000000..0344b32
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shared/NotificationHeadsUpCycling.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.shared
+
+import com.android.systemui.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for reading or using the heads-up cycling flag state. */
+@Suppress("NOTHING_TO_INLINE")
+object NotificationHeadsUpCycling {
+    /** The aconfig flag name */
+    const val FLAG_NAME = Flags.FLAG_NOTIFICATION_HEADS_UP_CYCLING
+
+    /** A token used for dependency declaration */
+    val token: FlagToken
+        get() = FlagToken(FLAG_NAME, isEnabled)
+
+    /** Is the heads-up cycling animation enabled */
+    @JvmStatic
+    inline val isEnabled
+        get() = Flags.notificationContentAlphaOptimization()
+
+    /**
+     * Called to ensure code is only run when the flag is enabled. This protects users from the
+     * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+     * build to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun isUnexpectedlyInLegacyMode() =
+        RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+    /**
+     * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+     * the flag is enabled to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 5b9eb21..0bb871b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -742,7 +742,7 @@
         pw.println("mHideSensitive=" + mHideSensitive);
         pw.println("mShadeExpanded=" + mShadeExpanded);
         pw.println("mClearAllInProgress=" + mClearAllInProgress);
-        pw.println("mStatusBarState=" + mStatusBarState);
+        pw.println("mStatusBarState=" + StatusBarState.toString(mStatusBarState));
         pw.println("mExpansionChanging=" + mExpansionChanging);
         pw.println("mPanelFullWidth=" + mIsSmallScreen);
         pw.println("mPulsing=" + mPulsing);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java
index 03a1082..0c248f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java
@@ -30,7 +30,7 @@
     public static final int NO_DELAY = -1;
     boolean animateAlpha;
     boolean animateX;
-    boolean animateY;
+    public boolean animateY;
     ArraySet<View> animateYViews = new ArraySet<>();
     boolean animateZ;
     boolean animateHeight;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 3367dc4..82559de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -113,6 +113,9 @@
 import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
 import com.android.systemui.statusbar.notification.shared.NotificationsImprovedHunAnimation;
 import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor;
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds;
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape;
+import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView;
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
 import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
@@ -135,6 +138,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.function.BiConsumer;
@@ -143,7 +147,9 @@
 /**
  * A layout which handles a dynamic amount of notifications and presents them in a scrollable stack.
  */
-public class NotificationStackScrollLayout extends ViewGroup implements Dumpable {
+public class NotificationStackScrollLayout
+        extends ViewGroup
+        implements Dumpable, NotificationScrollView {
 
     public static final float BACKGROUND_ALPHA_DIMMED = 0.7f;
     private static final String TAG = "StackScroller";
@@ -218,6 +224,7 @@
      */
     private final StackScrollAlgorithm mStackScrollAlgorithm;
     private final AmbientState mAmbientState;
+    private final ScrollViewFields mScrollViewFields = new ScrollViewFields();
 
     private final GroupMembershipManager mGroupMembershipManager;
     private final GroupExpansionManager mGroupExpansionManager;
@@ -230,7 +237,8 @@
     private final ArrayList<View> mSwipedOutViews = new ArrayList<>();
     private NotificationStackSizeCalculator mNotificationStackSizeCalculator;
     private final StackStateAnimator mStateAnimator;
-    private boolean mAnimationsEnabled;
+    // TODO(b/332732878): call setAnimationsEnabled with scene container enabled, then remove this
+    private boolean mAnimationsEnabled = SceneContainerFlag.isEnabled();
     private boolean mChangePositionInProgress;
     private boolean mChildTransferInProgress;
 
@@ -589,7 +597,7 @@
         @Override
         public boolean isScrolledToTop() {
             if (SceneContainerFlag.isEnabled()) {
-                return mController.isPlaceholderScrolledToTop();
+                return mScrollViewFields.isScrolledToTop();
             } else {
                 return mOwnScrollY == 0;
             }
@@ -854,7 +862,8 @@
         drawDebugInfo(canvas, y, Color.MAGENTA,
                 /* label= */ "mContentHeight = " + y);
 
-        drawDebugInfo(canvas, mRoundedRectClippingBottom, Color.DKGRAY,
+        y = mRoundedRectClippingBottom;
+        drawDebugInfo(canvas, y, Color.DKGRAY,
                 /* label= */ "mRoundedRectClippingBottom) = " + y);
     }
 
@@ -1130,6 +1139,48 @@
         }
     }
 
+    @Override
+    public View asView() {
+        return this;
+    }
+
+    @Override
+    public void setScrolledToTop(boolean scrolledToTop) {
+        mScrollViewFields.setScrolledToTop(scrolledToTop);
+    }
+
+    @Override
+    public void setStackTop(float stackTop) {
+        mScrollViewFields.setStackTop(stackTop);
+        // TODO(b/332574413): replace the following with using stackTop
+        updateTopPadding(stackTop, isAddOrRemoveAnimationPending());
+    }
+
+    @Override
+    public void setStackBottom(float stackBottom) {
+        mScrollViewFields.setStackBottom(stackBottom);
+    }
+
+    @Override
+    public void setHeadsUpTop(float headsUpTop) {
+        mScrollViewFields.setHeadsUpTop(headsUpTop);
+    }
+
+    @Override
+    public void setSyntheticScrollConsumer(@Nullable Consumer<Float> consumer) {
+        mScrollViewFields.setSyntheticScrollConsumer(consumer);
+    }
+
+    @Override
+    public void setStackHeightConsumer(@Nullable Consumer<Float> consumer) {
+        mScrollViewFields.setStackHeightConsumer(consumer);
+    }
+
+    @Override
+    public void setHeadsUpHeightConsumer(@Nullable Consumer<Float> consumer) {
+        mScrollViewFields.setHeadsUpHeightConsumer(consumer);
+    }
+
     /**
      * @param listener to be notified after the location of Notification children might have
      *                 changed.
@@ -1380,6 +1431,31 @@
         mOnStackYChanged = onStackYChanged;
     }
 
+    @Override
+    public void setExpandFraction(float expandFraction) {
+        if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
+        final float oldFraction = mAmbientState.getExpansionFraction();
+        final boolean wasExpanding = oldFraction != 0f && oldFraction != 1f;
+        final boolean nowExpanding = expandFraction != 0f && expandFraction != 1f;
+
+        // need to enter 'expanding' state before handling the new expand fraction, and then
+        if (nowExpanding && !wasExpanding) {
+            onExpansionStarted();
+            mController.checkSnoozeLeavebehind();
+        }
+
+        // Update the expand progress between started/stopped events
+        mAmbientState.setExpansionFraction(expandFraction);
+        // TODO(b/332577544): don't convert to height which then converts to the fraction again
+        setExpandedHeight(expandFraction * getHeight());
+
+        // expansion stopped event requires that the expandFraction has already been updated
+        if (!nowExpanding && wasExpanding) {
+            setCheckForLeaveBehind(false);
+            onExpansionStopped();
+        }
+    }
+
     /**
      * Update the height of the panel.
      *
@@ -1792,6 +1868,13 @@
     private void updateImeInset(WindowInsets windowInsets) {
         mImeInset = windowInsets.getInsets(WindowInsets.Type.ime()).bottom;
 
+        if (mFooterView != null && mFooterView.getViewState() != null) {
+            // Do not animate footer Y when showing IME so that after IME hides, the footer
+            // appears at the correct Y. Once resetY is true, it remains true (even when IME
+            // hides, where mImeInset=0) until reset in FooterViewState#animateTo.
+            ((FooterView.FooterViewState) mFooterView.getViewState()).resetY |= mImeInset > 0;
+        }
+
         if (mForcedScroll != null) {
             updateForcedScroll();
         }
@@ -2314,7 +2397,7 @@
                         /* notificationStackScrollLayout= */ this, mMaxDisplayedNotifications,
                         shelfIntrinsicHeight);
         mIntrinsicContentHeight = height;
-        mController.setIntrinsicContentHeight(mIntrinsicContentHeight);
+        mScrollViewFields.sendStackHeight(height);
 
         // The topPadding can be bigger than the regular padding when qs is expanded, in that
         // state the maxPanelHeight and the contentHeight should be bigger
@@ -2904,6 +2987,7 @@
     }
 
     public void setAnimationsEnabled(boolean animationsEnabled) {
+        // TODO(b/332732878): remove the initial value of this field once the setter is called
         mAnimationsEnabled = animationsEnabled;
         updateNotificationAnimationStates();
         if (!animationsEnabled) {
@@ -3553,7 +3637,7 @@
 
     protected boolean isInsideQsHeader(MotionEvent ev) {
         if (SceneContainerFlag.isEnabled()) {
-            return ev.getY() < mController.getPlaceholderTop();
+            return ev.getY() < mScrollViewFields.getScrimClippingShape().getBounds().getTop();
         }
 
         mQsHeader.getBoundsOnScreen(mQsHeaderBound);
@@ -4086,7 +4170,7 @@
                     // to it so that it can scroll the stack and scrim accordingly.
                     if (SceneContainerFlag.isEnabled()) {
                         float diff = endPosition - layoutEnd;
-                        mController.sendSyntheticScrollToSceneFramework(diff);
+                        mScrollViewFields.sendSyntheticScroll(diff);
                     }
                     setOwnScrollY((int) (mOwnScrollY + endPosition - layoutEnd));
                     mDisallowScrollingInThisMotion = true;
@@ -4969,6 +5053,7 @@
                     elapsedRealtime - mLastUpdateSidePaddingElapsedRealtime);
             println(pw, "isSmallLandscapeLockscreenEnabled", mIsSmallLandscapeLockscreenEnabled);
             mNotificationStackSizeCalculator.dump(pw, args);
+            mScrollViewFields.dump(pw);
         });
         pw.println();
         pw.println("Contents:");
@@ -5509,8 +5594,40 @@
     /**
      * Set rounded rect clipping bounds on this view.
      */
+    @Override
+    public void setScrimClippingShape(@Nullable ShadeScrimShape shape) {
+        if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) return;
+        if (Objects.equals(mScrollViewFields.getScrimClippingShape(), shape)) return;
+        mScrollViewFields.setScrimClippingShape(shape);
+        mShouldUseRoundedRectClipping = shape != null;
+        mRoundedClipPath.reset();
+        if (shape != null) {
+            ShadeScrimBounds bounds = shape.getBounds();
+            mRoundedRectClippingLeft = (int) bounds.getLeft();
+            mRoundedRectClippingTop = (int) bounds.getTop();
+            mRoundedRectClippingRight = (int) bounds.getRight();
+            mRoundedRectClippingBottom = (int) bounds.getBottom();
+            mBgCornerRadii[0] = shape.getTopRadius();
+            mBgCornerRadii[1] = shape.getTopRadius();
+            mBgCornerRadii[2] = shape.getTopRadius();
+            mBgCornerRadii[3] = shape.getTopRadius();
+            mBgCornerRadii[4] = shape.getBottomRadius();
+            mBgCornerRadii[5] = shape.getBottomRadius();
+            mBgCornerRadii[6] = shape.getBottomRadius();
+            mBgCornerRadii[7] = shape.getBottomRadius();
+            mRoundedClipPath.addRoundRect(
+                    bounds.getLeft(), bounds.getTop(), bounds.getRight(), bounds.getBottom(),
+                    mBgCornerRadii, Path.Direction.CW);
+        }
+        invalidate();
+    }
+
+    /**
+     * Set rounded rect clipping bounds on this view.
+     */
     public void setRoundedClippingBounds(int left, int top, int right, int bottom, int topRadius,
                                          int bottomRadius) {
+        SceneContainerFlag.assertInLegacyMode();
         if (mRoundedRectClippingLeft == left && mRoundedRectClippingRight == right
                 && mRoundedRectClippingBottom == bottom && mRoundedRectClippingTop == top
                 && mBgCornerRadii[0] == topRadius && mBgCornerRadii[5] == bottomRadius) {
@@ -5588,6 +5705,7 @@
      * Should we use rounded rect clipping
      */
     private void updateUseRoundedRectClipping() {
+        if (SceneContainerFlag.isEnabled()) return;
         // We don't want to clip notifications when QS is expanded, because incoming heads up on
         // the bottom would be clipped otherwise
         boolean qsAllowsClipping = mQsExpansionFraction < 0.5f || mShouldUseSplitNotificationShade;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index ec111a1..06479e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -83,7 +83,7 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.domain.interactor.PowerInteractor;
 import com.android.systemui.res.R;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
+import com.android.systemui.scene.shared.flag.SceneContainerFlag;
 import com.android.systemui.scene.ui.view.WindowRootView;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.shade.ShadeViewController;
@@ -115,7 +115,6 @@
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
 import com.android.systemui.statusbar.notification.dagger.SilentHeader;
-import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor;
 import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor;
 import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
@@ -127,12 +126,10 @@
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.notification.row.NotificationSnooze;
 import com.android.systemui.statusbar.notification.shared.NotificationsHeadsUpRefactor;
-import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor;
 import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationListViewBinder;
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
 import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -185,7 +182,6 @@
     private final FalsingCollector mFalsingCollector;
     private final FalsingManager mFalsingManager;
     private final NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder;
-    private final ScrimController mScrimController;
     private final NotifPipeline mNotifPipeline;
     private final NotifCollection mNotifCollection;
     private final UiEventLogger mUiEventLogger;
@@ -193,7 +189,6 @@
     private final VisibilityLocationProviderDelegator mVisibilityLocationProviderDelegator;
     private final ShadeController mShadeController;
     private final Provider<WindowRootView> mWindowRootView;
-    private final NotificationStackAppearanceInteractor mStackAppearanceInteractor;
     private final KeyguardMediaController mKeyguardMediaController;
     private final SysuiStatusBarStateController mStatusBarStateController;
     private final KeyguardBypassController mKeyguardBypassController;
@@ -734,7 +729,6 @@
             FalsingCollector falsingCollector,
             FalsingManager falsingManager,
             NotificationSwipeHelper.Builder notificationSwipeHelperBuilder,
-            ScrimController scrimController,
             GroupExpansionManager groupManager,
             @SilentHeader SectionHeaderController silentHeaderController,
             NotifPipeline notifPipeline,
@@ -743,13 +737,10 @@
             UiEventLogger uiEventLogger,
             NotificationRemoteInputManager remoteInputManager,
             VisibilityLocationProviderDelegator visibilityLocationProviderDelegator,
-            ActiveNotificationsInteractor activeNotificationsInteractor,
             SeenNotificationsInteractor seenNotificationsInteractor,
             NotificationListViewBinder viewBinder,
             ShadeController shadeController,
-            SceneContainerFlags sceneContainerFlags,
             Provider<WindowRootView> windowRootView,
-            NotificationStackAppearanceInteractor stackAppearanceInteractor,
             InteractionJankMonitor jankMonitor,
             StackStateLogger stackLogger,
             NotificationStackScrollLogger logger,
@@ -790,7 +781,6 @@
         mFalsingCollector = falsingCollector;
         mFalsingManager = falsingManager;
         mNotificationSwipeHelperBuilder = notificationSwipeHelperBuilder;
-        mScrimController = scrimController;
         mJankMonitor = jankMonitor;
         mNotificationStackSizeCalculator = notificationStackSizeCalculator;
         mGroupExpansionManager = groupManager;
@@ -803,7 +793,6 @@
         mSeenNotificationsInteractor = seenNotificationsInteractor;
         mShadeController = shadeController;
         mWindowRootView = windowRootView;
-        mStackAppearanceInteractor = stackAppearanceInteractor;
         mFeatureFlags = featureFlags;
         mNotificationTargetsHelper = notificationTargetsHelper;
         mSecureSettings = secureSettings;
@@ -1132,6 +1121,7 @@
     }
 
     public boolean isAddOrRemoveAnimationPending() {
+        SceneContainerFlag.assertInLegacyMode();
         return mView != null && mView.isAddOrRemoveAnimationPending();
     }
 
@@ -1171,29 +1161,6 @@
         }
     }
 
-    /** Send internal notification expansion to the scene container framework. */
-    public void sendSyntheticScrollToSceneFramework(Float delta) {
-        mStackAppearanceInteractor.setSyntheticScroll(delta);
-    }
-
-    /** Get the y-coordinate of the top bound of the stack. */
-    public float getPlaceholderTop() {
-        return mStackAppearanceInteractor.getStackBounds().getValue().getTop();
-    }
-
-    /**
-     * Returns whether the notification stack is scrolled to the top; i.e., it cannot be scrolled
-     * down any further.
-     */
-    public boolean isPlaceholderScrolledToTop() {
-        return mStackAppearanceInteractor.getScrolledToTop().getValue();
-    }
-
-    /** Set the intrinsic height of the stack content without additional padding. */
-    public void setIntrinsicContentHeight(float intrinsicContentHeight) {
-        mStackAppearanceInteractor.setIntrinsicContentHeight(intrinsicContentHeight);
-    }
-
     public void setIntrinsicPadding(int intrinsicPadding) {
         mView.setIntrinsicPadding(intrinsicPadding);
     }
@@ -1272,6 +1239,7 @@
     }
 
     public void setScrollingEnabled(boolean enabled) {
+        SceneContainerFlag.assertInLegacyMode();
         mView.setScrollingEnabled(enabled);
     }
 
@@ -1292,6 +1260,7 @@
     }
 
     public void updateTopPadding(float qsHeight, boolean animate) {
+        SceneContainerFlag.assertInLegacyMode();
         mView.updateTopPadding(qsHeight, animate);
     }
 
@@ -1394,11 +1363,13 @@
     }
 
     public void onExpansionStarted() {
+        SceneContainerFlag.assertInLegacyMode();
         mView.onExpansionStarted();
         checkSnoozeLeavebehind();
     }
 
     public void onExpansionStopped() {
+        SceneContainerFlag.assertInLegacyMode();
         mView.setCheckForLeaveBehind(false);
         mView.onExpansionStopped();
     }
@@ -1527,6 +1498,7 @@
     }
 
     public void setExpandedHeight(float expandedHeight) {
+        SceneContainerFlag.assertInLegacyMode();
         mView.setExpandedHeight(expandedHeight);
     }
 
@@ -1802,6 +1774,7 @@
      */
     public void setRoundedClippingBounds(int left, int top, int right, int bottom, int topRadius,
             int bottomRadius) {
+        SceneContainerFlag.assertInLegacyMode();
         mView.setRoundedClippingBounds(left, top, right, bottom, topRadius, bottomRadius);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
index 1b53cbe..5bd4c75 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
@@ -17,14 +17,15 @@
 package com.android.systemui.statusbar.notification.stack
 
 import android.content.res.Resources
+import android.os.SystemProperties
 import android.util.Log
 import android.view.View.GONE
 import androidx.annotation.VisibleForTesting
 import com.android.systemui.Flags.notificationMinimalismPrototype
-import com.android.systemui.res.R
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.LockscreenShadeTransitionController
 import com.android.systemui.statusbar.StatusBarState.KEYGUARD
 import com.android.systemui.statusbar.SysuiStatusBarStateController
@@ -177,8 +178,8 @@
 
         // TODO: Avoid making this split shade assumption by simply checking the stack for media
         val isMediaShowing = mediaDataManager.hasActiveMediaOrRecommendation()
-        val isMediaShowingInStack = isMediaShowing && !splitShadeStateController
-                .shouldUseSplitNotificationShade(resources)
+        val isMediaShowingInStack =
+            isMediaShowing && !splitShadeStateController.shouldUseSplitNotificationShade(resources)
 
         log { "\tGet maxNotifWithoutSavingSpace ---" }
         val maxNotifWithoutSavingSpace =
@@ -378,8 +379,17 @@
     }
 
     fun updateResources() {
-        maxKeyguardNotifications = if (notificationMinimalismPrototype()) 1
-            else infiniteIfNegative(resources.getInteger(R.integer.keyguard_max_notification_count))
+        maxKeyguardNotifications =
+            infiniteIfNegative(
+                if (notificationMinimalismPrototype()) {
+                    SystemProperties.getInt(
+                        "persist.notification_minimalism_prototype.lock_screen_max_notifs",
+                        1
+                    )
+                } else {
+                    resources.getInteger(R.integer.keyguard_max_notification_count)
+                }
+            )
         maxNotificationsExcludesMedia = notificationMinimalismPrototype()
 
         dividerHeight =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt
new file mode 100644
index 0000000..edac5ed
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.stack
+
+import android.util.IndentingPrintWriter
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape
+import com.android.systemui.util.printSection
+import com.android.systemui.util.println
+import java.util.function.Consumer
+
+/**
+ * This is a state holder object used by [NSSL][NotificationStackScrollLayout] to contain states
+ * provided by the `NotificationScrollViewBinder` to the `NotificationScrollView`.
+ *
+ * Unlike AmbientState, no class other than NSSL should ever have access to this class in any way.
+ * These fields are effectively NSSL's private fields.
+ */
+class ScrollViewFields {
+    /** Used to produce the clipping path */
+    var scrimClippingShape: ShadeScrimShape? = null
+    /** Y coordinate in view pixels of the top of the notification stack */
+    var stackTop: Float = 0f
+    /**
+     * Y coordinate in view pixels above which the bottom of the notification stack / shelf / footer
+     * must be.
+     */
+    var stackBottom: Float = 0f
+    /** Y coordinate in view pixels of the top of the HUN */
+    var headsUpTop: Float = 0f
+    /** Whether the notifications are scrolled all the way to the top (i.e. when freshly opened) */
+    var isScrolledToTop: Boolean = true
+
+    /**
+     * When internal NSSL expansion requires the stack to be scrolled (e.g. to keep an expanding
+     * notification in view), that scroll amount can be sent here and it will be handled by the
+     * placeholder
+     */
+    var syntheticScrollConsumer: Consumer<Float>? = null
+    /**
+     * Any time the stack height is recalculated, it should be updated here to be used by the
+     * placeholder
+     */
+    var stackHeightConsumer: Consumer<Float>? = null
+    /**
+     * Any time the heads up height is recalculated, it should be updated here to be used by the
+     * placeholder
+     */
+    var headsUpHeightConsumer: Consumer<Float>? = null
+
+    /** send the [syntheticScroll] to the [syntheticScrollConsumer], if present. */
+    fun sendSyntheticScroll(syntheticScroll: Float) =
+        syntheticScrollConsumer?.accept(syntheticScroll)
+    /** send the [stackHeight] to the [stackHeightConsumer], if present. */
+    fun sendStackHeight(stackHeight: Float) = stackHeightConsumer?.accept(stackHeight)
+    /** send the [headsUpHeight] to the [headsUpHeightConsumer], if present. */
+    fun sendHeadsUpHeight(headsUpHeight: Float) = headsUpHeightConsumer?.accept(headsUpHeight)
+
+    fun dump(pw: IndentingPrintWriter) {
+        pw.printSection("StackViewStates") {
+            pw.println("scrimClippingShape", scrimClippingShape)
+            pw.println("stackTop", stackTop)
+            pw.println("stackBottom", stackBottom)
+            pw.println("headsUpTop", headsUpTop)
+            pw.println("isScrolledToTop", isScrolledToTop)
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationPlaceholderRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationPlaceholderRepository.kt
new file mode 100644
index 0000000..b047379
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationPlaceholderRepository.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.stack.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
+import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
+
+/**
+ * This repository contains state generated by the composable placeholders to define the position
+ * and appearance of the notification stack and related visual elements
+ */
+@SysUISingleton
+class NotificationPlaceholderRepository @Inject constructor() {
+    /**
+     * The bounds of the notification shade scrim / container in the current scene.
+     *
+     * When `null`, clipping should not be applied to notifications.
+     */
+    val shadeScrimBounds = MutableStateFlow<ShadeScrimBounds?>(null)
+
+    /**
+     * The y-coordinate in px of top of the contents of the notification stack. This value can be
+     * negative, if the stack is scrolled such that its top extends beyond the top edge of the
+     * screen.
+     */
+    val stackTop = MutableStateFlow(0f)
+
+    /** the bottom-most acceptable y-position for the bottom of the stack / shelf */
+    val stackBottom = MutableStateFlow(0f)
+
+    /** the y position of the top of the HUN area */
+    val headsUpTop = MutableStateFlow(0f)
+
+    /** height made available to the notifications in the size-constrained mode of lock screen. */
+    val constrainedAvailableSpace = MutableStateFlow(0)
+
+    /**
+     * Whether the notification stack is scrolled to the top; i.e., it cannot be scrolled down any
+     * further.
+     */
+    val scrolledToTop = MutableStateFlow(true)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepository.kt
deleted file mode 100644
index 79ba25e..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepository.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package com.android.systemui.statusbar.notification.stack.data.repository
-
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.notification.stack.shared.model.StackBounds
-import javax.inject.Inject
-import kotlinx.coroutines.flow.MutableStateFlow
-
-/** A repository which holds state about and controlling the appearance of the notification stack */
-@SysUISingleton
-class NotificationStackAppearanceRepository @Inject constructor() {
-    /** The bounds of the notification stack in the current scene. */
-    val stackBounds = MutableStateFlow(StackBounds())
-
-    /**
-     * The height in px of the contents of notification stack. Depending on the number of
-     * notifications, this can exceed the space available on screen to show notifications, at which
-     * point the notification stack should become scrollable.
-     */
-    val intrinsicContentHeight = MutableStateFlow(0f)
-
-    /**
-     * The y-coordinate in px of top of the contents of the notification stack. This value can be
-     * negative, if the stack is scrolled such that its top extends beyond the top edge of the
-     * screen.
-     */
-    val contentTop = MutableStateFlow(0f)
-
-    /**
-     * Whether the notification stack is scrolled to the top; i.e., it cannot be scrolled down any
-     * further.
-     */
-    val scrolledToTop = MutableStateFlow(true)
-
-    /**
-     * The amount in px that the notification stack should scroll due to internal expansion. This
-     * should only happen when a notification expansion hits the bottom of the screen, so it is
-     * necessary to scroll up to keep expanding the notification.
-     */
-    val syntheticScroll = MutableStateFlow(0f)
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationViewHeightRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationViewHeightRepository.kt
new file mode 100644
index 0000000..8a9da69
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationViewHeightRepository.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.stack.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
+
+/**
+ * This repository contains state generated by the NSSL and required by the composable placeholders
+ * to ensure they are representing the actual contents that will be rendered.
+ */
+@SysUISingleton
+class NotificationViewHeightRepository @Inject constructor() {
+
+    /**
+     * The height in px of the contents of notification stack. Depending on the number of
+     * notifications, this can exceed the space available on screen to show notifications, at which
+     * point the notification stack should become scrollable.
+     */
+    val stackHeight = MutableStateFlow(0f)
+
+    /** The height in px of the current heads up notification. */
+    val headsUpHeight = MutableStateFlow(0f)
+
+    /**
+     * The amount in px that the notification stack should scroll due to internal expansion. This
+     * should only happen when a notification expansion hits the bottom of the screen, so it is
+     * necessary to scroll up to keep expanding the notification.
+     */
+    val syntheticScroll = MutableStateFlow(0f)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt
index f05d017..a5b4f5f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractor.kt
@@ -20,9 +20,10 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
-import com.android.systemui.statusbar.notification.stack.data.repository.NotificationStackAppearanceRepository
-import com.android.systemui.statusbar.notification.stack.shared.model.StackBounds
-import com.android.systemui.statusbar.notification.stack.shared.model.StackRounding
+import com.android.systemui.statusbar.notification.stack.data.repository.NotificationPlaceholderRepository
+import com.android.systemui.statusbar.notification.stack.data.repository.NotificationViewHeightRepository
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimRounding
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.StateFlow
@@ -36,11 +37,13 @@
 class NotificationStackAppearanceInteractor
 @Inject
 constructor(
-    private val repository: NotificationStackAppearanceRepository,
+    private val viewHeightRepository: NotificationViewHeightRepository,
+    private val placeholderRepository: NotificationPlaceholderRepository,
     shadeInteractor: ShadeInteractor,
 ) {
     /** The bounds of the notification stack in the current scene. */
-    val stackBounds: StateFlow<StackBounds> = repository.stackBounds.asStateFlow()
+    val shadeScrimBounds: StateFlow<ShadeScrimBounds?> =
+        placeholderRepository.shadeScrimBounds.asStateFlow()
 
     /**
      * Whether the stack is expanding from GONE-with-HUN to SHADE
@@ -50,14 +53,14 @@
     private val isExpandingFromHeadsUp: Flow<Boolean> = flowOf(false)
 
     /** The rounding of the notification stack. */
-    val stackRounding: Flow<StackRounding> =
+    val shadeScrimRounding: Flow<ShadeScrimRounding> =
         combine(
                 shadeInteractor.shadeMode,
                 isExpandingFromHeadsUp,
             ) { shadeMode, isExpandingFromHeadsUp ->
-                StackRounding(
-                    roundTop = !(shadeMode == ShadeMode.Split && isExpandingFromHeadsUp),
-                    roundBottom = shadeMode != ShadeMode.Single,
+                ShadeScrimRounding(
+                    isTopRounded = !(shadeMode == ShadeMode.Split && isExpandingFromHeadsUp),
+                    isBottomRounded = shadeMode != ShadeMode.Single,
                 )
             }
             .distinctUntilChanged()
@@ -67,47 +70,78 @@
      * notifications, this can exceed the space available on screen to show notifications, at which
      * point the notification stack should become scrollable.
      */
-    val intrinsicContentHeight: StateFlow<Float> = repository.intrinsicContentHeight.asStateFlow()
+    val stackHeight: StateFlow<Float> = viewHeightRepository.stackHeight.asStateFlow()
+
+    /** The height in px of the contents of the HUN. */
+    val headsUpHeight: StateFlow<Float> = viewHeightRepository.headsUpHeight.asStateFlow()
 
     /** The y-coordinate in px of top of the contents of the notification stack. */
-    val contentTop: StateFlow<Float> = repository.contentTop.asStateFlow()
+    val stackTop: StateFlow<Float> = placeholderRepository.stackTop.asStateFlow()
+
+    /** The y-coordinate in px of bottom of the contents of the notification stack. */
+    val stackBottom: StateFlow<Float> = placeholderRepository.stackBottom.asStateFlow()
+
+    /** The height of the keyguard's available space bounds */
+    val constrainedAvailableSpace: StateFlow<Int> =
+        placeholderRepository.constrainedAvailableSpace.asStateFlow()
 
     /**
      * Whether the notification stack is scrolled to the top; i.e., it cannot be scrolled down any
      * further.
      */
-    val scrolledToTop: StateFlow<Boolean> = repository.scrolledToTop.asStateFlow()
+    val scrolledToTop: StateFlow<Boolean> = placeholderRepository.scrolledToTop.asStateFlow()
+
+    /** The y-coordinate in px of bottom of the contents of the HUN. */
+    val headsUpTop: StateFlow<Float> = placeholderRepository.headsUpTop.asStateFlow()
 
     /**
      * The amount in px that the notification stack should scroll due to internal expansion. This
      * should only happen when a notification expansion hits the bottom of the screen, so it is
      * necessary to scroll up to keep expanding the notification.
      */
-    val syntheticScroll: Flow<Float> = repository.syntheticScroll.asStateFlow()
+    val syntheticScroll: Flow<Float> = viewHeightRepository.syntheticScroll.asStateFlow()
 
     /** Sets the position of the notification stack in the current scene. */
-    fun setStackBounds(bounds: StackBounds) {
-        check(bounds.top <= bounds.bottom) { "Invalid bounds: $bounds" }
-        repository.stackBounds.value = bounds
+    fun setShadeScrimBounds(bounds: ShadeScrimBounds?) {
+        check(bounds == null || bounds.top <= bounds.bottom) { "Invalid bounds: $bounds" }
+        placeholderRepository.shadeScrimBounds.value = bounds
     }
 
     /** Sets the height of the contents of the notification stack. */
-    fun setIntrinsicContentHeight(height: Float) {
-        repository.intrinsicContentHeight.value = height
+    fun setStackHeight(height: Float) {
+        viewHeightRepository.stackHeight.value = height
+    }
+
+    /** Sets the height of heads up notification. */
+    fun setHeadsUpHeight(height: Float) {
+        viewHeightRepository.headsUpHeight.value = height
     }
 
     /** Sets the y-coord in px of the top of the contents of the notification stack. */
-    fun setContentTop(startY: Float) {
-        repository.contentTop.value = startY
+    fun setStackTop(stackTop: Float) {
+        placeholderRepository.stackTop.value = stackTop
+    }
+
+    /** Sets the y-coord in px of the bottom of the contents of the notification stack. */
+    fun setStackBottom(stackBottom: Float) {
+        placeholderRepository.stackBottom.value = stackBottom
     }
 
     /** Sets whether the notification stack is scrolled to the top. */
     fun setScrolledToTop(scrolledToTop: Boolean) {
-        repository.scrolledToTop.value = scrolledToTop
+        placeholderRepository.scrolledToTop.value = scrolledToTop
     }
 
     /** Sets the amount (px) that the notification stack should scroll due to internal expansion. */
     fun setSyntheticScroll(delta: Float) {
-        repository.syntheticScroll.value = delta
+        viewHeightRepository.syntheticScroll.value = delta
+    }
+
+    fun setConstrainedAvailableSpace(height: Int) {
+        placeholderRepository.constrainedAvailableSpace.value = height
+    }
+
+    fun setHeadsUpTop(headsUpTop: Float) {
+        placeholderRepository.headsUpTop.value = headsUpTop
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackBounds.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimBounds.kt
similarity index 82%
rename from packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackBounds.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimBounds.kt
index 1fc9a18..7e3e724 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackBounds.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimBounds.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.statusbar.notification.stack.shared.model
 
 /** Models the bounds of the notification stack. */
-data class StackBounds(
+data class ShadeScrimBounds(
     /** The position of the left of the stack in its window coordinate system, in pixels. */
     val left: Float = 0f,
     /** The position of the top of the stack in its window coordinate system, in pixels. */
@@ -29,4 +29,12 @@
 ) {
     /** The current height of the notification container. */
     val height: Float = bottom - top
+
+    operator fun minus(position: ViewPosition) =
+        ShadeScrimBounds(
+            left = left - position.left,
+            top = top - position.top,
+            right = right - position.left,
+            bottom = bottom - position.top,
+        )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimClipping.kt
similarity index 80%
copy from packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
copy to packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimClipping.kt
index 0c92b50..e86fd1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimClipping.kt
@@ -16,5 +16,8 @@
 
 package com.android.systemui.statusbar.notification.stack.shared.model
 
-/** Models the clipping rounded rectangle of the notification stack */
-data class StackClipping(val bounds: StackBounds, val rounding: StackRounding)
+/** Models the clipping rounded rectangle of the notification stack, where the rounding is binary */
+data class ShadeScrimClipping(
+    val bounds: ShadeScrimBounds = ShadeScrimBounds(),
+    val rounding: ShadeScrimRounding = ShadeScrimRounding()
+)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackRounding.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimRounding.kt
similarity index 88%
rename from packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackRounding.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimRounding.kt
index ddc5d7ea..9d4231c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackRounding.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimRounding.kt
@@ -17,9 +17,9 @@
 package com.android.systemui.statusbar.notification.stack.shared.model
 
 /** Models the corner rounds of the notification stack. */
-data class StackRounding(
+data class ShadeScrimRounding(
     /** Whether the top corners of the notification stack should be rounded. */
-    val roundTop: Boolean = false,
+    val isTopRounded: Boolean = false,
     /** Whether the bottom corners of the notification stack should be rounded. */
-    val roundBottom: Boolean = false,
+    val isBottomRounded: Boolean = false,
 )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimShape.kt
similarity index 74%
copy from packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
copy to packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimShape.kt
index 0c92b50..e6f0647 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ShadeScrimShape.kt
@@ -16,5 +16,11 @@
 
 package com.android.systemui.statusbar.notification.stack.shared.model
 
-/** Models the clipping rounded rectangle of the notification stack */
-data class StackClipping(val bounds: StackBounds, val rounding: StackRounding)
+/** Models the clipping rounded rectangle of the notification stack, with corner radii in px */
+data class ShadeScrimShape(
+    val bounds: ShadeScrimBounds = ShadeScrimBounds(),
+    /** radius in px of the top corners */
+    val topRadius: Int,
+    /** radius in px of the bottom corners */
+    val bottomRadius: Int,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ViewPosition.kt
similarity index 81%
rename from packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ViewPosition.kt
index 0c92b50..5d2b0ad2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/ViewPosition.kt
@@ -16,5 +16,5 @@
 
 package com.android.systemui.statusbar.notification.stack.shared.model
 
-/** Models the clipping rounded rectangle of the notification stack */
-data class StackClipping(val bounds: StackBounds, val rounding: StackRounding)
+/** An offset of view, used to adjust bounds. */
+data class ViewPosition(val left: Int = 0, val top: Int = 0)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt
new file mode 100644
index 0000000..ac00d3b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.stack.ui.view
+
+import android.view.View
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape
+import java.util.function.Consumer
+
+/**
+ * This view (interface) is the view which scrolls and positions the heads up notification and
+ * notification stack, but is otherwise agnostic to the content.
+ */
+interface NotificationScrollView {
+    /**
+     * Since this is an interface rather than a literal View, this provides cast-like access to the
+     * underlying view.
+     */
+    fun asView(): View
+
+    /** Set the clipping bounds used when drawing */
+    fun setScrimClippingShape(shape: ShadeScrimShape?)
+
+    /** set the y position in px of the top of the stack in this view's coordinates */
+    fun setStackTop(stackTop: Float)
+
+    /** set the y position in px of the bottom of the stack in this view's coordinates */
+    fun setStackBottom(stackBottom: Float)
+
+    /** set the y position in px of the top of the HUN in this view's coordinates */
+    fun setHeadsUpTop(headsUpTop: Float)
+
+    /** set whether the view has been scrolled all the way to the top */
+    fun setScrolledToTop(scrolledToTop: Boolean)
+
+    /** Set a consumer for synthetic scroll events */
+    fun setSyntheticScrollConsumer(consumer: Consumer<Float>?)
+    /** Set a consumer for stack height changed events */
+    fun setStackHeightConsumer(consumer: Consumer<Float>?)
+    /** Set a consumer for heads up height changed events */
+    fun setHeadsUpHeightConsumer(consumer: Consumer<Float>?)
+
+    /** sets that scrolling is allowed */
+    fun setScrollingEnabled(enabled: Boolean)
+
+    /** sets the current expand fraction */
+    fun setExpandFraction(expandFraction: Float)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt
new file mode 100644
index 0000000..a98717a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.stack.ui.viewbinder
+
+import android.view.View
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.common.ui.ConfigurationState
+import com.android.systemui.common.ui.view.onLayoutChanged
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.notification.stack.shared.model.ViewPosition
+import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
+import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationScrollViewModel
+import com.android.systemui.util.kotlin.FlowDumperImpl
+import com.android.systemui.util.kotlin.launchAndDispose
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.DisposableHandle
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+/** Binds the [NotificationScrollView]. */
+@SysUISingleton
+class NotificationScrollViewBinder
+@Inject
+constructor(
+    dumpManager: DumpManager,
+    @Main private val mainImmediateDispatcher: CoroutineDispatcher,
+    private val view: NotificationScrollView,
+    private val viewModel: NotificationScrollViewModel,
+    private val configuration: ConfigurationState,
+) : FlowDumperImpl(dumpManager) {
+
+    private val viewPosition = MutableStateFlow(ViewPosition()).dumpValue("viewPosition")
+    private val viewTopOffset = viewPosition.map { it.top }.distinctUntilChanged()
+
+    fun bindWhileAttached(): DisposableHandle {
+        return view.asView().repeatWhenAttached(mainImmediateDispatcher) {
+            repeatOnLifecycle(Lifecycle.State.CREATED) { bind() }
+        }
+    }
+
+    suspend fun bind() = coroutineScope {
+        launchAndDispose {
+            viewPosition.value = view.asView().position
+            view.asView().onLayoutChanged { viewPosition.value = it.position }
+        }
+
+        launch {
+            viewModel.shadeScrimShape(scrimRadius, viewPosition).collect {
+                view.setScrimClippingShape(it)
+            }
+        }
+
+        launch { viewModel.stackTop.minusTopOffset().collect { view.setStackTop(it) } }
+        launch { viewModel.stackBottom.minusTopOffset().collect { view.setStackBottom(it) } }
+        launch { viewModel.scrolledToTop.collect { view.setScrolledToTop(it) } }
+        launch { viewModel.headsUpTop.minusTopOffset().collect { view.setHeadsUpTop(it) } }
+        launch { viewModel.expandFraction.collect { view.setExpandFraction(it) } }
+        launch { viewModel.isScrollable.collect { view.setScrollingEnabled(it) } }
+
+        launchAndDispose {
+            view.setSyntheticScrollConsumer(viewModel.syntheticScrollConsumer)
+            view.setStackHeightConsumer(viewModel.stackHeightConsumer)
+            view.setHeadsUpHeightConsumer(viewModel.headsUpHeightConsumer)
+            DisposableHandle {
+                view.setSyntheticScrollConsumer(null)
+                view.setStackHeightConsumer(null)
+                view.setHeadsUpHeightConsumer(null)
+            }
+        }
+    }
+
+    /** Combine with the topOffset flow and subtract that value from this flow's value */
+    private fun Flow<Float>.minusTopOffset() =
+        combine(viewTopOffset) { y, topOffset -> y - topOffset }
+
+    /** flow of the scrim clipping radius */
+    private val scrimRadius: Flow<Int>
+        get() = configuration.getDimensionPixelOffset(R.dimen.notification_scrim_corner_radius)
+
+    /** Construct a [ViewPosition] from this view using [View.getLeft] and [View.getTop] */
+    private val View.position
+        get() = ViewPosition(left = left, top = top)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackViewBinder.kt
deleted file mode 100644
index 1a34bb4..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationStackViewBinder.kt
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.stack.ui.viewbinder
-
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.repeatOnLifecycle
-import com.android.systemui.common.ui.ConfigurationState
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.lifecycle.repeatWhenAttached
-import com.android.systemui.res.R
-import com.android.systemui.statusbar.notification.stack.AmbientState
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
-import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationStackAppearanceViewModel
-import javax.inject.Inject
-import kotlin.math.roundToInt
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.DisposableHandle
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.launch
-
-/** Binds the NSSL/Controller/AmbientState to their ViewModel. */
-@SysUISingleton
-class NotificationStackViewBinder
-@Inject
-constructor(
-    @Main private val mainImmediateDispatcher: CoroutineDispatcher,
-    private val ambientState: AmbientState,
-    private val view: NotificationStackScrollLayout,
-    private val controller: NotificationStackScrollLayoutController,
-    private val viewModel: NotificationStackAppearanceViewModel,
-    private val configuration: ConfigurationState,
-) {
-
-    fun bindWhileAttached(): DisposableHandle {
-        return view.repeatWhenAttached(mainImmediateDispatcher) {
-            repeatOnLifecycle(Lifecycle.State.CREATED) { bind() }
-        }
-    }
-
-    suspend fun bind() = coroutineScope {
-        launch {
-            combine(viewModel.stackClipping, clipRadius, ::Pair).collect { (clipping, clipRadius) ->
-                val (bounds, rounding) = clipping
-                val viewLeft = controller.view.left
-                val viewTop = controller.view.top
-                controller.setRoundedClippingBounds(
-                    bounds.left.roundToInt() - viewLeft,
-                    bounds.top.roundToInt() - viewTop,
-                    bounds.right.roundToInt() - viewLeft,
-                    bounds.bottom.roundToInt() - viewTop,
-                    if (rounding.roundTop) clipRadius else 0,
-                    if (rounding.roundBottom) clipRadius else 0,
-                )
-            }
-        }
-
-        launch {
-            viewModel.contentTop.collect {
-                controller.updateTopPadding(it, controller.isAddOrRemoveAnimationPending)
-            }
-        }
-
-        launch {
-            var wasExpanding = false
-            viewModel.expandFraction.collect { expandFraction ->
-                val nowExpanding = expandFraction != 0f && expandFraction != 1f
-                if (nowExpanding && !wasExpanding) {
-                    controller.onExpansionStarted()
-                }
-                ambientState.expansionFraction = expandFraction
-                controller.expandedHeight = expandFraction * controller.view.height
-                if (!nowExpanding && wasExpanding) {
-                    controller.onExpansionStopped()
-                }
-                wasExpanding = nowExpanding
-            }
-        }
-
-        launch { viewModel.isScrollable.collect { controller.setScrollingEnabled(it) } }
-    }
-
-    private val clipRadius: Flow<Int>
-        get() = configuration.getDimensionPixelOffset(R.dimen.notification_scrim_corner_radius)
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
index 4a096a8..cfd19ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/SharedNotificationContainerBinder.kt
@@ -49,7 +49,7 @@
     private val sceneContainerFlags: SceneContainerFlags,
     private val controller: NotificationStackScrollLayoutController,
     private val notificationStackSizeCalculator: NotificationStackSizeCalculator,
-    private val notificationStackViewBinder: NotificationStackViewBinder,
+    private val notificationScrollViewBinder: NotificationScrollViewBinder,
     @Main private val mainImmediateDispatcher: CoroutineDispatcher,
 ) {
 
@@ -162,7 +162,7 @@
             }
 
         if (sceneContainerFlags.isEnabled()) {
-            disposables += notificationStackViewBinder.bindWhileAttached()
+            disposables += notificationScrollViewBinder.bindWhileAttached()
         }
 
         controller.setOnHeightChangedRunnable { viewModel.notificationStackChanged() }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationStackAppearanceViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
similarity index 61%
rename from packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationStackAppearanceViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
index a7cbc33..9483f33 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationStackAppearanceViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
@@ -19,29 +19,27 @@
 
 import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.scene.domain.interactor.SceneInteractor
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.scene.shared.model.Scenes.Shade
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
-import com.android.systemui.statusbar.notification.stack.shared.model.StackClipping
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimClipping
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimShape
+import com.android.systemui.statusbar.notification.stack.shared.model.ViewPosition
 import com.android.systemui.util.kotlin.FlowDumperImpl
 import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.map
 
 /** ViewModel which represents the state of the NSSL/Controller in the world of flexiglass */
 @SysUISingleton
-class NotificationStackAppearanceViewModel
+class NotificationScrollViewModel
 @Inject
 constructor(
-    @Application applicationScope: CoroutineScope,
     dumpManager: DumpManager,
     stackAppearanceInteractor: NotificationStackAppearanceInteractor,
     shadeInteractor: ShadeInteractor,
@@ -83,16 +81,48 @@
             .dumpWhileCollecting("expandFraction")
 
     /** The bounds of the notification stack in the current scene. */
-    val stackClipping: Flow<StackClipping> =
+    private val shadeScrimClipping: Flow<ShadeScrimClipping?> =
         combine(
-                stackAppearanceInteractor.stackBounds,
-                stackAppearanceInteractor.stackRounding,
-                ::StackClipping
-            )
+                stackAppearanceInteractor.shadeScrimBounds,
+                stackAppearanceInteractor.shadeScrimRounding,
+            ) { bounds, rounding ->
+                bounds?.let { ShadeScrimClipping(it, rounding) }
+            }
             .dumpWhileCollecting("stackClipping")
 
+    fun shadeScrimShape(
+        cornerRadius: Flow<Int>,
+        viewPosition: Flow<ViewPosition>
+    ): Flow<ShadeScrimShape?> =
+        combine(shadeScrimClipping, cornerRadius, viewPosition) { clipping, radius, position ->
+                if (clipping == null) return@combine null
+                ShadeScrimShape(
+                    bounds = clipping.bounds - position,
+                    topRadius = radius.takeIf { clipping.rounding.isTopRounded } ?: 0,
+                    bottomRadius = radius.takeIf { clipping.rounding.isBottomRounded } ?: 0
+                )
+            }
+            .dumpWhileCollecting("shadeScrimShape")
+
     /** The y-coordinate in px of top of the contents of the notification stack. */
-    val contentTop: StateFlow<Float> = stackAppearanceInteractor.contentTop.dumpValue("contentTop")
+    val stackTop: Flow<Float> = stackAppearanceInteractor.stackTop.dumpValue("stackTop")
+    /** The y-coordinate in px of bottom of the contents of the notification stack. */
+    val stackBottom: Flow<Float> = stackAppearanceInteractor.stackBottom.dumpValue("stackBottom")
+    /**
+     * Whether the notification stack is scrolled to the top; i.e., it cannot be scrolled down any
+     * further.
+     */
+    val scrolledToTop: Flow<Boolean> =
+        stackAppearanceInteractor.scrolledToTop.dumpValue("scrolledToTop")
+    /** The y-coordinate in px of bottom of the contents of the HUN. */
+    val headsUpTop: Flow<Float> = stackAppearanceInteractor.headsUpTop.dumpValue("headsUpTop")
+
+    /** Receives the amount (px) that the stack should scroll due to internal expansion. */
+    val syntheticScrollConsumer: (Float) -> Unit = stackAppearanceInteractor::setSyntheticScroll
+    /** Receives the height of the contents of the notification stack. */
+    val stackHeightConsumer: (Float) -> Unit = stackAppearanceInteractor::setStackHeight
+    /** Receives the height of the heads up notification. */
+    val headsUpHeightConsumer: (Float) -> Unit = stackAppearanceInteractor::setHeadsUpHeight
 
     /** Whether the notification stack is scrollable or not. */
     val isScrollable: Flow<Boolean> =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
index bd83121..b284179 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModel.kt
@@ -18,16 +18,19 @@
 
 import com.android.systemui.common.shared.model.NotificationContainerBounds
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.flags.FeatureFlagsClassic
 import com.android.systemui.flags.Flags
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.scene.shared.flag.SceneContainerFlags
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
-import com.android.systemui.statusbar.notification.stack.shared.model.StackBounds
-import com.android.systemui.statusbar.notification.stack.shared.model.StackRounding
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimBounds
+import com.android.systemui.statusbar.notification.stack.shared.model.ShadeScrimRounding
+import com.android.systemui.util.kotlin.FlowDumperImpl
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
 
 /**
  * ViewModel used by the Notification placeholders inside the scene container to update the
@@ -37,67 +40,72 @@
 class NotificationsPlaceholderViewModel
 @Inject
 constructor(
+    dumpManager: DumpManager,
     private val interactor: NotificationStackAppearanceInteractor,
     shadeInteractor: ShadeInteractor,
     flags: SceneContainerFlags,
     featureFlags: FeatureFlagsClassic,
     private val keyguardInteractor: KeyguardInteractor,
-) {
+) : FlowDumperImpl(dumpManager) {
     /** DEBUG: whether the placeholder should be made slightly visible for positional debugging. */
     val isVisualDebuggingEnabled: Boolean = featureFlags.isEnabled(Flags.NSSL_DEBUG_LINES)
 
     /** DEBUG: whether the debug logging should be output. */
     val isDebugLoggingEnabled: Boolean = flags.isEnabled()
 
-    /**
-     * Notifies that the bounds of the notification placeholder have changed.
-     *
-     * @param top The position of the top of the container in its window coordinate system, in
-     *   pixels.
-     * @param bottom The position of the bottom of the container in its window coordinate system, in
-     *   pixels.
-     */
-    fun onBoundsChanged(
-        left: Float,
+    /** Notifies that the bounds of the notification scrim have changed. */
+    fun onScrimBoundsChanged(bounds: ShadeScrimBounds?) {
+        interactor.setShadeScrimBounds(bounds)
+    }
+
+    /** Notifies that the bounds of the notification placeholder have changed. */
+    fun onStackBoundsChanged(
         top: Float,
-        right: Float,
         bottom: Float,
     ) {
         keyguardInteractor.setNotificationContainerBounds(
             NotificationContainerBounds(top = top, bottom = bottom)
         )
-        interactor.setStackBounds(
-            StackBounds(top = top, bottom = bottom, left = left, right = right)
-        )
+        interactor.setStackTop(top)
+        interactor.setStackBottom(bottom)
+    }
+
+    /** Sets the available space */
+    fun onConstrainedAvailableSpaceChanged(height: Int) {
+        interactor.setConstrainedAvailableSpace(height)
+    }
+
+    fun onHeadsUpTopChanged(headsUpTop: Float) {
+        interactor.setHeadsUpTop(headsUpTop)
     }
 
     /** Corner rounding of the stack */
-    val stackRounding: Flow<StackRounding> = interactor.stackRounding
+    val shadeScrimRounding: Flow<ShadeScrimRounding> =
+        interactor.shadeScrimRounding.dumpWhileCollecting("shadeScrimRounding")
 
     /**
      * The height in px of the contents of notification stack. Depending on the number of
      * notifications, this can exceed the space available on screen to show notifications, at which
      * point the notification stack should become scrollable.
      */
-    val intrinsicContentHeight = interactor.intrinsicContentHeight
+    val stackHeight: StateFlow<Float> = interactor.stackHeight.dumpValue("stackHeight")
+
+    /** The height in px of the contents of the HUN. */
+    val headsUpHeight: StateFlow<Float> = interactor.headsUpHeight.dumpValue("headsUpHeight")
 
     /**
      * The amount [0-1] that the shade has been opened. At 0, the shade is closed; at 1, the shade
      * is open.
      */
-    val expandFraction: Flow<Float> = shadeInteractor.shadeExpansion
+    val expandFraction: Flow<Float> = shadeInteractor.shadeExpansion.dumpValue("expandFraction")
 
     /**
      * The amount in px that the notification stack should scroll due to internal expansion. This
      * should only happen when a notification expansion hits the bottom of the screen, so it is
      * necessary to scroll up to keep expanding the notification.
      */
-    val syntheticScroll: Flow<Float> = interactor.syntheticScroll
-
-    /** Sets the y-coord in px of the top of the contents of the notification stack. */
-    fun onContentTopChanged(padding: Float) {
-        interactor.setContentTop(padding)
-    }
+    val syntheticScroll: Flow<Float> =
+        interactor.syntheticScroll.dumpWhileCollecting("syntheticScroll")
 
     /** Sets whether the notification stack is scrolled to the top. */
     fun setScrolledToTop(scrolledToTop: Boolean) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 9f57606..692368d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -60,7 +60,9 @@
 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToLockscreenTransitionViewModel
 import com.android.systemui.keyguard.ui.viewmodel.ViewStateAccessor
+import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
 import com.android.systemui.util.kotlin.BooleanFlowOperators.and
 import com.android.systemui.util.kotlin.BooleanFlowOperators.or
@@ -97,6 +99,7 @@
     private val keyguardInteractor: KeyguardInteractor,
     private val keyguardTransitionInteractor: KeyguardTransitionInteractor,
     private val shadeInteractor: ShadeInteractor,
+    private val notificationStackAppearanceInteractor: NotificationStackAppearanceInteractor,
     private val alternateBouncerToGoneTransitionViewModel:
         AlternateBouncerToGoneTransitionViewModel,
     private val aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel,
@@ -364,6 +367,10 @@
                 initialValue = NotificationContainerBounds(),
             )
             .dumpValue("bounds")
+        get() {
+            /* check if */ SceneContainerFlag.isUnexpectedlyInLegacyMode()
+            return field
+        }
 
     /**
      * Ensure view is visible when the shade/qs are expanded. Also, as QS is expanding, fade out
@@ -571,8 +578,11 @@
             .dumpWhileCollecting("translationX")
 
     private val availableHeight: Flow<Float> =
-        bounds
-            .map { it.bottom - it.top }
+        if (SceneContainerFlag.isEnabled) {
+                notificationStackAppearanceInteractor.constrainedAvailableSpace.map { it.toFloat() }
+            } else {
+                bounds.map { it.bottom - it.top }
+            }
             .distinctUntilChanged()
             .dumpWhileCollecting("availableHeight")
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 2798dbf..5baf6a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -28,7 +28,6 @@
 import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
 import static com.android.systemui.Flags.lightRevealMigration;
 import static com.android.systemui.Flags.newAodTransition;
-import static com.android.systemui.Flags.predictiveBackSysui;
 import static com.android.systemui.Flags.truncatedStatusBarIconsFix;
 import static com.android.systemui.charging.WirelessChargingAnimation.UNKNOWN_BATTERY_LEVEL;
 import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
@@ -837,7 +836,7 @@
         mLightRevealScrimViewModelLazy = lightRevealScrimViewModelLazy;
         mLightRevealScrim = lightRevealScrim;
 
-        if (predictiveBackSysui()) {
+        if (PredictiveBackSysUiFlag.isEnabled()) {
             mContext.getApplicationInfo().setEnableOnBackInvokedCallback(true);
         }
     }
@@ -3061,7 +3060,7 @@
         public void onConfigChanged(Configuration newConfig) {
             updateResources();
             updateDisplaySize(); // populates mDisplayMetrics
-            if (predictiveBackSysui()) {
+            if (PredictiveBackSysUiFlag.isEnabled()) {
                 mContext.getApplicationInfo().setEnableOnBackInvokedCallback(true);
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
index 82b10bc..eadb7f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt
@@ -23,12 +23,12 @@
 import android.widget.FrameLayout
 import androidx.annotation.StringRes
 import com.android.keyguard.LockIconViewController
-import com.android.systemui.res.R
 import com.android.systemui.keyguard.ui.binder.KeyguardBottomAreaViewBinder
 import com.android.systemui.keyguard.ui.binder.KeyguardBottomAreaViewBinder.bind
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.res.R
 import com.android.systemui.statusbar.VibratorHelper
 
 /**
@@ -155,13 +155,13 @@
                 // make top of ambient indication view the bottom of the lock icon
                 it.layout(
                     ambientLeft,
-                    lockIconViewController?.bottom?.toInt() ?: 0,
+                    lockIconViewController?.getBottom()?.toInt() ?: 0,
                     right - ambientLeft,
                     ambientTop + it.measuredHeight
                 )
             } else {
                 // make bottom of ambient indication view the top of the lock icon
-                val lockLocationTop = lockIconViewController?.top ?: 0
+                val lockLocationTop = lockIconViewController?.getTop() ?: 0
                 it.layout(
                     ambientLeft,
                     lockLocationTop.toInt() - it.measuredHeight,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PredictiveBackSysUiFlag.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PredictiveBackSysUiFlag.kt
new file mode 100644
index 0000000..74d6ba5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PredictiveBackSysUiFlag.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone
+
+import com.android.systemui.Flags
+import com.android.systemui.flags.FlagToken
+import com.android.systemui.flags.RefactorFlagUtils
+
+/** Helper for reading or using the predictive back flag state. */
+@Suppress("NOTHING_TO_INLINE")
+object PredictiveBackSysUiFlag {
+    /** The aconfig flag name */
+    const val FLAG_NAME = Flags.FLAG_PREDICTIVE_BACK_SYSUI
+
+    /** A token used for dependency declaration */
+    val token: FlagToken
+        get() = FlagToken(FLAG_NAME, isEnabled)
+
+    /** Is the refactor enabled */
+    @JvmStatic
+    inline val isEnabled
+        get() = Flags.predictiveBackSysui()
+
+    /**
+     * Called to ensure code is only run when the flag is enabled. This protects users from the
+     * unintended behaviors caused by accidentally running new logic, while also crashing on an eng
+     * build to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun isUnexpectedlyInLegacyMode() =
+        RefactorFlagUtils.isUnexpectedlyInLegacyMode(isEnabled, FLAG_NAME)
+
+    /**
+     * Called to ensure code is only run when the flag is disabled. This will throw an exception if
+     * the flag is enabled to ensure that the refactor author catches issues in testing.
+     */
+    @JvmStatic
+    inline fun assertInLegacyMode() = RefactorFlagUtils.assertInLegacyMode(isEnabled, FLAG_NAME)
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index afd2415..5f26702 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -662,7 +662,12 @@
          * show if any subsequent events are to be handled.
          */
         if (beginShowingBouncer(event)) {
-            mPrimaryBouncerInteractor.show(/* isScrimmed= */false);
+            if (SceneContainerFlag.isEnabled()) {
+                mSceneInteractorLazy.get().changeScene(
+                        Scenes.Bouncer, "StatusBarKeyguardViewManager.onPanelExpansionChanged");
+            } else {
+                mPrimaryBouncerInteractor.show(/* isScrimmed= */false);
+            }
         }
 
         if (!primaryBouncerIsOrWillBeShowing()) {
@@ -716,7 +721,12 @@
             // The keyguard might be showing (already). So we need to hide it.
             if (!primaryBouncerIsShowing()) {
                 mCentralSurfaces.hideKeyguard();
-                mPrimaryBouncerInteractor.show(true);
+                if (SceneContainerFlag.isEnabled()) {
+                    mSceneInteractorLazy.get().changeScene(
+                            Scenes.Bouncer, "StatusBarKeyguardViewManager.showBouncerOrKeyguard");
+                } else {
+                    mPrimaryBouncerInteractor.show(/* isScrimmed= */ true);
+                }
             } else {
                 Log.e(TAG, "Attempted to show the sim bouncer when it is already showing.");
             }
@@ -778,7 +788,12 @@
     public void showPrimaryBouncer(boolean scrimmed) {
         hideAlternateBouncer(false);
         if (mKeyguardStateController.isShowing() && !isBouncerShowing()) {
-            mPrimaryBouncerInteractor.show(scrimmed);
+            if (SceneContainerFlag.isEnabled()) {
+                mSceneInteractorLazy.get().changeScene(
+                        Scenes.Bouncer, "StatusBarKeyguardViewManager.showPrimaryBouncer");
+            } else {
+                mPrimaryBouncerInteractor.show(scrimmed);
+            }
         }
         updateStates();
     }
@@ -873,13 +888,23 @@
                 if (afterKeyguardGone) {
                     // we'll handle the dismiss action after keyguard is gone, so just show the
                     // bouncer
-                    mPrimaryBouncerInteractor.show(/* isScrimmed= */true);
+                    if (SceneContainerFlag.isEnabled()) {
+                        mSceneInteractorLazy.get().changeScene(
+                                Scenes.Bouncer, "StatusBarKeyguardViewManager.dismissWithAction");
+                    } else {
+                        mPrimaryBouncerInteractor.show(/* isScrimmed= */ true);
+                    }
                 } else {
                     // after authentication success, run dismiss action with the option to defer
                     // hiding the keyguard based on the return value of the OnDismissAction
                     mPrimaryBouncerInteractor.setDismissAction(
                             mAfterKeyguardGoneAction, mKeyguardGoneCancelAction);
-                    mPrimaryBouncerInteractor.show(/* isScrimmed= */true);
+                    if (SceneContainerFlag.isEnabled()) {
+                        mSceneInteractorLazy.get().changeScene(
+                                Scenes.Bouncer, "StatusBarKeyguardViewManager.dismissWithAction");
+                    } else {
+                        mPrimaryBouncerInteractor.show(/* isScrimmed= */ true);
+                    }
                     // bouncer will handle the dismiss action, so we no longer need to track it here
                     mAfterKeyguardGoneAction = null;
                     mKeyguardGoneCancelAction = null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 82d9fc7..2a921dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -42,6 +42,7 @@
 import android.view.WindowManager.LayoutParams;
 
 import androidx.annotation.Nullable;
+import androidx.annotation.StyleRes;
 
 import com.android.systemui.Dependency;
 import com.android.systemui.animation.DialogTransitionAnimator;
@@ -71,7 +72,7 @@
  * and dismisses itself when it receives the broadcast.
  */
 public class SystemUIDialog extends AlertDialog implements ViewRootImpl.ConfigChangedCallback {
-    protected static final int DEFAULT_THEME = R.style.Theme_SystemUI_Dialog;
+    public static final int DEFAULT_THEME = R.style.Theme_SystemUI_Dialog;
     // TODO(b/203389579): Remove this once the dialog width on large screens has been agreed on.
     private static final String FLAG_TABLET_DIALOG_WIDTH =
             "persist.systemui.flag_tablet_dialog_width";
@@ -141,7 +142,7 @@
          * When you just need a dialog, call this.
          */
         public SystemUIDialog create() {
-            return create(new DialogDelegate<>(){}, mContext);
+            return create(new DialogDelegate<>(){}, mContext, DEFAULT_THEME);
         }
 
         /** Creates a new instance of {@link SystemUIDialog} with no customized behavior.
@@ -149,7 +150,7 @@
          * When you just need a dialog created with a specific {@link Context}, call this.
          */
         public SystemUIDialog create(Context context) {
-            return create(new DialogDelegate<>(){}, context);
+            return create(new DialogDelegate<>(){}, context, DEFAULT_THEME);
         }
 
         /**
@@ -159,7 +160,10 @@
          * When you need to customize the dialog, pass it a delegate.
          */
         public SystemUIDialog create(Delegate delegate, Context context) {
-            return create((DialogDelegate<SystemUIDialog>) delegate, context);
+            return create(delegate, context, DEFAULT_THEME);
+        }
+        public SystemUIDialog create(Delegate delegate, Context context, @StyleRes int theme) {
+            return create((DialogDelegate<SystemUIDialog>) delegate, context, theme);
         }
 
         public SystemUIDialog create(Delegate delegate) {
@@ -167,10 +171,10 @@
         }
 
         private SystemUIDialog create(DialogDelegate<SystemUIDialog> dialogDelegate,
-                Context context) {
+                Context context, @StyleRes int theme) {
             return new SystemUIDialog(
                     context,
-                    DEFAULT_THEME,
+                    theme,
                     DEFAULT_DISMISS_ON_DEVICE_LOCK,
                     mSystemUIDialogManager,
                     mSysUiState,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/airplane/domain/interactor/AirplaneModeInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/airplane/domain/interactor/AirplaneModeInteractor.kt
index c6c8823..684e38e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/airplane/domain/interactor/AirplaneModeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/airplane/domain/interactor/AirplaneModeInteractor.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.map
 
 /**
@@ -40,7 +41,7 @@
     private val mobileConnectionsRepository: MobileConnectionsRepository,
 ) {
     /** True if the device is currently in airplane mode. */
-    val isAirplaneMode: Flow<Boolean> = airplaneModeRepository.isAirplaneMode
+    val isAirplaneMode: StateFlow<Boolean> = airplaneModeRepository.isAirplaneMode
 
     /** True if we're configured to force-hide the airplane mode icon and false otherwise. */
     val isForceHidden: Flow<Boolean> =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/model/SignalIconModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/model/SignalIconModel.kt
index d6b8fd4..5d3b9ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/model/SignalIconModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/model/SignalIconModel.kt
@@ -94,7 +94,8 @@
         }
 
         override fun logFully(row: TableRowLogger) {
-            row.logChange("numLevels", "HELLO")
+            // Satellite icon has only 3 levels, unchanging
+            row.logChange(COL_NUM_LEVELS, "3")
             row.logChange(COL_TYPE, "s")
             row.logChange(COL_LEVEL, level)
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
index 3f89d04b..08ed030 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractor.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
 import com.android.systemui.statusbar.pipeline.satellite.data.DeviceBasedSatelliteRepository
 import com.android.systemui.statusbar.pipeline.satellite.shared.model.SatelliteConnectionState
+import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -39,6 +40,7 @@
 constructor(
     val repo: DeviceBasedSatelliteRepository,
     iconsInteractor: MobileIconsInteractor,
+    deviceProvisioningInteractor: DeviceProvisioningInteractor,
     @Application scope: CoroutineScope,
 ) {
     /** Must be observed by any UI showing Satellite iconography */
@@ -69,6 +71,8 @@
             }
             .stateIn(scope, SharingStarted.WhileSubscribed(), 0)
 
+    val isDeviceProvisioned: Flow<Boolean> = deviceProvisioningInteractor.isDeviceProvisioned
+
     /** When all connections are considered OOS, satellite connectivity is potentially valid */
     val areAllConnectionsOutOfService =
         if (Flags.oemEnabledSatelliteFlag()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
index bef6b0b..40641be 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModel.kt
@@ -56,10 +56,12 @@
             if (!allOos) {
                 flowOf(false)
             } else {
-                combine(interactor.isSatelliteAllowed, airplaneModeRepository.isAirplaneMode) {
-                    isSatelliteAllowed,
-                    isAirplaneMode ->
-                    isSatelliteAllowed && !isAirplaneMode
+                combine(
+                    interactor.isSatelliteAllowed,
+                    interactor.isDeviceProvisioned,
+                    airplaneModeRepository.isAirplaneMode
+                ) { isSatelliteAllowed, isDeviceProvisioned, isAirplaneMode ->
+                    isSatelliteAllowed && isDeviceProvisioned && !isAirplaneMode
                 }
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
index 55a0f59..9cdecef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/AvalancheController.kt
@@ -17,9 +17,12 @@
 
 import android.util.Log
 import androidx.annotation.VisibleForTesting
+import com.android.systemui.Dumpable
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dump.DumpManager
 import com.android.systemui.statusbar.notification.shared.NotificationThrottleHun
 import com.android.systemui.statusbar.policy.BaseHeadsUpManager.HeadsUpEntry
+import java.io.PrintWriter
 import javax.inject.Inject
 
 /*
@@ -27,7 +30,9 @@
  * succession, by delaying visual listener side effects and removal handling from BaseHeadsUpManager
  */
 @SysUISingleton
-class AvalancheController @Inject constructor() {
+class AvalancheController @Inject constructor(
+    dumpManager: DumpManager,
+) : Dumpable {
 
     private val tag = "AvalancheController"
     private val debug = false
@@ -54,22 +59,26 @@
     // For debugging only
     @VisibleForTesting var debugDropSet: MutableSet<HeadsUpEntry> = HashSet()
 
-    /**
-     * Run or delay Runnable for given HeadsUpEntry
-     */
-    fun update(entry: HeadsUpEntry, runnable: Runnable, label: String) {
+    init {
+        dumpManager.registerNormalDumpable(tag, /* module */ this)
+    }
+
+    /** Run or delay Runnable for given HeadsUpEntry */
+    fun update(entry: HeadsUpEntry?, runnable: Runnable, label: String) {
         if (!NotificationThrottleHun.isEnabled) {
             runnable.run()
             return
         }
         val fn = "[$label] => AvalancheController.update ${getKey(entry)}"
-
+        if (entry == null) {
+            log { "Entry is NULL, stop update." }
+            return;
+        }
         if (debug) {
             debugRunnableLabelMap[runnable] = label
         }
-
         if (isShowing(entry)) {
-            log {"$fn => [update showing]" }
+            log { "$fn => [update showing]" }
             runnable.run()
         } else if (entry in nextMap) {
             log { "$fn => [update next]" }
@@ -164,9 +173,7 @@
         }
     }
 
-    /**
-     * Return true if entry is waiting to show.
-     */
+    /** Return true if entry is waiting to show. */
     fun isWaiting(key: String): Boolean {
         if (!NotificationThrottleHun.isEnabled) {
             return false
@@ -179,9 +186,7 @@
         return false
     }
 
-    /**
-     * Return list of keys for huns waiting
-     */
+    /** Return list of keys for huns waiting */
     fun getWaitingKeys(): MutableList<String> {
         if (!NotificationThrottleHun.isEnabled) {
             return mutableListOf()
@@ -254,12 +259,15 @@
         }
     }
 
-    // TODO(b/315362456) expose as dumpable for bugreports
+    private fun getStateStr(): String {
+        return "SHOWING: ${getKey(headsUpEntryShowing)}" +
+            "\tNEXT LIST: $nextListStr\tMAP: $nextMapStr" +
+            "\tDROP: $dropSetStr"
+    }
+
     private fun logState(reason: String) {
-        log { "state $reason" }
-        log { "showing: " + getKey(headsUpEntryShowing) }
-        log { "next list: $nextListStr map: $nextMapStr" }
-        log { "drop: $dropSetStr" }
+        log { "REASON $reason" }
+        log { getStateStr() }
     }
 
     private val dropSetStr: String
@@ -298,4 +306,8 @@
         }
         return entry.mEntry!!.key
     }
+
+    override fun dump(pw: PrintWriter, args: Array<out String>) {
+        pw.println("AvalancheController: ${getStateStr()}")
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
index 20a82a4..d99af2d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
@@ -165,6 +165,8 @@
     public void showNotification(@NonNull NotificationEntry entry) {
         HeadsUpEntry headsUpEntry = createHeadsUpEntry(entry);
 
+        mLogger.logShowNotificationRequest(entry);
+
         Runnable runnable = () -> {
             // TODO(b/315362456) log outside runnable too
             mLogger.logShowNotification(entry);
@@ -219,6 +221,8 @@
      */
     public void updateNotification(@NonNull String key, boolean shouldHeadsUpAgain) {
         HeadsUpEntry headsUpEntry = mHeadsUpEntryMap.get(key);
+        mLogger.logUpdateNotificationRequest(key, shouldHeadsUpAgain, headsUpEntry != null);
+
         Runnable runnable = () -> {
             updateNotificationInternal(key, shouldHeadsUpAgain);
         };
@@ -378,8 +382,11 @@
      */
     protected final void removeEntry(@NonNull String key) {
         HeadsUpEntry headsUpEntry = mHeadsUpEntryMap.get(key);
+        mLogger.logRemoveEntryRequest(key);
 
         Runnable runnable = () -> {
+            mLogger.logRemoveEntry(key);
+
             if (headsUpEntry == null) {
                 return;
             }
@@ -566,8 +573,10 @@
     public void unpinAll(boolean userUnPinned) {
         for (String key : mHeadsUpEntryMap.keySet()) {
             HeadsUpEntry headsUpEntry = getHeadsUpEntry(key);
-
+            mLogger.logUnpinEntryRequest(key);
             Runnable runnable = () -> {
+                mLogger.logUnpinEntry(key);
+
                 setEntryPinned(headsUpEntry, false /* isPinned */);
                 // maybe it got un sticky
                 headsUpEntry.updateEntry(false /* updatePostTime */, "unpinAll");
@@ -886,6 +895,7 @@
          * Clear any pending removal runnables.
          */
         public void cancelAutoRemovalCallbacks(@Nullable String reason) {
+            mLogger.logAutoRemoveCancelRequest(this.mEntry, reason);
             Runnable runnable = () -> {
                 final boolean removed = cancelAutoRemovalCallbackInternal();
 
@@ -900,6 +910,7 @@
         public void scheduleAutoRemovalCallback(FinishTimeUpdater finishTimeCalculator,
                 @NonNull String reason) {
 
+            mLogger.logAutoRemoveRequest(this.mEntry, reason);
             Runnable runnable = () -> {
                 long delayMs = finishTimeCalculator.updateAndGetTimeRemaining();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt
index f6154afe..a306606 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt
@@ -58,6 +58,14 @@
         })
     }
 
+    fun logShowNotificationRequest(entry: NotificationEntry) {
+        buffer.log(TAG, INFO, {
+            str1 = entry.logKey
+        }, {
+            "request: show notification $str1"
+        })
+    }
+
     fun logShowNotification(entry: NotificationEntry) {
         buffer.log(TAG, INFO, {
             str1 = entry.logKey
@@ -76,6 +84,15 @@
         })
     }
 
+    fun logAutoRemoveRequest(entry: NotificationEntry, reason: String) {
+        buffer.log(TAG, INFO, {
+            str1 = entry.logKey
+            str2 = reason
+        }, {
+            "request: reschedule auto remove of $str1 reason: $str2"
+        })
+    }
+
     fun logAutoRemoveRescheduled(entry: NotificationEntry, delayMillis: Long, reason: String) {
         buffer.log(TAG, INFO, {
             str1 = entry.logKey
@@ -86,6 +103,15 @@
         })
     }
 
+    fun logAutoRemoveCancelRequest(entry: NotificationEntry, reason: String?) {
+        buffer.log(TAG, INFO, {
+            str1 = entry.logKey
+            str2 = reason ?: "unknown"
+        }, {
+            "request: cancel auto remove of $str1 reason: $str2"
+        })
+    }
+
     fun logAutoRemoveCanceled(entry: NotificationEntry, reason: String?) {
         buffer.log(TAG, INFO, {
             str1 = entry.logKey
@@ -95,6 +121,38 @@
         })
     }
 
+    fun logRemoveEntryRequest(key: String) {
+        buffer.log(TAG, INFO, {
+            str1 = logKey(key)
+        }, {
+            "request: remove entry $str1"
+        })
+    }
+
+    fun logRemoveEntry(key: String) {
+        buffer.log(TAG, INFO, {
+            str1 = logKey(key)
+        }, {
+            "remove entry $str1"
+        })
+    }
+
+    fun logUnpinEntryRequest(key: String) {
+        buffer.log(TAG, INFO, {
+            str1 = logKey(key)
+        }, {
+            "request: unpin entry $str1"
+        })
+    }
+
+    fun logUnpinEntry(key: String) {
+        buffer.log(TAG, INFO, {
+            str1 = logKey(key)
+        }, {
+            "unpin entry $str1"
+        })
+    }
+
     fun logRemoveNotification(key: String, releaseImmediately: Boolean) {
         buffer.log(TAG, INFO, {
             str1 = logKey(key)
@@ -112,6 +170,16 @@
         })
     }
 
+    fun logUpdateNotificationRequest(key: String, alert: Boolean, hasEntry: Boolean) {
+        buffer.log(TAG, INFO, {
+            str1 = logKey(key)
+            bool1 = alert
+            bool2 = hasEntry
+        }, {
+            "request: update notification $str1 alert: $bool1 hasEntry: $bool2 reason: $str2"
+        })
+    }
+
     fun logUpdateNotification(key: String, alert: Boolean, hasEntry: Boolean) {
         buffer.log(TAG, INFO, {
             str1 = logKey(key)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
index 7a57027..db4e605d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
@@ -14,6 +14,12 @@
 
 package com.android.systemui.statusbar.policy
 
+import android.hardware.SensorPrivacyManager.Sensors.CAMERA
+import android.hardware.SensorPrivacyManager.Sensors.MICROPHONE
+import android.os.UserManager.DISALLOW_CAMERA_TOGGLE
+import android.os.UserManager.DISALLOW_CONFIG_LOCATION
+import android.os.UserManager.DISALLOW_MICROPHONE_TOGGLE
+import android.os.UserManager.DISALLOW_SHARE_LOCATION
 import com.android.systemui.qs.QsEventLogger
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.tileimpl.QSTileImpl
@@ -38,6 +44,11 @@
 import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileDataInteractor
 import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel
+import com.android.systemui.qs.tiles.impl.sensorprivacy.SensorPrivacyToggleTileDataInteractor
+import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.SensorPrivacyToggleTileUserActionInteractor
+import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel
+import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyTileResources
+import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyToggleTileMapper
 import com.android.systemui.qs.tiles.impl.uimodenight.domain.UiModeNightTileMapper
 import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.UiModeNightTileDataInteractor
 import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.UiModeNightTileUserActionInteractor
@@ -47,6 +58,7 @@
 import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel
 import com.android.systemui.qs.tiles.impl.work.ui.WorkModeTileMapper
 import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy
 import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
 import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
 import com.android.systemui.res.R
@@ -74,6 +86,8 @@
         const val ALARM_TILE_SPEC = "alarm"
         const val UIMODENIGHT_TILE_SPEC = "dark"
         const val WORK_MODE_TILE_SPEC = "work"
+        const val CAMERA_TOGGLE_TILE_SPEC = "cameratoggle"
+        const val MIC_TOGGLE_TILE_SPEC = "mictoggle"
 
         /** Inject flashlight config */
         @Provides
@@ -120,6 +134,13 @@
                         labelRes = R.string.quick_settings_location_label,
                     ),
                 instanceId = uiEventLogger.getNewInstanceId(),
+                policy =
+                    QSTilePolicy.Restricted(
+                        listOf(
+                            DISALLOW_SHARE_LOCATION,
+                            DISALLOW_CONFIG_LOCATION
+                        )
+                    )
             )
 
         /** Inject LocationTile into tileViewModelMap in QSModule */
@@ -234,6 +255,72 @@
                 stateInteractor,
                 mapper,
             )
+
+        /** Inject camera toggle config */
+        @Provides
+        @IntoMap
+        @StringKey(CAMERA_TOGGLE_TILE_SPEC)
+        fun provideCameraToggleTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+            QSTileConfig(
+                tileSpec = TileSpec.create(CAMERA_TOGGLE_TILE_SPEC),
+                uiConfig =
+                    QSTileUIConfig.Resource(
+                        iconRes = R.drawable.qs_camera_access_icon_off,
+                        labelRes = R.string.quick_settings_camera_label,
+                    ),
+                instanceId = uiEventLogger.getNewInstanceId(),
+                policy = QSTilePolicy.Restricted(listOf(DISALLOW_CAMERA_TOGGLE)),
+            )
+
+        /** Inject camera toggle tile into tileViewModelMap in QSModule */
+        @Provides
+        @IntoMap
+        @StringKey(CAMERA_TOGGLE_TILE_SPEC)
+        fun provideCameraToggleTileViewModel(
+            factory: QSTileViewModelFactory.Static<SensorPrivacyToggleTileModel>,
+            mapper: SensorPrivacyToggleTileMapper.Factory,
+            stateInteractor: SensorPrivacyToggleTileDataInteractor.Factory,
+            userActionInteractor: SensorPrivacyToggleTileUserActionInteractor.Factory,
+        ): QSTileViewModel =
+            factory.create(
+                TileSpec.create(CAMERA_TOGGLE_TILE_SPEC),
+                userActionInteractor.create(CAMERA),
+                stateInteractor.create(CAMERA),
+                mapper.create(SensorPrivacyTileResources.CameraPrivacyTileResources),
+            )
+
+        /** Inject microphone toggle config */
+        @Provides
+        @IntoMap
+        @StringKey(MIC_TOGGLE_TILE_SPEC)
+        fun provideMicrophoneToggleTileConfig(uiEventLogger: QsEventLogger): QSTileConfig =
+            QSTileConfig(
+                tileSpec = TileSpec.create(MIC_TOGGLE_TILE_SPEC),
+                uiConfig =
+                    QSTileUIConfig.Resource(
+                        iconRes = R.drawable.qs_mic_access_off,
+                        labelRes = R.string.quick_settings_mic_label,
+                    ),
+                instanceId = uiEventLogger.getNewInstanceId(),
+                policy = QSTilePolicy.Restricted(listOf(DISALLOW_MICROPHONE_TOGGLE)),
+            )
+
+        /** Inject microphone toggle tile into tileViewModelMap in QSModule */
+        @Provides
+        @IntoMap
+        @StringKey(MIC_TOGGLE_TILE_SPEC)
+        fun provideMicrophoneToggleTileViewModel(
+            factory: QSTileViewModelFactory.Static<SensorPrivacyToggleTileModel>,
+            mapper: SensorPrivacyToggleTileMapper.Factory,
+            stateInteractor: SensorPrivacyToggleTileDataInteractor.Factory,
+            userActionInteractor: SensorPrivacyToggleTileUserActionInteractor.Factory,
+        ): QSTileViewModel =
+            factory.create(
+                TileSpec.create(MIC_TOGGLE_TILE_SPEC),
+                userActionInteractor.create(MICROPHONE),
+                stateInteractor.create(MICROPHONE),
+                mapper.create(SensorPrivacyTileResources.MicrophonePrivacyTileResources),
+            )
     }
 
     /** Inject FlashlightTile into tileMap in QSModule */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java
index 068e0a6..0d53277 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerImpl.java
@@ -20,6 +20,7 @@
 import static android.provider.Settings.Global.DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS;
 
 import static com.android.server.notification.Flags.screenshareNotificationHiding;
+import static com.android.systemui.Flags.screenshareNotificationHidingBugFix;
 
 import android.annotation.MainThread;
 import android.app.IActivityManager;
@@ -31,6 +32,7 @@
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.Trace;
+import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
 import android.util.ArraySet;
 import android.util.Log;
@@ -94,7 +96,8 @@
 
                         int packageUid;
                         try {
-                            packageUid = mPackageManager.getPackageUid(info.getPackageName(), 0);
+                            packageUid = mPackageManager.getPackageUidAsUser(info.getPackageName(),
+                                    info.getUserHandle().getIdentifier());
                         } catch (PackageManager.NameNotFoundException e) {
                             Log.w(LOG_TAG, "Package " + info.getPackageName() + " not found");
                             packageUid = -1;
@@ -315,6 +318,10 @@
             return false;
         }
 
+        if (screenshareNotificationHidingBugFix() && UserHandle.isCore(sbn.getUid())) {
+            return false; // do not hide/redact notifications from system uid
+        }
+
         // Only protect/redact notifications if the developer has not explicitly set notification
         // visibility as public and users has not adjusted default channel visibility to private
         boolean notificationRequestsRedaction = entry.isNotificationVisibilityPrivate();
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
index 2f2c4b0..b6f5433 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinator.kt
@@ -31,6 +31,7 @@
 import android.view.ViewGroup
 import android.view.WindowManager
 import android.view.accessibility.AccessibilityManager
+import android.view.accessibility.AccessibilityNodeInfo
 import android.widget.ImageView
 import android.widget.TextView
 import androidx.annotation.DimenRes
@@ -57,6 +58,7 @@
 import com.android.systemui.util.time.SystemClock
 import com.android.systemui.util.view.ViewUtil
 import com.android.systemui.util.wakelock.WakeLock
+import java.time.Duration
 import javax.inject.Inject
 
 /**
@@ -228,6 +230,18 @@
         chipInnerView.contentDescription =
             "$loadedIconDesc${newInfo.text.loadText(context)}$endItemDesc"
         chipInnerView.accessibilityLiveRegion = ACCESSIBILITY_LIVE_REGION_ASSERTIVE
+        // Set minimum duration between content changes to 1 second in order to announce quick
+        // state changes.
+        chipInnerView.accessibilityDelegate =
+            object : View.AccessibilityDelegate() {
+                override fun onInitializeAccessibilityNodeInfo(
+                    host: View,
+                    info: AccessibilityNodeInfo
+                ) {
+                    super.onInitializeAccessibilityNodeInfo(host, info)
+                    info.minDurationBetweenContentChanges = Duration.ofMillis(1000)
+                }
+            }
         maybeGetAccessibilityFocus(newInfo, currentView)
 
         // ---- Haptics ----
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt b/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt
index 81c8d50..a382cf9 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt
@@ -23,10 +23,11 @@
 import android.provider.Settings
 import androidx.core.view.OneShotPreDrawListener
 import com.android.internal.util.LatencyTracker
-import com.android.systemui.Flags.migrateClocksToBlueprint
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.keyguard.MigrateClocksToBlueprint
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.ToAodFoldTransitionInteractor
 import com.android.systemui.shade.ShadeFoldAnimator
 import com.android.systemui.shade.ShadeViewController
 import com.android.systemui.statusbar.LightRevealScrim
@@ -55,6 +56,7 @@
     private val globalSettings: GlobalSettings,
     private val latencyTracker: LatencyTracker,
     private val keyguardInteractor: Lazy<KeyguardInteractor>,
+    private val foldTransitionInteractor: Lazy<ToAodFoldTransitionInteractor>,
 ) : CallbackController<FoldAodAnimationStatus>, ScreenOffAnimation, WakefulnessLifecycle.Observer {
 
     private lateinit var shadeViewController: ShadeViewController
@@ -74,7 +76,7 @@
     private val foldToAodLatencyTracker = FoldToAodLatencyTracker()
 
     private val startAnimationRunnable = Runnable {
-        getShadeFoldAnimator().startFoldToAodAnimation(
+        shadeFoldAnimator.startFoldToAodAnimation(
             /* startAction= */ { foldToAodLatencyTracker.onAnimationStarted() },
             /* endAction= */ { setAnimationState(playing = false) },
             /* cancelAction= */ { setAnimationState(playing = false) },
@@ -82,11 +84,12 @@
     }
 
     override fun initialize(
-            centralSurfaces: CentralSurfaces,
-            shadeViewController: ShadeViewController,
-            lightRevealScrim: LightRevealScrim,
+        centralSurfaces: CentralSurfaces,
+        shadeViewController: ShadeViewController,
+        lightRevealScrim: LightRevealScrim,
     ) {
         this.shadeViewController = shadeViewController
+        foldTransitionInteractor.get().initialize(shadeViewController.shadeFoldAnimator)
 
         deviceStateManager.registerCallback(mainExecutor, FoldListener())
         wakefulnessLifecycle.addObserver(this)
@@ -103,7 +106,7 @@
     override fun startAnimation(): Boolean =
         if (shouldStartAnimation()) {
             setAnimationState(playing = true)
-            getShadeFoldAnimator().prepareFoldToAodAnimation()
+            shadeFoldAnimator.prepareFoldToAodAnimation()
             true
         } else {
             setAnimationState(playing = false)
@@ -114,14 +117,20 @@
         if (isAnimationPlaying) {
             foldToAodLatencyTracker.cancel()
             cancelAnimation?.run()
-            getShadeFoldAnimator().cancelFoldToAodAnimation()
+            shadeFoldAnimator.cancelFoldToAodAnimation()
         }
 
         setAnimationState(playing = false)
     }
 
-    private fun getShadeFoldAnimator(): ShadeFoldAnimator =
-        shadeViewController.shadeFoldAnimator
+    private val shadeFoldAnimator: ShadeFoldAnimator
+        get() {
+            return if (MigrateClocksToBlueprint.isEnabled) {
+                foldTransitionInteractor.get().foldAnimator
+            } else {
+                shadeViewController.shadeFoldAnimator
+            }
+        }
 
     private fun setAnimationState(playing: Boolean) {
         shouldPlayAnimation = playing
@@ -137,41 +146,45 @@
      * @see [com.android.systemui.keyguard.KeyguardViewMediator]
      */
     @BinderThread
-    fun onScreenTurningOn(onReady: Runnable) = mainExecutor.execute {
-        if (shouldPlayAnimation) {
-            // The device was not dozing and going to sleep after folding, play the animation
-
-            if (isScrimOpaque) {
-                onReady.run()
-            } else {
-                pendingScrimReadyCallback = onReady
-            }
-        } else if (isFolded && !isFoldHandled && alwaysOnEnabled &&
-                keyguardInteractor.get().isDozing.value) {
-            setAnimationState(playing = true)
-            getShadeFoldAnimator().prepareFoldToAodAnimation()
-
-            // We don't need to wait for the scrim as it is already displayed
-            // but we should wait for the initial animation preparations to be drawn
-            // (setting initial alpha/translation)
-            // TODO(b/254878364): remove this call to NPVC.getView()
-            if (!migrateClocksToBlueprint()) {
-                getShadeFoldAnimator().view?.let {
-                    OneShotPreDrawListener.add(it, onReady)
+    fun onScreenTurningOn(onReady: Runnable) =
+        mainExecutor.execute {
+            if (shouldPlayAnimation) {
+                // The device was not dozing and going to sleep after folding, play the animation
+                if (isScrimOpaque) {
+                    onReady.run()
+                } else {
+                    pendingScrimReadyCallback = onReady
                 }
-            }
-        } else {
-            // No animation, call ready callback immediately
-            onReady.run()
-        }
+            } else if (
+                isFolded &&
+                    !isFoldHandled &&
+                    alwaysOnEnabled &&
+                    keyguardInteractor.get().isDozing.value
+            ) {
+                setAnimationState(playing = true)
+                shadeFoldAnimator.prepareFoldToAodAnimation()
 
-        if (isFolded) {
-            // Any time the screen turns on, this state needs to be reset if the device has been
-            // folded. Reaching this line implies AOD has been shown in one way or another,
-            // if enabled
-            isFoldHandled = true
+                // We don't need to wait for the scrim as it is already displayed
+                // but we should wait for the initial animation preparations to be drawn
+                // (setting initial alpha/translation)
+                // TODO(b/254878364): remove this call to NPVC.getView()
+                if (!MigrateClocksToBlueprint.isEnabled) {
+                    shadeFoldAnimator.view?.let { OneShotPreDrawListener.add(it, onReady) }
+                } else {
+                    onReady.run()
+                }
+            } else {
+                // No animation, call ready callback immediately
+                onReady.run()
+            }
+
+            if (isFolded) {
+                // Any time the screen turns on, this state needs to be reset if the device has been
+                // folded. Reaching this line implies AOD has been shown in one way or another,
+                // if enabled
+                isFoldHandled = true
+            }
         }
-    }
 
     /** Called when keyguard scrim opaque changed */
     override fun onScrimOpaqueChanged(isOpaque: Boolean) {
@@ -184,18 +197,17 @@
     }
 
     @BinderThread
-    fun onScreenTurnedOn() = mainExecutor.execute {
-        if (shouldPlayAnimation) {
-            cancelAnimation?.run()
+    fun onScreenTurnedOn() =
+        mainExecutor.execute {
+            if (shouldPlayAnimation) {
+                cancelAnimation?.run()
 
-            // Post starting the animation to the next frame to avoid junk due to inset changes
-            cancelAnimation = mainExecutor.executeDelayed(
-                startAnimationRunnable,
-                /* delayMillis= */ 0
-            )
-            shouldPlayAnimation = false
+                // Post starting the animation to the next frame to avoid junk due to inset changes
+                cancelAnimation =
+                    mainExecutor.executeDelayed(startAnimationRunnable, /* delayMillis= */ 0)
+                shouldPlayAnimation = false
+            }
         }
-    }
 
     override fun isAnimationPlaying(): Boolean = isAnimationPlaying
 
@@ -247,11 +259,10 @@
      * Tracks the latency of fold to AOD using [LatencyTracker].
      *
      * Events that trigger start and end are:
-     *
      * - Start: Once [DeviceStateManager] sends the folded signal [FoldToAodLatencyTracker.onFolded]
-     * is called and latency tracking starts.
+     *   is called and latency tracking starts.
      * - End: Once the fold -> AOD animation starts, [FoldToAodLatencyTracker.onAnimationStarted] is
-     * called, and latency tracking stops.
+     *   called, and latency tracking stops.
      */
     private inner class FoldToAodLatencyTracker {
 
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt
index e977014..aea739d 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimation.kt
@@ -20,11 +20,10 @@
 import android.animation.AnimatorListenerAdapter
 import android.animation.ValueAnimator
 import android.annotation.BinderThread
-import android.content.Context
-import android.os.Handler
 import android.os.SystemProperties
 import android.util.Log
 import android.view.animation.DecelerateInterpolator
+import com.android.app.tracing.TraceUtils.traceAsync
 import com.android.internal.foldables.FoldLockSettingAvailabilityProvider
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.display.data.repository.DeviceStateRepository
@@ -36,12 +35,13 @@
 import com.android.systemui.unfold.FullscreenLightRevealAnimationController.Companion.isVerticalRotation
 import com.android.systemui.unfold.dagger.UnfoldBg
 import com.android.systemui.util.animation.data.repository.AnimationStatusRepository
+import com.android.systemui.util.kotlin.race
 import javax.inject.Inject
 import kotlin.coroutines.resume
 import kotlinx.coroutines.CompletableDeferred
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.TimeoutCancellationException
-import kotlinx.coroutines.android.asCoroutineDispatcher
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.catch
 import kotlinx.coroutines.flow.distinctUntilChanged
@@ -59,13 +59,13 @@
 class FoldLightRevealOverlayAnimation
 @Inject
 constructor(
-    private val context: Context,
-    @UnfoldBg private val bgHandler: Handler,
+    @UnfoldBg private val bgDispatcher: CoroutineDispatcher,
     private val deviceStateRepository: DeviceStateRepository,
     private val powerInteractor: PowerInteractor,
     @Background private val applicationScope: CoroutineScope,
     private val animationStatusRepository: AnimationStatusRepository,
-    private val controllerFactory: FullscreenLightRevealAnimationController.Factory
+    private val controllerFactory: FullscreenLightRevealAnimationController.Factory,
+    private val foldLockSettingAvailabilityProvider: FoldLockSettingAvailabilityProvider
 ) : FullscreenLightRevealAnimation {
 
     private val revealProgressValueAnimator: ValueAnimator =
@@ -79,7 +79,7 @@
     override fun init() {
         // This method will be called only on devices where this animation is enabled,
         // so normally this thread won't be created
-        if (!FoldLockSettingAvailabilityProvider(context.resources).isFoldLockBehaviorAvailable) {
+        if (!foldLockSettingAvailabilityProvider.isFoldLockBehaviorAvailable) {
             return
         }
 
@@ -91,7 +91,6 @@
             )
         controller.init()
 
-        val bgDispatcher = bgHandler.asCoroutineDispatcher("@UnfoldBg Handler")
         applicationScope.launch(bgDispatcher) {
             powerInteractor.screenPowerState.collect {
                 if (it == ScreenPowerState.SCREEN_ON) {
@@ -109,14 +108,21 @@
                             if (!areAnimationEnabled.first() || !isFolded) {
                                 return@flow
                             }
-                            withTimeout(WAIT_FOR_ANIMATION_TIMEOUT_MS) {
-                                readyCallback = CompletableDeferred()
-                                val onReady = readyCallback?.await()
-                                readyCallback = null
-                                controller.addOverlay(ALPHA_OPAQUE, onReady)
-                                waitForScreenTurnedOn()
-                            }
-                            playFoldLightRevealOverlayAnimation()
+                            race(
+                                {
+                                    traceAsync(TAG, "prepareAndPlayFoldAnimation()") {
+                                        withTimeout(WAIT_FOR_ANIMATION_TIMEOUT_MS) {
+                                            readyCallback = CompletableDeferred()
+                                            val onReady = readyCallback?.await()
+                                            readyCallback = null
+                                            controller.addOverlay(ALPHA_OPAQUE, onReady)
+                                            waitForScreenTurnedOn()
+                                        }
+                                        playFoldLightRevealOverlayAnimation()
+                                    }
+                                },
+                                { waitForGoToSleep() }
+                            )
                         }
                         .catchTimeoutAndLog()
                         .onCompletion {
@@ -135,9 +141,13 @@
         readyCallback?.complete(onOverlayReady) ?: onOverlayReady.run()
     }
 
-    private suspend fun waitForScreenTurnedOn() {
-        powerInteractor.screenPowerState.filter { it == ScreenPowerState.SCREEN_ON }.first()
-    }
+    private suspend fun waitForScreenTurnedOn() =
+        traceAsync(TAG, "waitForScreenTurnedOn()") {
+            powerInteractor.screenPowerState.filter { it == ScreenPowerState.SCREEN_ON }.first()
+        }
+
+    private suspend fun waitForGoToSleep() =
+        traceAsync(TAG, "waitForGoToSleep()") { powerInteractor.isAsleep.filter { it }.first() }
 
     private suspend fun playFoldLightRevealOverlayAnimation() {
         revealProgressValueAnimator.duration = ANIMATION_DURATION
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
index 9bd0e32..3522850 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt
@@ -19,6 +19,7 @@
 import android.content.Context
 import android.hardware.devicestate.DeviceStateManager
 import android.os.SystemProperties
+import com.android.internal.foldables.FoldLockSettingAvailabilityProvider
 import com.android.systemui.CoreStartable
 import com.android.systemui.Flags
 import com.android.systemui.dagger.qualifiers.Application
@@ -175,6 +176,12 @@
     fun provideDisplaySwitchLatencyLogger(): DisplaySwitchLatencyLogger =
         DisplaySwitchLatencyLogger()
 
+    @Provides
+    @Singleton
+    fun provideFoldLockSettingAvailabilityProvider(
+        context: Context
+    ): FoldLockSettingAvailabilityProvider = FoldLockSettingAvailabilityProvider(context.resources)
+
     @Module
     interface Bindings {
         @Binds fun bindRepository(impl: UnfoldTransitionRepositoryImpl): UnfoldTransitionRepository
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/DisposableHandleExt.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/DisposableHandleExt.kt
index 909a18be..97d957d 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/DisposableHandleExt.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/DisposableHandleExt.kt
@@ -17,8 +17,14 @@
 package com.android.systemui.util.kotlin
 
 import com.android.systemui.lifecycle.repeatWhenAttached
+import kotlin.coroutines.CoroutineContext
+import kotlin.coroutines.EmptyCoroutineContext
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.CoroutineStart
 import kotlinx.coroutines.DisposableHandle
+import kotlinx.coroutines.Job
 import kotlinx.coroutines.awaitCancellation
+import kotlinx.coroutines.launch
 
 /**
  * Suspends to keep getting updates until cancellation. Once cancelled, mark this as eligible for
@@ -42,3 +48,22 @@
         dispose()
     }
 }
+
+/**
+ * This will [launch], run [onLaunch] to get a [DisposableHandle], and finally
+ * [awaitCancellationThenDispose][DisposableHandle.awaitCancellationThenDispose]. This can be used
+ * to structure self-disposing code which attaches listeners, for example in ViewBinders:
+ * ```
+ * suspend fun bind(view: MyView, viewModel: MyViewModel) = coroutineScope {
+ *     launchAndDispose {
+ *         view.setOnClickListener { viewModel.handleClick() }
+ *         DisposableHandle { view.setOnClickListener(null) }
+ *     }
+ * }
+ * ```
+ */
+inline fun CoroutineScope.launchAndDispose(
+    context: CoroutineContext = EmptyCoroutineContext,
+    start: CoroutineStart = CoroutineStart.DEFAULT,
+    crossinline onLaunch: () -> DisposableHandle
+): Job = launch(context, start) { onLaunch().awaitCancellationThenDispose() }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallableFactory.java b/packages/SystemUI/src/com/android/systemui/utils/PolicyRestriction.kt
similarity index 62%
copy from tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallableFactory.java
copy to packages/SystemUI/src/com/android/systemui/utils/PolicyRestriction.kt
index b8f9f0e..38c6d7f 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallableFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/utils/PolicyRestriction.kt
@@ -14,16 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.systemui.utils
 
-import com.android.asllib.util.MalformedXmlException;
+import com.android.settingslib.RestrictedLockUtils
 
-import org.w3c.dom.Element;
+/**
+ * Models a possible policy restriction.
+ *
+ * @see RestrictedLockUtils.checkIfRestrictionEnforced
+ */
+sealed interface PolicyRestriction {
+    data object NoRestriction : PolicyRestriction
 
-import java.util.List;
-
-public interface AslMarshallableFactory<T extends AslMarshallable> {
-
-    /** Creates an {@link AslMarshallableFactory} from human-readable DOM element */
-    T createFromHrElements(List<Element> elements) throws MalformedXmlException;
+    data class Restricted(val admin: RestrictedLockUtils.EnforcedAdmin) : PolicyRestriction
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaDeviceSessionInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaDeviceSessionInteractor.kt
index b0c8a4a..dc73344 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaDeviceSessionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaDeviceSessionInteractor.kt
@@ -23,7 +23,7 @@
 import com.android.settingslib.volume.data.repository.MediaControllerRepository
 import com.android.settingslib.volume.data.repository.stateChanges
 import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.volume.panel.component.mediaoutput.domain.model.MediaDeviceSession
+import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession
 import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope
 import javax.inject.Inject
 import kotlin.coroutines.CoroutineContext
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputActionsInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputActionsInteractor.kt
index ea4c082..eebb6fb 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputActionsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputActionsInteractor.kt
@@ -21,7 +21,7 @@
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.animation.Expandable
 import com.android.systemui.media.dialog.MediaOutputDialogManager
-import com.android.systemui.volume.panel.component.mediaoutput.domain.model.MediaDeviceSession
+import com.android.systemui.volume.panel.component.mediaoutput.shared.model.SessionWithPlayback
 import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope
 import javax.inject.Inject
 
@@ -33,10 +33,10 @@
     private val mediaOutputDialogManager: MediaOutputDialogManager,
 ) {
 
-    fun onBarClick(session: MediaDeviceSession, isPlaybackActive: Boolean, expandable: Expandable) {
-        if (isPlaybackActive) {
+    fun onBarClick(sessionWithPlayback: SessionWithPlayback?, expandable: Expandable) {
+        if (sessionWithPlayback?.playback?.isActive == true) {
             mediaOutputDialogManager.createAndShowWithController(
-                session.packageName,
+                sessionWithPlayback.session.packageName,
                 false,
                 expandable.dialogController()
             )
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputInteractor.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputInteractor.kt
index e60139e..41ad035 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/interactor/MediaOutputInteractor.kt
@@ -25,8 +25,8 @@
 import com.android.settingslib.volume.data.repository.MediaControllerRepository
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.volume.panel.component.mediaoutput.data.repository.LocalMediaRepositoryFactory
-import com.android.systemui.volume.panel.component.mediaoutput.domain.model.MediaDeviceSession
 import com.android.systemui.volume.panel.component.mediaoutput.domain.model.MediaDeviceSessions
+import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession
 import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope
 import javax.inject.Inject
 import kotlin.coroutines.CoroutineContext
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/model/MediaDeviceSessions.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/model/MediaDeviceSessions.kt
index ddc0784..22c160d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/model/MediaDeviceSessions.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/model/MediaDeviceSessions.kt
@@ -16,6 +16,8 @@
 
 package com.android.systemui.volume.panel.component.mediaoutput.domain.model
 
+import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession
+
 /** Models a pair of local and remote [MediaDeviceSession]s. */
 data class MediaDeviceSessions(
     val local: MediaDeviceSession?,
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/model/MediaDeviceSession.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/shared/model/MediaDeviceSession.kt
similarity index 98%
rename from packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/model/MediaDeviceSession.kt
rename to packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/shared/model/MediaDeviceSession.kt
index 2a2ce79..eca3315 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/domain/model/MediaDeviceSession.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/shared/model/MediaDeviceSession.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.volume.panel.component.mediaoutput.domain.model
+package com.android.systemui.volume.panel.component.mediaoutput.shared.model
 
 import android.media.session.MediaSession
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/shared/model/SessionWithPlayback.kt
similarity index 72%
copy from packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
copy to packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/shared/model/SessionWithPlayback.kt
index 0c92b50..c4476fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/shared/model/SessionWithPlayback.kt
@@ -14,7 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.notification.stack.shared.model
+package com.android.systemui.volume.panel.component.mediaoutput.shared.model
 
-/** Models the clipping rounded rectangle of the notification stack */
-data class StackClipping(val bounds: StackBounds, val rounding: StackRounding)
+import android.media.session.PlaybackState
+
+data class SessionWithPlayback(
+    val session: MediaDeviceSession,
+    val playback: PlaybackState,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt
index 2530a3a..fc9602e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.volume.panel.component.mediaoutput.ui.viewmodel
 
 import android.content.Context
-import android.media.session.PlaybackState
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.Color
 import com.android.systemui.common.shared.model.Icon
@@ -25,9 +24,8 @@
 import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaDeviceSessionInteractor
 import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputActionsInteractor
 import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor
-import com.android.systemui.volume.panel.component.mediaoutput.domain.model.MediaDeviceSession
+import com.android.systemui.volume.panel.component.mediaoutput.shared.model.SessionWithPlayback
 import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope
-import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -47,7 +45,6 @@
 constructor(
     private val context: Context,
     @VolumePanelScope private val coroutineScope: CoroutineScope,
-    private val volumePanelViewModel: VolumePanelViewModel,
     private val actionsInteractor: MediaOutputActionsInteractor,
     private val mediaDeviceSessionInteractor: MediaDeviceSessionInteractor,
     interactor: MediaOutputInteractor,
@@ -129,14 +126,6 @@
             )
 
     fun onBarClick(expandable: Expandable) {
-        sessionWithPlayback.value?.let {
-            actionsInteractor.onBarClick(it.session, it.playback.isActive, expandable)
-        }
-        volumePanelViewModel.dismissPanel()
+        actionsInteractor.onBarClick(sessionWithPlayback.value, expandable)
     }
-
-    private data class SessionWithPlayback(
-        val session: MediaDeviceSession,
-        val playback: PlaybackState,
-    )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/ui/viewmodel/SpatialAudioViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/ui/viewmodel/SpatialAudioViewModel.kt
index ceb769e..f022039 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/ui/viewmodel/SpatialAudioViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/spatial/ui/viewmodel/SpatialAudioViewModel.kt
@@ -81,15 +81,19 @@
                             model = isEnabled,
                             iconColor =
                                 Color.Attribute(
-                                    if (isChecked)
+                                    if (isChecked) {
                                         com.android.internal.R.attr.materialColorOnPrimaryContainer
-                                    else com.android.internal.R.attr.materialColorOnSurfaceVariant
+                                    } else {
+                                        com.android.internal.R.attr.materialColorOnSurfaceVariant
+                                    }
                                 ),
                             labelColor =
                                 Color.Attribute(
-                                    if (isChecked)
+                                    if (isChecked) {
                                         com.android.internal.R.attr.materialColorOnSurface
-                                    else com.android.internal.R.attr.materialColorOutline
+                                    } else {
+                                        com.android.internal.R.attr.materialColorOnSurfaceVariant
+                                    }
                                 ),
                         )
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt
index 73c8bbf..8d8fa17 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt
@@ -21,7 +21,7 @@
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.res.R
 import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaDeviceSessionInteractor
-import com.android.systemui.volume.panel.component.mediaoutput.domain.model.MediaDeviceSession
+import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession
 import com.android.systemui.volume.panel.component.volume.domain.interactor.VolumeSliderInteractor
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt
index 4e9a456..09e56c1 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/ui/viewmodel/AudioVolumeComponentViewModel.kt
@@ -20,8 +20,8 @@
 import com.android.settingslib.volume.shared.model.AudioStream
 import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaDeviceSessionInteractor
 import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor
-import com.android.systemui.volume.panel.component.mediaoutput.domain.model.MediaDeviceSession
-import com.android.systemui.volume.panel.component.mediaoutput.domain.model.isTheSameSession
+import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession
+import com.android.systemui.volume.panel.component.mediaoutput.shared.model.isTheSameSession
 import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.AudioStreamSliderViewModel
 import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.CastVolumeSliderViewModel
 import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.SliderViewModel
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
index 1d9b90a..ff18418 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/controller/QuickAccessWalletController.java
@@ -91,17 +91,22 @@
             @Background Executor bgExecutor,
             SecureSettings secureSettings,
             QuickAccessWalletClient quickAccessWalletClient,
-            SystemClock clock) {
+            SystemClock clock,
+            RoleManager roleManager) {
         mContext = context;
         mExecutor = executor;
         mBgExecutor = bgExecutor;
         mSecureSettings = secureSettings;
-        mRoleManager = mContext.getSystemService(RoleManager.class);
+        mRoleManager = roleManager;
         mQuickAccessWalletClient = quickAccessWalletClient;
         mClock = clock;
         mQawClientCreatedTimeMillis = mClock.elapsedRealtime();
     }
 
+    public boolean isWalletRoleAvailable() {
+        return mRoleManager.isRoleAvailable(RoleManager.ROLE_WALLET);
+    }
+
     /**
      * Returns true if the Quick Access Wallet service & feature is available.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
index 9bfc4ce..d00081e 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
@@ -22,6 +22,7 @@
 
 import android.app.WallpaperColors;
 import android.app.WallpaperManager;
+import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.RecordingCanvas;
@@ -183,8 +184,11 @@
 
         @Override
         public void onDestroy() {
-            getDisplayContext().getSystemService(DisplayManager.class)
-                    .unregisterDisplayListener(this);
+            Context context = getDisplayContext();
+            if (context != null) {
+                DisplayManager displayManager = context.getSystemService(DisplayManager.class);
+                if (displayManager != null) displayManager.unregisterDisplayListener(this);
+            }
             mWallpaperLocalColorExtractor.cleanUp();
         }
 
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 572a6c1..0dbbe63 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -224,6 +224,5 @@
 
     <instrumentation android:name="android.testing.TestableInstrumentation"
         android:targetPackage="com.android.systemui.tests"
-        android:label="Tests for SystemUI">
-    </instrumentation>
+        android:label="Tests for SystemUI" />
 </manifest>
diff --git a/packages/SystemUI/tests/AndroidTest.xml b/packages/SystemUI/tests/AndroidTest.xml
index cd2a62d..2de5faf 100644
--- a/packages/SystemUI/tests/AndroidTest.xml
+++ b/packages/SystemUI/tests/AndroidTest.xml
@@ -23,6 +23,15 @@
         <option name="force-root" value="true" />
     </target_preparer>
 
+    <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
+        <option name="screen-always-on" value="on" />
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+        <option name="run-command" value="input keyevent KEYCODE_WAKEUP" />
+        <option name="run-command" value="wm dismiss-keyguard" />
+    </target_preparer>
+
     <option name="test-suite-tag" value="apct" />
     <option name="test-suite-tag" value="framework-base-presubmit" />
     <option name="test-tag" value="SystemUITests" />
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenLaunching.json b/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenLaunching.json
new file mode 100644
index 0000000..60bff17
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenLaunching.json
@@ -0,0 +1,393 @@
+{
+  "frame_ids": [
+    "before",
+    0,
+    26,
+    52,
+    78,
+    105,
+    131,
+    157,
+    184,
+    210,
+    236,
+    263,
+    289,
+    315,
+    342,
+    368,
+    394,
+    421,
+    447,
+    473,
+    500
+  ],
+  "features": [
+    {
+      "name": "bounds",
+      "type": "rect",
+      "data_points": [
+        {
+          "left": 0,
+          "top": 0,
+          "right": 0,
+          "bottom": 0
+        },
+        {
+          "left": 100,
+          "top": 300,
+          "right": 200,
+          "bottom": 400
+        },
+        {
+          "left": 98,
+          "top": 293,
+          "right": 203,
+          "bottom": 407
+        },
+        {
+          "left": 91,
+          "top": 269,
+          "right": 213,
+          "bottom": 430
+        },
+        {
+          "left": 71,
+          "top": 206,
+          "right": 240,
+          "bottom": 491
+        },
+        {
+          "left": 34,
+          "top": 98,
+          "right": 283,
+          "bottom": 595
+        },
+        {
+          "left": 22,
+          "top": 63,
+          "right": 296,
+          "bottom": 629
+        },
+        {
+          "left": 15,
+          "top": 44,
+          "right": 303,
+          "bottom": 648
+        },
+        {
+          "left": 11,
+          "top": 32,
+          "right": 308,
+          "bottom": 659
+        },
+        {
+          "left": 8,
+          "top": 23,
+          "right": 311,
+          "bottom": 667
+        },
+        {
+          "left": 6,
+          "top": 18,
+          "right": 313,
+          "bottom": 673
+        },
+        {
+          "left": 5,
+          "top": 13,
+          "right": 315,
+          "bottom": 677
+        },
+        {
+          "left": 3,
+          "top": 9,
+          "right": 316,
+          "bottom": 681
+        },
+        {
+          "left": 2,
+          "top": 7,
+          "right": 317,
+          "bottom": 683
+        },
+        {
+          "left": 2,
+          "top": 5,
+          "right": 318,
+          "bottom": 685
+        },
+        {
+          "left": 1,
+          "top": 3,
+          "right": 319,
+          "bottom": 687
+        },
+        {
+          "left": 1,
+          "top": 2,
+          "right": 319,
+          "bottom": 688
+        },
+        {
+          "left": 0,
+          "top": 1,
+          "right": 320,
+          "bottom": 689
+        },
+        {
+          "left": 0,
+          "top": 0,
+          "right": 320,
+          "bottom": 690
+        },
+        {
+          "left": 0,
+          "top": 0,
+          "right": 320,
+          "bottom": 690
+        },
+        {
+          "left": 0,
+          "top": 0,
+          "right": 320,
+          "bottom": 690
+        }
+      ]
+    },
+    {
+      "name": "corner_radii",
+      "type": "cornerRadii",
+      "data_points": [
+        null,
+        {
+          "top_left_x": 10,
+          "top_left_y": 10,
+          "top_right_x": 10,
+          "top_right_y": 10,
+          "bottom_right_x": 20,
+          "bottom_right_y": 20,
+          "bottom_left_x": 20,
+          "bottom_left_y": 20
+        },
+        {
+          "top_left_x": 9.762664,
+          "top_left_y": 9.762664,
+          "top_right_x": 9.762664,
+          "top_right_y": 9.762664,
+          "bottom_right_x": 19.525328,
+          "bottom_right_y": 19.525328,
+          "bottom_left_x": 19.525328,
+          "bottom_left_y": 19.525328
+        },
+        {
+          "top_left_x": 8.969244,
+          "top_left_y": 8.969244,
+          "top_right_x": 8.969244,
+          "top_right_y": 8.969244,
+          "bottom_right_x": 17.938488,
+          "bottom_right_y": 17.938488,
+          "bottom_left_x": 17.938488,
+          "bottom_left_y": 17.938488
+        },
+        {
+          "top_left_x": 6.8709626,
+          "top_left_y": 6.8709626,
+          "top_right_x": 6.8709626,
+          "top_right_y": 6.8709626,
+          "bottom_right_x": 13.741925,
+          "bottom_right_y": 13.741925,
+          "bottom_left_x": 13.741925,
+          "bottom_left_y": 13.741925
+        },
+        {
+          "top_left_x": 3.260561,
+          "top_left_y": 3.260561,
+          "top_right_x": 3.260561,
+          "top_right_y": 3.260561,
+          "bottom_right_x": 6.521122,
+          "bottom_right_y": 6.521122,
+          "bottom_left_x": 6.521122,
+          "bottom_left_y": 6.521122
+        },
+        {
+          "top_left_x": 2.0915751,
+          "top_left_y": 2.0915751,
+          "top_right_x": 2.0915751,
+          "top_right_y": 2.0915751,
+          "bottom_right_x": 4.1831503,
+          "bottom_right_y": 4.1831503,
+          "bottom_left_x": 4.1831503,
+          "bottom_left_y": 4.1831503
+        },
+        {
+          "top_left_x": 1.4640827,
+          "top_left_y": 1.4640827,
+          "top_right_x": 1.4640827,
+          "top_right_y": 1.4640827,
+          "bottom_right_x": 2.9281654,
+          "bottom_right_y": 2.9281654,
+          "bottom_left_x": 2.9281654,
+          "bottom_left_y": 2.9281654
+        },
+        {
+          "top_left_x": 1.057313,
+          "top_left_y": 1.057313,
+          "top_right_x": 1.057313,
+          "top_right_y": 1.057313,
+          "bottom_right_x": 2.114626,
+          "bottom_right_y": 2.114626,
+          "bottom_left_x": 2.114626,
+          "bottom_left_y": 2.114626
+        },
+        {
+          "top_left_x": 0.7824335,
+          "top_left_y": 0.7824335,
+          "top_right_x": 0.7824335,
+          "top_right_y": 0.7824335,
+          "bottom_right_x": 1.564867,
+          "bottom_right_y": 1.564867,
+          "bottom_left_x": 1.564867,
+          "bottom_left_y": 1.564867
+        },
+        {
+          "top_left_x": 0.5863056,
+          "top_left_y": 0.5863056,
+          "top_right_x": 0.5863056,
+          "top_right_y": 0.5863056,
+          "bottom_right_x": 1.1726112,
+          "bottom_right_y": 1.1726112,
+          "bottom_left_x": 1.1726112,
+          "bottom_left_y": 1.1726112
+        },
+        {
+          "top_left_x": 0.4332962,
+          "top_left_y": 0.4332962,
+          "top_right_x": 0.4332962,
+          "top_right_y": 0.4332962,
+          "bottom_right_x": 0.8665924,
+          "bottom_right_y": 0.8665924,
+          "bottom_left_x": 0.8665924,
+          "bottom_left_y": 0.8665924
+        },
+        {
+          "top_left_x": 0.3145876,
+          "top_left_y": 0.3145876,
+          "top_right_x": 0.3145876,
+          "top_right_y": 0.3145876,
+          "bottom_right_x": 0.6291752,
+          "bottom_right_y": 0.6291752,
+          "bottom_left_x": 0.6291752,
+          "bottom_left_y": 0.6291752
+        },
+        {
+          "top_left_x": 0.22506618,
+          "top_left_y": 0.22506618,
+          "top_right_x": 0.22506618,
+          "top_right_y": 0.22506618,
+          "bottom_right_x": 0.45013237,
+          "bottom_right_y": 0.45013237,
+          "bottom_left_x": 0.45013237,
+          "bottom_left_y": 0.45013237
+        },
+        {
+          "top_left_x": 0.15591621,
+          "top_left_y": 0.15591621,
+          "top_right_x": 0.15591621,
+          "top_right_y": 0.15591621,
+          "bottom_right_x": 0.31183243,
+          "bottom_right_y": 0.31183243,
+          "bottom_left_x": 0.31183243,
+          "bottom_left_y": 0.31183243
+        },
+        {
+          "top_left_x": 0.100948334,
+          "top_left_y": 0.100948334,
+          "top_right_x": 0.100948334,
+          "top_right_y": 0.100948334,
+          "bottom_right_x": 0.20189667,
+          "bottom_right_y": 0.20189667,
+          "bottom_left_x": 0.20189667,
+          "bottom_left_y": 0.20189667
+        },
+        {
+          "top_left_x": 0.06496239,
+          "top_left_y": 0.06496239,
+          "top_right_x": 0.06496239,
+          "top_right_y": 0.06496239,
+          "bottom_right_x": 0.12992477,
+          "bottom_right_y": 0.12992477,
+          "bottom_left_x": 0.12992477,
+          "bottom_left_y": 0.12992477
+        },
+        {
+          "top_left_x": 0.03526497,
+          "top_left_y": 0.03526497,
+          "top_right_x": 0.03526497,
+          "top_right_y": 0.03526497,
+          "bottom_right_x": 0.07052994,
+          "bottom_right_y": 0.07052994,
+          "bottom_left_x": 0.07052994,
+          "bottom_left_y": 0.07052994
+        },
+        {
+          "top_left_x": 0.014661789,
+          "top_left_y": 0.014661789,
+          "top_right_x": 0.014661789,
+          "top_right_y": 0.014661789,
+          "bottom_right_x": 0.029323578,
+          "bottom_right_y": 0.029323578,
+          "bottom_left_x": 0.029323578,
+          "bottom_left_y": 0.029323578
+        },
+        {
+          "top_left_x": 0.0041856766,
+          "top_left_y": 0.0041856766,
+          "top_right_x": 0.0041856766,
+          "top_right_y": 0.0041856766,
+          "bottom_right_x": 0.008371353,
+          "bottom_right_y": 0.008371353,
+          "bottom_left_x": 0.008371353,
+          "bottom_left_y": 0.008371353
+        },
+        {
+          "top_left_x": 0,
+          "top_left_y": 0,
+          "top_right_x": 0,
+          "top_right_y": 0,
+          "bottom_right_x": 0,
+          "bottom_right_y": 0,
+          "bottom_left_x": 0,
+          "bottom_left_y": 0
+        }
+      ]
+    },
+    {
+      "name": "alpha",
+      "type": "int",
+      "data_points": [
+        0,
+        0,
+        115,
+        178,
+        217,
+        241,
+        253,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenReturning.json b/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenReturning.json
new file mode 100644
index 0000000..ea768c0
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/backgroundAnimationWithoutFade_whenReturning.json
@@ -0,0 +1,393 @@
+{
+  "frame_ids": [
+    "before",
+    0,
+    26,
+    52,
+    78,
+    105,
+    131,
+    157,
+    184,
+    210,
+    236,
+    263,
+    289,
+    315,
+    342,
+    368,
+    394,
+    421,
+    447,
+    473,
+    500
+  ],
+  "features": [
+    {
+      "name": "bounds",
+      "type": "rect",
+      "data_points": [
+        {
+          "left": 0,
+          "top": 0,
+          "right": 0,
+          "bottom": 0
+        },
+        {
+          "left": 100,
+          "top": 300,
+          "right": 200,
+          "bottom": 400
+        },
+        {
+          "left": 98,
+          "top": 293,
+          "right": 203,
+          "bottom": 407
+        },
+        {
+          "left": 91,
+          "top": 269,
+          "right": 213,
+          "bottom": 430
+        },
+        {
+          "left": 71,
+          "top": 206,
+          "right": 240,
+          "bottom": 491
+        },
+        {
+          "left": 34,
+          "top": 98,
+          "right": 283,
+          "bottom": 595
+        },
+        {
+          "left": 22,
+          "top": 63,
+          "right": 296,
+          "bottom": 629
+        },
+        {
+          "left": 15,
+          "top": 44,
+          "right": 303,
+          "bottom": 648
+        },
+        {
+          "left": 11,
+          "top": 32,
+          "right": 308,
+          "bottom": 659
+        },
+        {
+          "left": 8,
+          "top": 23,
+          "right": 311,
+          "bottom": 667
+        },
+        {
+          "left": 6,
+          "top": 18,
+          "right": 313,
+          "bottom": 673
+        },
+        {
+          "left": 5,
+          "top": 13,
+          "right": 315,
+          "bottom": 677
+        },
+        {
+          "left": 3,
+          "top": 9,
+          "right": 316,
+          "bottom": 681
+        },
+        {
+          "left": 2,
+          "top": 7,
+          "right": 317,
+          "bottom": 683
+        },
+        {
+          "left": 2,
+          "top": 5,
+          "right": 318,
+          "bottom": 685
+        },
+        {
+          "left": 1,
+          "top": 3,
+          "right": 319,
+          "bottom": 687
+        },
+        {
+          "left": 1,
+          "top": 2,
+          "right": 319,
+          "bottom": 688
+        },
+        {
+          "left": 0,
+          "top": 1,
+          "right": 320,
+          "bottom": 689
+        },
+        {
+          "left": 0,
+          "top": 0,
+          "right": 320,
+          "bottom": 690
+        },
+        {
+          "left": 0,
+          "top": 0,
+          "right": 320,
+          "bottom": 690
+        },
+        {
+          "left": 0,
+          "top": 0,
+          "right": 320,
+          "bottom": 690
+        }
+      ]
+    },
+    {
+      "name": "corner_radii",
+      "type": "cornerRadii",
+      "data_points": [
+        null,
+        {
+          "top_left_x": 10,
+          "top_left_y": 10,
+          "top_right_x": 10,
+          "top_right_y": 10,
+          "bottom_right_x": 20,
+          "bottom_right_y": 20,
+          "bottom_left_x": 20,
+          "bottom_left_y": 20
+        },
+        {
+          "top_left_x": 9.762664,
+          "top_left_y": 9.762664,
+          "top_right_x": 9.762664,
+          "top_right_y": 9.762664,
+          "bottom_right_x": 19.525328,
+          "bottom_right_y": 19.525328,
+          "bottom_left_x": 19.525328,
+          "bottom_left_y": 19.525328
+        },
+        {
+          "top_left_x": 8.969244,
+          "top_left_y": 8.969244,
+          "top_right_x": 8.969244,
+          "top_right_y": 8.969244,
+          "bottom_right_x": 17.938488,
+          "bottom_right_y": 17.938488,
+          "bottom_left_x": 17.938488,
+          "bottom_left_y": 17.938488
+        },
+        {
+          "top_left_x": 6.8709626,
+          "top_left_y": 6.8709626,
+          "top_right_x": 6.8709626,
+          "top_right_y": 6.8709626,
+          "bottom_right_x": 13.741925,
+          "bottom_right_y": 13.741925,
+          "bottom_left_x": 13.741925,
+          "bottom_left_y": 13.741925
+        },
+        {
+          "top_left_x": 3.260561,
+          "top_left_y": 3.260561,
+          "top_right_x": 3.260561,
+          "top_right_y": 3.260561,
+          "bottom_right_x": 6.521122,
+          "bottom_right_y": 6.521122,
+          "bottom_left_x": 6.521122,
+          "bottom_left_y": 6.521122
+        },
+        {
+          "top_left_x": 2.0915751,
+          "top_left_y": 2.0915751,
+          "top_right_x": 2.0915751,
+          "top_right_y": 2.0915751,
+          "bottom_right_x": 4.1831503,
+          "bottom_right_y": 4.1831503,
+          "bottom_left_x": 4.1831503,
+          "bottom_left_y": 4.1831503
+        },
+        {
+          "top_left_x": 1.4640827,
+          "top_left_y": 1.4640827,
+          "top_right_x": 1.4640827,
+          "top_right_y": 1.4640827,
+          "bottom_right_x": 2.9281654,
+          "bottom_right_y": 2.9281654,
+          "bottom_left_x": 2.9281654,
+          "bottom_left_y": 2.9281654
+        },
+        {
+          "top_left_x": 1.057313,
+          "top_left_y": 1.057313,
+          "top_right_x": 1.057313,
+          "top_right_y": 1.057313,
+          "bottom_right_x": 2.114626,
+          "bottom_right_y": 2.114626,
+          "bottom_left_x": 2.114626,
+          "bottom_left_y": 2.114626
+        },
+        {
+          "top_left_x": 0.7824335,
+          "top_left_y": 0.7824335,
+          "top_right_x": 0.7824335,
+          "top_right_y": 0.7824335,
+          "bottom_right_x": 1.564867,
+          "bottom_right_y": 1.564867,
+          "bottom_left_x": 1.564867,
+          "bottom_left_y": 1.564867
+        },
+        {
+          "top_left_x": 0.5863056,
+          "top_left_y": 0.5863056,
+          "top_right_x": 0.5863056,
+          "top_right_y": 0.5863056,
+          "bottom_right_x": 1.1726112,
+          "bottom_right_y": 1.1726112,
+          "bottom_left_x": 1.1726112,
+          "bottom_left_y": 1.1726112
+        },
+        {
+          "top_left_x": 0.4332962,
+          "top_left_y": 0.4332962,
+          "top_right_x": 0.4332962,
+          "top_right_y": 0.4332962,
+          "bottom_right_x": 0.8665924,
+          "bottom_right_y": 0.8665924,
+          "bottom_left_x": 0.8665924,
+          "bottom_left_y": 0.8665924
+        },
+        {
+          "top_left_x": 0.3145876,
+          "top_left_y": 0.3145876,
+          "top_right_x": 0.3145876,
+          "top_right_y": 0.3145876,
+          "bottom_right_x": 0.6291752,
+          "bottom_right_y": 0.6291752,
+          "bottom_left_x": 0.6291752,
+          "bottom_left_y": 0.6291752
+        },
+        {
+          "top_left_x": 0.22506618,
+          "top_left_y": 0.22506618,
+          "top_right_x": 0.22506618,
+          "top_right_y": 0.22506618,
+          "bottom_right_x": 0.45013237,
+          "bottom_right_y": 0.45013237,
+          "bottom_left_x": 0.45013237,
+          "bottom_left_y": 0.45013237
+        },
+        {
+          "top_left_x": 0.15591621,
+          "top_left_y": 0.15591621,
+          "top_right_x": 0.15591621,
+          "top_right_y": 0.15591621,
+          "bottom_right_x": 0.31183243,
+          "bottom_right_y": 0.31183243,
+          "bottom_left_x": 0.31183243,
+          "bottom_left_y": 0.31183243
+        },
+        {
+          "top_left_x": 0.100948334,
+          "top_left_y": 0.100948334,
+          "top_right_x": 0.100948334,
+          "top_right_y": 0.100948334,
+          "bottom_right_x": 0.20189667,
+          "bottom_right_y": 0.20189667,
+          "bottom_left_x": 0.20189667,
+          "bottom_left_y": 0.20189667
+        },
+        {
+          "top_left_x": 0.06496239,
+          "top_left_y": 0.06496239,
+          "top_right_x": 0.06496239,
+          "top_right_y": 0.06496239,
+          "bottom_right_x": 0.12992477,
+          "bottom_right_y": 0.12992477,
+          "bottom_left_x": 0.12992477,
+          "bottom_left_y": 0.12992477
+        },
+        {
+          "top_left_x": 0.03526497,
+          "top_left_y": 0.03526497,
+          "top_right_x": 0.03526497,
+          "top_right_y": 0.03526497,
+          "bottom_right_x": 0.07052994,
+          "bottom_right_y": 0.07052994,
+          "bottom_left_x": 0.07052994,
+          "bottom_left_y": 0.07052994
+        },
+        {
+          "top_left_x": 0.014661789,
+          "top_left_y": 0.014661789,
+          "top_right_x": 0.014661789,
+          "top_right_y": 0.014661789,
+          "bottom_right_x": 0.029323578,
+          "bottom_right_y": 0.029323578,
+          "bottom_left_x": 0.029323578,
+          "bottom_left_y": 0.029323578
+        },
+        {
+          "top_left_x": 0.0041856766,
+          "top_left_y": 0.0041856766,
+          "top_right_x": 0.0041856766,
+          "top_right_y": 0.0041856766,
+          "bottom_right_x": 0.008371353,
+          "bottom_right_y": 0.008371353,
+          "bottom_left_x": 0.008371353,
+          "bottom_left_y": 0.008371353
+        },
+        {
+          "top_left_x": 0,
+          "top_left_y": 0,
+          "top_right_x": 0,
+          "top_right_y": 0,
+          "bottom_right_x": 0,
+          "bottom_right_y": 0,
+          "bottom_left_x": 0,
+          "bottom_left_y": 0
+        }
+      ]
+    },
+    {
+      "name": "alpha",
+      "type": "int",
+      "data_points": [
+        0,
+        255,
+        255,
+        255,
+        255,
+        255,
+        255,
+        239,
+        183,
+        135,
+        91,
+        53,
+        23,
+        5,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimation_whenLaunching.json b/packages/SystemUI/tests/goldens/backgroundAnimation_whenLaunching.json
new file mode 100644
index 0000000..608e633
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/backgroundAnimation_whenLaunching.json
@@ -0,0 +1,393 @@
+{
+  "frame_ids": [
+    "before",
+    0,
+    26,
+    52,
+    78,
+    105,
+    131,
+    157,
+    184,
+    210,
+    236,
+    263,
+    289,
+    315,
+    342,
+    368,
+    394,
+    421,
+    447,
+    473,
+    500
+  ],
+  "features": [
+    {
+      "name": "bounds",
+      "type": "rect",
+      "data_points": [
+        {
+          "left": 0,
+          "top": 0,
+          "right": 0,
+          "bottom": 0
+        },
+        {
+          "left": 100,
+          "top": 300,
+          "right": 200,
+          "bottom": 400
+        },
+        {
+          "left": 98,
+          "top": 293,
+          "right": 203,
+          "bottom": 407
+        },
+        {
+          "left": 91,
+          "top": 269,
+          "right": 213,
+          "bottom": 430
+        },
+        {
+          "left": 71,
+          "top": 206,
+          "right": 240,
+          "bottom": 491
+        },
+        {
+          "left": 34,
+          "top": 98,
+          "right": 283,
+          "bottom": 595
+        },
+        {
+          "left": 22,
+          "top": 63,
+          "right": 296,
+          "bottom": 629
+        },
+        {
+          "left": 15,
+          "top": 44,
+          "right": 303,
+          "bottom": 648
+        },
+        {
+          "left": 11,
+          "top": 32,
+          "right": 308,
+          "bottom": 659
+        },
+        {
+          "left": 8,
+          "top": 23,
+          "right": 311,
+          "bottom": 667
+        },
+        {
+          "left": 6,
+          "top": 18,
+          "right": 313,
+          "bottom": 673
+        },
+        {
+          "left": 5,
+          "top": 13,
+          "right": 315,
+          "bottom": 677
+        },
+        {
+          "left": 3,
+          "top": 9,
+          "right": 316,
+          "bottom": 681
+        },
+        {
+          "left": 2,
+          "top": 7,
+          "right": 317,
+          "bottom": 683
+        },
+        {
+          "left": 2,
+          "top": 5,
+          "right": 318,
+          "bottom": 685
+        },
+        {
+          "left": 1,
+          "top": 3,
+          "right": 319,
+          "bottom": 687
+        },
+        {
+          "left": 1,
+          "top": 2,
+          "right": 319,
+          "bottom": 688
+        },
+        {
+          "left": 0,
+          "top": 1,
+          "right": 320,
+          "bottom": 689
+        },
+        {
+          "left": 0,
+          "top": 0,
+          "right": 320,
+          "bottom": 690
+        },
+        {
+          "left": 0,
+          "top": 0,
+          "right": 320,
+          "bottom": 690
+        },
+        {
+          "left": 0,
+          "top": 0,
+          "right": 320,
+          "bottom": 690
+        }
+      ]
+    },
+    {
+      "name": "corner_radii",
+      "type": "cornerRadii",
+      "data_points": [
+        null,
+        {
+          "top_left_x": 10,
+          "top_left_y": 10,
+          "top_right_x": 10,
+          "top_right_y": 10,
+          "bottom_right_x": 20,
+          "bottom_right_y": 20,
+          "bottom_left_x": 20,
+          "bottom_left_y": 20
+        },
+        {
+          "top_left_x": 9.762664,
+          "top_left_y": 9.762664,
+          "top_right_x": 9.762664,
+          "top_right_y": 9.762664,
+          "bottom_right_x": 19.525328,
+          "bottom_right_y": 19.525328,
+          "bottom_left_x": 19.525328,
+          "bottom_left_y": 19.525328
+        },
+        {
+          "top_left_x": 8.969244,
+          "top_left_y": 8.969244,
+          "top_right_x": 8.969244,
+          "top_right_y": 8.969244,
+          "bottom_right_x": 17.938488,
+          "bottom_right_y": 17.938488,
+          "bottom_left_x": 17.938488,
+          "bottom_left_y": 17.938488
+        },
+        {
+          "top_left_x": 6.8709626,
+          "top_left_y": 6.8709626,
+          "top_right_x": 6.8709626,
+          "top_right_y": 6.8709626,
+          "bottom_right_x": 13.741925,
+          "bottom_right_y": 13.741925,
+          "bottom_left_x": 13.741925,
+          "bottom_left_y": 13.741925
+        },
+        {
+          "top_left_x": 3.260561,
+          "top_left_y": 3.260561,
+          "top_right_x": 3.260561,
+          "top_right_y": 3.260561,
+          "bottom_right_x": 6.521122,
+          "bottom_right_y": 6.521122,
+          "bottom_left_x": 6.521122,
+          "bottom_left_y": 6.521122
+        },
+        {
+          "top_left_x": 2.0915751,
+          "top_left_y": 2.0915751,
+          "top_right_x": 2.0915751,
+          "top_right_y": 2.0915751,
+          "bottom_right_x": 4.1831503,
+          "bottom_right_y": 4.1831503,
+          "bottom_left_x": 4.1831503,
+          "bottom_left_y": 4.1831503
+        },
+        {
+          "top_left_x": 1.4640827,
+          "top_left_y": 1.4640827,
+          "top_right_x": 1.4640827,
+          "top_right_y": 1.4640827,
+          "bottom_right_x": 2.9281654,
+          "bottom_right_y": 2.9281654,
+          "bottom_left_x": 2.9281654,
+          "bottom_left_y": 2.9281654
+        },
+        {
+          "top_left_x": 1.057313,
+          "top_left_y": 1.057313,
+          "top_right_x": 1.057313,
+          "top_right_y": 1.057313,
+          "bottom_right_x": 2.114626,
+          "bottom_right_y": 2.114626,
+          "bottom_left_x": 2.114626,
+          "bottom_left_y": 2.114626
+        },
+        {
+          "top_left_x": 0.7824335,
+          "top_left_y": 0.7824335,
+          "top_right_x": 0.7824335,
+          "top_right_y": 0.7824335,
+          "bottom_right_x": 1.564867,
+          "bottom_right_y": 1.564867,
+          "bottom_left_x": 1.564867,
+          "bottom_left_y": 1.564867
+        },
+        {
+          "top_left_x": 0.5863056,
+          "top_left_y": 0.5863056,
+          "top_right_x": 0.5863056,
+          "top_right_y": 0.5863056,
+          "bottom_right_x": 1.1726112,
+          "bottom_right_y": 1.1726112,
+          "bottom_left_x": 1.1726112,
+          "bottom_left_y": 1.1726112
+        },
+        {
+          "top_left_x": 0.4332962,
+          "top_left_y": 0.4332962,
+          "top_right_x": 0.4332962,
+          "top_right_y": 0.4332962,
+          "bottom_right_x": 0.8665924,
+          "bottom_right_y": 0.8665924,
+          "bottom_left_x": 0.8665924,
+          "bottom_left_y": 0.8665924
+        },
+        {
+          "top_left_x": 0.3145876,
+          "top_left_y": 0.3145876,
+          "top_right_x": 0.3145876,
+          "top_right_y": 0.3145876,
+          "bottom_right_x": 0.6291752,
+          "bottom_right_y": 0.6291752,
+          "bottom_left_x": 0.6291752,
+          "bottom_left_y": 0.6291752
+        },
+        {
+          "top_left_x": 0.22506618,
+          "top_left_y": 0.22506618,
+          "top_right_x": 0.22506618,
+          "top_right_y": 0.22506618,
+          "bottom_right_x": 0.45013237,
+          "bottom_right_y": 0.45013237,
+          "bottom_left_x": 0.45013237,
+          "bottom_left_y": 0.45013237
+        },
+        {
+          "top_left_x": 0.15591621,
+          "top_left_y": 0.15591621,
+          "top_right_x": 0.15591621,
+          "top_right_y": 0.15591621,
+          "bottom_right_x": 0.31183243,
+          "bottom_right_y": 0.31183243,
+          "bottom_left_x": 0.31183243,
+          "bottom_left_y": 0.31183243
+        },
+        {
+          "top_left_x": 0.100948334,
+          "top_left_y": 0.100948334,
+          "top_right_x": 0.100948334,
+          "top_right_y": 0.100948334,
+          "bottom_right_x": 0.20189667,
+          "bottom_right_y": 0.20189667,
+          "bottom_left_x": 0.20189667,
+          "bottom_left_y": 0.20189667
+        },
+        {
+          "top_left_x": 0.06496239,
+          "top_left_y": 0.06496239,
+          "top_right_x": 0.06496239,
+          "top_right_y": 0.06496239,
+          "bottom_right_x": 0.12992477,
+          "bottom_right_y": 0.12992477,
+          "bottom_left_x": 0.12992477,
+          "bottom_left_y": 0.12992477
+        },
+        {
+          "top_left_x": 0.03526497,
+          "top_left_y": 0.03526497,
+          "top_right_x": 0.03526497,
+          "top_right_y": 0.03526497,
+          "bottom_right_x": 0.07052994,
+          "bottom_right_y": 0.07052994,
+          "bottom_left_x": 0.07052994,
+          "bottom_left_y": 0.07052994
+        },
+        {
+          "top_left_x": 0.014661789,
+          "top_left_y": 0.014661789,
+          "top_right_x": 0.014661789,
+          "top_right_y": 0.014661789,
+          "bottom_right_x": 0.029323578,
+          "bottom_right_y": 0.029323578,
+          "bottom_left_x": 0.029323578,
+          "bottom_left_y": 0.029323578
+        },
+        {
+          "top_left_x": 0.0041856766,
+          "top_left_y": 0.0041856766,
+          "top_right_x": 0.0041856766,
+          "top_right_y": 0.0041856766,
+          "bottom_right_x": 0.008371353,
+          "bottom_right_y": 0.008371353,
+          "bottom_left_x": 0.008371353,
+          "bottom_left_y": 0.008371353
+        },
+        {
+          "top_left_x": 0,
+          "top_left_y": 0,
+          "top_right_x": 0,
+          "top_right_y": 0,
+          "bottom_right_x": 0,
+          "bottom_right_y": 0,
+          "bottom_left_x": 0,
+          "bottom_left_y": 0
+        }
+      ]
+    },
+    {
+      "name": "alpha",
+      "type": "int",
+      "data_points": [
+        0,
+        0,
+        115,
+        178,
+        217,
+        241,
+        253,
+        239,
+        183,
+        135,
+        91,
+        53,
+        23,
+        5,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/goldens/backgroundAnimation_whenReturning.json b/packages/SystemUI/tests/goldens/backgroundAnimation_whenReturning.json
new file mode 100644
index 0000000..608e633
--- /dev/null
+++ b/packages/SystemUI/tests/goldens/backgroundAnimation_whenReturning.json
@@ -0,0 +1,393 @@
+{
+  "frame_ids": [
+    "before",
+    0,
+    26,
+    52,
+    78,
+    105,
+    131,
+    157,
+    184,
+    210,
+    236,
+    263,
+    289,
+    315,
+    342,
+    368,
+    394,
+    421,
+    447,
+    473,
+    500
+  ],
+  "features": [
+    {
+      "name": "bounds",
+      "type": "rect",
+      "data_points": [
+        {
+          "left": 0,
+          "top": 0,
+          "right": 0,
+          "bottom": 0
+        },
+        {
+          "left": 100,
+          "top": 300,
+          "right": 200,
+          "bottom": 400
+        },
+        {
+          "left": 98,
+          "top": 293,
+          "right": 203,
+          "bottom": 407
+        },
+        {
+          "left": 91,
+          "top": 269,
+          "right": 213,
+          "bottom": 430
+        },
+        {
+          "left": 71,
+          "top": 206,
+          "right": 240,
+          "bottom": 491
+        },
+        {
+          "left": 34,
+          "top": 98,
+          "right": 283,
+          "bottom": 595
+        },
+        {
+          "left": 22,
+          "top": 63,
+          "right": 296,
+          "bottom": 629
+        },
+        {
+          "left": 15,
+          "top": 44,
+          "right": 303,
+          "bottom": 648
+        },
+        {
+          "left": 11,
+          "top": 32,
+          "right": 308,
+          "bottom": 659
+        },
+        {
+          "left": 8,
+          "top": 23,
+          "right": 311,
+          "bottom": 667
+        },
+        {
+          "left": 6,
+          "top": 18,
+          "right": 313,
+          "bottom": 673
+        },
+        {
+          "left": 5,
+          "top": 13,
+          "right": 315,
+          "bottom": 677
+        },
+        {
+          "left": 3,
+          "top": 9,
+          "right": 316,
+          "bottom": 681
+        },
+        {
+          "left": 2,
+          "top": 7,
+          "right": 317,
+          "bottom": 683
+        },
+        {
+          "left": 2,
+          "top": 5,
+          "right": 318,
+          "bottom": 685
+        },
+        {
+          "left": 1,
+          "top": 3,
+          "right": 319,
+          "bottom": 687
+        },
+        {
+          "left": 1,
+          "top": 2,
+          "right": 319,
+          "bottom": 688
+        },
+        {
+          "left": 0,
+          "top": 1,
+          "right": 320,
+          "bottom": 689
+        },
+        {
+          "left": 0,
+          "top": 0,
+          "right": 320,
+          "bottom": 690
+        },
+        {
+          "left": 0,
+          "top": 0,
+          "right": 320,
+          "bottom": 690
+        },
+        {
+          "left": 0,
+          "top": 0,
+          "right": 320,
+          "bottom": 690
+        }
+      ]
+    },
+    {
+      "name": "corner_radii",
+      "type": "cornerRadii",
+      "data_points": [
+        null,
+        {
+          "top_left_x": 10,
+          "top_left_y": 10,
+          "top_right_x": 10,
+          "top_right_y": 10,
+          "bottom_right_x": 20,
+          "bottom_right_y": 20,
+          "bottom_left_x": 20,
+          "bottom_left_y": 20
+        },
+        {
+          "top_left_x": 9.762664,
+          "top_left_y": 9.762664,
+          "top_right_x": 9.762664,
+          "top_right_y": 9.762664,
+          "bottom_right_x": 19.525328,
+          "bottom_right_y": 19.525328,
+          "bottom_left_x": 19.525328,
+          "bottom_left_y": 19.525328
+        },
+        {
+          "top_left_x": 8.969244,
+          "top_left_y": 8.969244,
+          "top_right_x": 8.969244,
+          "top_right_y": 8.969244,
+          "bottom_right_x": 17.938488,
+          "bottom_right_y": 17.938488,
+          "bottom_left_x": 17.938488,
+          "bottom_left_y": 17.938488
+        },
+        {
+          "top_left_x": 6.8709626,
+          "top_left_y": 6.8709626,
+          "top_right_x": 6.8709626,
+          "top_right_y": 6.8709626,
+          "bottom_right_x": 13.741925,
+          "bottom_right_y": 13.741925,
+          "bottom_left_x": 13.741925,
+          "bottom_left_y": 13.741925
+        },
+        {
+          "top_left_x": 3.260561,
+          "top_left_y": 3.260561,
+          "top_right_x": 3.260561,
+          "top_right_y": 3.260561,
+          "bottom_right_x": 6.521122,
+          "bottom_right_y": 6.521122,
+          "bottom_left_x": 6.521122,
+          "bottom_left_y": 6.521122
+        },
+        {
+          "top_left_x": 2.0915751,
+          "top_left_y": 2.0915751,
+          "top_right_x": 2.0915751,
+          "top_right_y": 2.0915751,
+          "bottom_right_x": 4.1831503,
+          "bottom_right_y": 4.1831503,
+          "bottom_left_x": 4.1831503,
+          "bottom_left_y": 4.1831503
+        },
+        {
+          "top_left_x": 1.4640827,
+          "top_left_y": 1.4640827,
+          "top_right_x": 1.4640827,
+          "top_right_y": 1.4640827,
+          "bottom_right_x": 2.9281654,
+          "bottom_right_y": 2.9281654,
+          "bottom_left_x": 2.9281654,
+          "bottom_left_y": 2.9281654
+        },
+        {
+          "top_left_x": 1.057313,
+          "top_left_y": 1.057313,
+          "top_right_x": 1.057313,
+          "top_right_y": 1.057313,
+          "bottom_right_x": 2.114626,
+          "bottom_right_y": 2.114626,
+          "bottom_left_x": 2.114626,
+          "bottom_left_y": 2.114626
+        },
+        {
+          "top_left_x": 0.7824335,
+          "top_left_y": 0.7824335,
+          "top_right_x": 0.7824335,
+          "top_right_y": 0.7824335,
+          "bottom_right_x": 1.564867,
+          "bottom_right_y": 1.564867,
+          "bottom_left_x": 1.564867,
+          "bottom_left_y": 1.564867
+        },
+        {
+          "top_left_x": 0.5863056,
+          "top_left_y": 0.5863056,
+          "top_right_x": 0.5863056,
+          "top_right_y": 0.5863056,
+          "bottom_right_x": 1.1726112,
+          "bottom_right_y": 1.1726112,
+          "bottom_left_x": 1.1726112,
+          "bottom_left_y": 1.1726112
+        },
+        {
+          "top_left_x": 0.4332962,
+          "top_left_y": 0.4332962,
+          "top_right_x": 0.4332962,
+          "top_right_y": 0.4332962,
+          "bottom_right_x": 0.8665924,
+          "bottom_right_y": 0.8665924,
+          "bottom_left_x": 0.8665924,
+          "bottom_left_y": 0.8665924
+        },
+        {
+          "top_left_x": 0.3145876,
+          "top_left_y": 0.3145876,
+          "top_right_x": 0.3145876,
+          "top_right_y": 0.3145876,
+          "bottom_right_x": 0.6291752,
+          "bottom_right_y": 0.6291752,
+          "bottom_left_x": 0.6291752,
+          "bottom_left_y": 0.6291752
+        },
+        {
+          "top_left_x": 0.22506618,
+          "top_left_y": 0.22506618,
+          "top_right_x": 0.22506618,
+          "top_right_y": 0.22506618,
+          "bottom_right_x": 0.45013237,
+          "bottom_right_y": 0.45013237,
+          "bottom_left_x": 0.45013237,
+          "bottom_left_y": 0.45013237
+        },
+        {
+          "top_left_x": 0.15591621,
+          "top_left_y": 0.15591621,
+          "top_right_x": 0.15591621,
+          "top_right_y": 0.15591621,
+          "bottom_right_x": 0.31183243,
+          "bottom_right_y": 0.31183243,
+          "bottom_left_x": 0.31183243,
+          "bottom_left_y": 0.31183243
+        },
+        {
+          "top_left_x": 0.100948334,
+          "top_left_y": 0.100948334,
+          "top_right_x": 0.100948334,
+          "top_right_y": 0.100948334,
+          "bottom_right_x": 0.20189667,
+          "bottom_right_y": 0.20189667,
+          "bottom_left_x": 0.20189667,
+          "bottom_left_y": 0.20189667
+        },
+        {
+          "top_left_x": 0.06496239,
+          "top_left_y": 0.06496239,
+          "top_right_x": 0.06496239,
+          "top_right_y": 0.06496239,
+          "bottom_right_x": 0.12992477,
+          "bottom_right_y": 0.12992477,
+          "bottom_left_x": 0.12992477,
+          "bottom_left_y": 0.12992477
+        },
+        {
+          "top_left_x": 0.03526497,
+          "top_left_y": 0.03526497,
+          "top_right_x": 0.03526497,
+          "top_right_y": 0.03526497,
+          "bottom_right_x": 0.07052994,
+          "bottom_right_y": 0.07052994,
+          "bottom_left_x": 0.07052994,
+          "bottom_left_y": 0.07052994
+        },
+        {
+          "top_left_x": 0.014661789,
+          "top_left_y": 0.014661789,
+          "top_right_x": 0.014661789,
+          "top_right_y": 0.014661789,
+          "bottom_right_x": 0.029323578,
+          "bottom_right_y": 0.029323578,
+          "bottom_left_x": 0.029323578,
+          "bottom_left_y": 0.029323578
+        },
+        {
+          "top_left_x": 0.0041856766,
+          "top_left_y": 0.0041856766,
+          "top_right_x": 0.0041856766,
+          "top_right_y": 0.0041856766,
+          "bottom_right_x": 0.008371353,
+          "bottom_right_y": 0.008371353,
+          "bottom_left_x": 0.008371353,
+          "bottom_left_y": 0.008371353
+        },
+        {
+          "top_left_x": 0,
+          "top_left_y": 0,
+          "top_right_x": 0,
+          "top_right_y": 0,
+          "bottom_right_x": 0,
+          "bottom_right_y": 0,
+          "bottom_left_x": 0,
+          "bottom_left_y": 0
+        }
+      ]
+    },
+    {
+      "name": "alpha",
+      "type": "int",
+      "data_points": [
+        0,
+        0,
+        115,
+        178,
+        217,
+        241,
+        253,
+        239,
+        183,
+        135,
+        91,
+        53,
+        23,
+        5,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
index 3d0d8fb..ca55dd8 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt
@@ -142,6 +142,7 @@
                 context.resources,
                 context,
                 mainExecutor,
+                IMMEDIATE,
                 bgExecutor,
                 clockBuffers,
                 withDeps.featureFlags,
@@ -329,7 +330,8 @@
                 TransitionStep(
                     from = KeyguardState.LOCKSCREEN,
                     to = KeyguardState.AOD,
-                    value = 0.4f
+                    value = 0.4f,
+                    transitionState = TransitionState.RUNNING,
                 )
             yield()
 
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerBaseTest.java
similarity index 98%
rename from packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
rename to packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerBaseTest.java
index 1c77351..f924ab4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerBaseTest.java
@@ -68,7 +68,7 @@
 import org.mockito.MockitoSession;
 import org.mockito.quality.Strictness;
 
-public class LockIconViewControllerBaseTest extends SysuiTestCase {
+public class LegacyLockIconViewControllerBaseTest extends SysuiTestCase {
     protected static final String UNLOCKED_LABEL = "unlocked";
     protected static final String LOCKED_LABEL = "locked";
     protected static final int PADDING = 10;
@@ -98,7 +98,7 @@
 
     protected @Mock PrimaryBouncerInteractor mPrimaryBouncerInteractor;
 
-    protected LockIconViewController mUnderTest;
+    protected LegacyLockIconViewController mUnderTest;
 
     // Capture listeners so that they can be used to send events
     @Captor protected ArgumentCaptor<View.OnAttachStateChangeListener> mAttachCaptor =
@@ -153,7 +153,7 @@
         mFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
         mFeatureFlags.set(LOCKSCREEN_ENABLE_LANDSCAPE, false);
 
-        mUnderTest = new LockIconViewController(
+        mUnderTest = new LegacyLockIconViewController(
                 mStatusBarStateController,
                 mKeyguardUpdateMonitor,
                 mKeyguardViewController,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java
similarity index 99%
rename from packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
rename to packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java
index b0887ef..8689842 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerTest.java
@@ -51,7 +51,7 @@
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
-public class LockIconViewControllerTest extends LockIconViewControllerBaseTest {
+public class LegacyLockIconViewControllerTest extends LegacyLockIconViewControllerBaseTest {
 
     @Override
     public void setUp() throws Exception {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt
similarity index 98%
rename from packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerWithCoroutinesTest.kt
rename to packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt
index 1213518..25a87b8 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LegacyLockIconViewControllerWithCoroutinesTest.kt
@@ -39,7 +39,7 @@
 
 @RunWith(AndroidTestingRunner::class)
 @SmallTest
-class LockIconViewControllerWithCoroutinesTest : LockIconViewControllerBaseTest() {
+class LegacyLockIconViewControllerWithCoroutinesTest : LegacyLockIconViewControllerBaseTest() {
 
     /** After migration, replaces LockIconViewControllerTest version */
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index f1b0c18..6f285fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -100,6 +100,7 @@
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.res.R;
 import com.android.systemui.settings.FakeDisplayTracker;
+import com.android.systemui.util.FakeSharedPreferences;
 import com.android.systemui.util.leak.ReferenceTestUtils;
 import com.android.systemui.util.settings.SecureSettings;
 import com.android.systemui.utils.os.FakeHandler;
@@ -169,6 +170,7 @@
     private View.OnTouchListener mTouchListener;
     private MotionEventHelper mMotionEventHelper = new MotionEventHelper();
     private KosmosJavaAdapter mKosmos;
+    private FakeSharedPreferences mSharedPreferences;
 
     /**
      *  return whether window magnification is supported for current test context.
@@ -180,6 +182,7 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        mContext = spy(mContext);
         mKosmos = new KosmosJavaAdapter(this);
         mContext = Mockito.spy(getContext());
         mHandler = new FakeHandler(TestableLooper.get(this).getLooper());
@@ -219,6 +222,10 @@
 
         mWindowMagnificationAnimationController = new WindowMagnificationAnimationController(
                 mContext, mValueAnimator);
+        mSharedPreferences = new FakeSharedPreferences();
+        when(mContext.getSharedPreferences(
+                eq("window_magnification_preferences"), anyInt()))
+                .thenReturn(mSharedPreferences);
         mWindowMagnificationController =
                 new WindowMagnificationController(
                         mContext,
@@ -249,7 +256,9 @@
     @After
     public void tearDown() {
         mInstrumentation.runOnMainSync(
-                () -> mWindowMagnificationController.deleteWindowMagnification());
+                () -> {
+                    mWindowMagnificationController.deleteWindowMagnification();
+                });
         mValueAnimator.cancel();
     }
 
@@ -600,22 +609,41 @@
     }
 
     @Test
-    public void onScreenChangedToSavedDensity_enabled_restoreSavedMagnifierWindow() {
-        mContext.getResources().getConfiguration().smallestScreenWidthDp =
+    public void onScreenSizeAndDensityChanged_enabled_restoreSavedMagnifierWindow() {
+        int newSmallestScreenWidthDp =
                 mContext.getResources().getConfiguration().smallestScreenWidthDp * 2;
         int windowFrameSize = mResources.getDimensionPixelSize(
                 com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
-        mWindowMagnificationController.mWindowMagnificationSizePrefs.saveSizeForCurrentDensity(
-                new Size(windowFrameSize, windowFrameSize));
-
+        Size preferredWindowSize = new Size(windowFrameSize, windowFrameSize);
+        mSharedPreferences
+                .edit()
+                .putString(String.valueOf(newSmallestScreenWidthDp),
+                        preferredWindowSize.toString())
+                .commit();
         mInstrumentation.runOnMainSync(() -> {
-            mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
-                    Float.NaN);
+            mWindowMagnificationController
+                    .enableWindowMagnificationInternal(Float.NaN, Float.NaN, Float.NaN);
         });
 
+        // Change screen density and size to trigger restoring the preferred window size
+        mContext.getResources().getConfiguration().smallestScreenWidthDp = newSmallestScreenWidthDp;
+        final Rect testWindowBounds = new Rect(
+                mWindowManager.getCurrentWindowMetrics().getBounds());
+        testWindowBounds.set(testWindowBounds.left, testWindowBounds.top,
+                testWindowBounds.right + 100, testWindowBounds.bottom + 100);
+        mWindowManager.setWindowBounds(testWindowBounds);
+        mInstrumentation.runOnMainSync(() -> {
+            mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_SCREEN_SIZE);
+        });
+
+        // wait for rect update
+        waitForIdleSync();
         WindowManager.LayoutParams params = mWindowManager.getLayoutParamsFromAttachedView();
-        assertTrue(params.width == windowFrameSize);
-        assertTrue(params.height == windowFrameSize);
+        final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
+                R.dimen.magnification_mirror_surface_margin);
+        // The width and height of the view include the magnification frame and the margins.
+        assertTrue(params.width == (windowFrameSize + 2 * mirrorSurfaceMargin));
+        assertTrue(params.height == (windowFrameSize + 2 * mirrorSurfaceMargin));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
index cbdc696..e9d36b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
@@ -102,6 +102,7 @@
 import com.android.systemui.model.SysUiState;
 import com.android.systemui.res.R;
 import com.android.systemui.settings.FakeDisplayTracker;
+import com.android.systemui.util.FakeSharedPreferences;
 import com.android.systemui.util.leak.ReferenceTestUtils;
 import com.android.systemui.util.settings.SecureSettings;
 import com.android.systemui.utils.os.FakeHandler;
@@ -176,6 +177,7 @@
     // The most recently created SurfaceControlViewHost.
     private SurfaceControlViewHost mSurfaceControlViewHost;
     private KosmosJavaAdapter mKosmos;
+    private FakeSharedPreferences mSharedPreferences;
 
     /**
      *  return whether window magnification is supported for current test context.
@@ -187,6 +189,7 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        mContext = spy(mContext);
         mKosmos = new KosmosJavaAdapter(this);
         mContext = Mockito.spy(getContext());
         mHandler = new FakeHandler(TestableLooper.get(this).getLooper());
@@ -228,6 +231,10 @@
             return mSurfaceControlViewHost;
         };
         mTransaction = spy(new SurfaceControl.Transaction());
+        mSharedPreferences = new FakeSharedPreferences();
+        when(mContext.getSharedPreferences(
+                eq("window_magnification_preferences"), anyInt()))
+                .thenReturn(mSharedPreferences);
         mWindowMagnificationController =
                 new WindowMagnificationController(
                         mContext,
@@ -258,7 +265,9 @@
     @After
     public void tearDown() {
         mInstrumentation.runOnMainSync(
-                () -> mWindowMagnificationController.deleteWindowMagnification());
+                () -> {
+                    mWindowMagnificationController.deleteWindowMagnification();
+                });
         mValueAnimator.cancel();
     }
 
@@ -614,22 +623,41 @@
     }
 
     @Test
-    public void onScreenChangedToSavedDensity_enabled_restoreSavedMagnifierWindow() {
-        mContext.getResources().getConfiguration().smallestScreenWidthDp =
+    public void onScreenSizeAndDensityChanged_enabled_restoreSavedMagnifierWindow() {
+        int newSmallestScreenWidthDp =
                 mContext.getResources().getConfiguration().smallestScreenWidthDp * 2;
         int windowFrameSize = mResources.getDimensionPixelSize(
                 com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
-        mWindowMagnificationController.mWindowMagnificationSizePrefs.saveSizeForCurrentDensity(
-                new Size(windowFrameSize, windowFrameSize));
-
+        Size preferredWindowSize = new Size(windowFrameSize, windowFrameSize);
+        mSharedPreferences
+                .edit()
+                .putString(String.valueOf(newSmallestScreenWidthDp),
+                        preferredWindowSize.toString())
+                .commit();
         mInstrumentation.runOnMainSync(() -> {
-            mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
-                    Float.NaN);
+            mWindowMagnificationController
+                    .enableWindowMagnificationInternal(Float.NaN, Float.NaN, Float.NaN);
         });
 
+        // Screen density and size change
+        mContext.getResources().getConfiguration().smallestScreenWidthDp = newSmallestScreenWidthDp;
+        final Rect testWindowBounds = new Rect(
+                mWindowManager.getCurrentWindowMetrics().getBounds());
+        testWindowBounds.set(testWindowBounds.left, testWindowBounds.top,
+                testWindowBounds.right + 100, testWindowBounds.bottom + 100);
+        mWindowManager.setWindowBounds(testWindowBounds);
+        mInstrumentation.runOnMainSync(() -> {
+            mWindowMagnificationController.onConfigurationChanged(ActivityInfo.CONFIG_SCREEN_SIZE);
+        });
+
+        // wait for rect update
+        waitForIdleSync();
         ViewGroup.LayoutParams params = mSurfaceControlViewHost.getView().getLayoutParams();
-        assertTrue(params.width == windowFrameSize);
-        assertTrue(params.height == windowFrameSize);
+        final int mirrorSurfaceMargin = mResources.getDimensionPixelSize(
+                R.dimen.magnification_mirror_surface_margin);
+        // The width and height of the view include the magnification frame and the margins.
+        assertTrue(params.width == (windowFrameSize + 2 * mirrorSurfaceMargin));
+        assertTrue(params.height == (windowFrameSize + 2 * mirrorSurfaceMargin));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSizePrefsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSizePrefsTest.java
index 04b0d70..b843fda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSizePrefsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationSizePrefsTest.java
@@ -18,13 +18,20 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.util.Size;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.util.FakeSharedPreferences;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -33,8 +40,18 @@
 @TestableLooper.RunWithLooper
 public class WindowMagnificationSizePrefsTest extends SysuiTestCase {
 
-    WindowMagnificationSizePrefs mWindowMagnificationSizePrefs =
-            new WindowMagnificationSizePrefs(mContext);
+    WindowMagnificationSizePrefs mWindowMagnificationSizePrefs;
+    FakeSharedPreferences mSharedPreferences;
+
+    @Before
+    public void setUp() {
+        mContext = spy(mContext);
+        mSharedPreferences = new FakeSharedPreferences();
+        when(mContext.getSharedPreferences(
+                eq("window_magnification_preferences"), anyInt()))
+                .thenReturn(mSharedPreferences);
+        mWindowMagnificationSizePrefs = new WindowMagnificationSizePrefs(mContext);
+    }
 
     @Test
     public void saveSizeForCurrentDensity_getExpectedSize() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
index de696f4..05d7560 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
@@ -165,7 +165,7 @@
         mMenuView = spy(
                 new MenuView(mSpyContext, mMenuViewModel, menuViewAppearance, mSecureSettings));
         // Ensure tests don't actually update metrics.
-        doNothing().when(mMenuView).incrementTexMetric(any(), anyInt());
+        doNothing().when(mMenuView).incrementTexMetric(any());
 
         mMenuViewLayer = spy(new MenuViewLayer(mSpyContext, mStubWindowManager,
                 mStubAccessibilityManager, mMenuViewModel, menuViewAppearance, mMenuView,
@@ -232,7 +232,7 @@
         final List<String> stubShortcutTargets = new ArrayList<>();
         stubShortcutTargets.add(TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString());
         when(mStubAccessibilityManager.getAccessibilityShortcutTargets(
-                AccessibilityManager.ACCESSIBILITY_BUTTON)).thenReturn(stubShortcutTargets);
+                ShortcutConstants.UserShortcutType.SOFTWARE)).thenReturn(stubShortcutTargets);
 
         mMenuViewLayer.mDismissMenuAction.run();
 
@@ -271,7 +271,7 @@
         final List<String> stubShortcutTargets = new ArrayList<>();
         stubShortcutTargets.add(TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString());
         when(mStubAccessibilityManager.getAccessibilityShortcutTargets(
-                AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY)).thenReturn(stubShortcutTargets);
+                ShortcutConstants.UserShortcutType.HARDWARE)).thenReturn(stubShortcutTargets);
 
         mMenuViewLayer.mDismissMenuAction.run();
         final String value = Settings.Secure.getString(mSpyContext.getContentResolver(),
@@ -414,40 +414,32 @@
     @Test
     @EnableFlags(Flags.FLAG_FLOATING_MENU_DRAG_TO_EDIT)
     public void onDismissAction_incrementsTexMetricDismiss() {
-        int uid1 = 1234, uid2 = 5678;
         mMenuViewModel.onTargetFeaturesChanged(
-                List.of(new TestAccessibilityTarget(mSpyContext, uid1),
-                        new TestAccessibilityTarget(mSpyContext, uid2)));
+                List.of(new TestAccessibilityTarget(mSpyContext, 1234),
+                        new TestAccessibilityTarget(mSpyContext, 5678)));
 
         mMenuViewLayer.dispatchAccessibilityAction(R.id.action_remove_menu);
 
-        ArgumentCaptor<Integer> uidCaptor = ArgumentCaptor.forClass(Integer.class);
-        verify(mMenuView, times(2)).incrementTexMetric(eq(MenuViewLayer.TEX_METRIC_DISMISS),
-                uidCaptor.capture());
-        assertThat(uidCaptor.getAllValues()).containsExactly(uid1, uid2);
+        verify(mMenuView, times(1)).incrementTexMetric(eq(MenuViewLayer.TEX_METRIC_DISMISS));
     }
 
     @Test
     @EnableFlags(Flags.FLAG_FLOATING_MENU_DRAG_TO_EDIT)
     public void onEditAction_incrementsTexMetricEdit() {
-        int uid1 = 1234, uid2 = 5678;
         mMenuViewModel.onTargetFeaturesChanged(
-                List.of(new TestAccessibilityTarget(mSpyContext, uid1),
-                        new TestAccessibilityTarget(mSpyContext, uid2)));
+                List.of(new TestAccessibilityTarget(mSpyContext, 1234),
+                        new TestAccessibilityTarget(mSpyContext, 5678)));
 
         mMenuViewLayer.dispatchAccessibilityAction(R.id.action_edit);
 
-        ArgumentCaptor<Integer> uidCaptor = ArgumentCaptor.forClass(Integer.class);
-        verify(mMenuView, times(2)).incrementTexMetric(eq(MenuViewLayer.TEX_METRIC_EDIT),
-                uidCaptor.capture());
-        assertThat(uidCaptor.getAllValues()).containsExactly(uid1, uid2);
+        verify(mMenuView, times(1)).incrementTexMetric(eq(MenuViewLayer.TEX_METRIC_EDIT));
     }
 
     /** Simplified AccessibilityTarget for testing MenuViewLayer. */
     private static class TestAccessibilityTarget extends AccessibilityTarget {
         TestAccessibilityTarget(Context context, int uid) {
             // Set fields unused by tests to defaults that allow test compilation.
-            super(context, AccessibilityManager.ACCESSIBILITY_BUTTON, 0, false,
+            super(context, ShortcutConstants.UserShortcutType.SOFTWARE, 0, false,
                     TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString(), uid, null, null, null);
         }
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
new file mode 100644
index 0000000..b0f0363
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility.hearingaid;
+
+import static com.android.systemui.statusbar.phone.SystemUIDialog.DEFAULT_DISMISS_ON_DEVICE_LOCK;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Intent;
+import android.media.AudioManager;
+import android.os.Handler;
+import android.provider.Settings;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.View;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.settingslib.bluetooth.BluetoothEventManager;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.animation.DialogTransitionAnimator;
+import com.android.systemui.model.SysUiState;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.qs.tiles.dialog.bluetooth.DeviceItem;
+import com.android.systemui.qs.tiles.dialog.bluetooth.DeviceItemType;
+import com.android.systemui.res.R;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+import com.android.systemui.statusbar.phone.SystemUIDialogManager;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Tests for {@link HearingDevicesDialogDelegate}. */
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+public class HearingDevicesDialogDelegateTest extends SysuiTestCase {
+    @Rule
+    public MockitoRule mockito = MockitoJUnit.rule();
+
+    private static final String DEVICE_ADDRESS = "AA:BB:CC:DD:EE:FF";
+
+    @Mock
+    private SystemUIDialog.Factory mSystemUIDialogFactory;
+    @Mock
+    private SystemUIDialogManager mSystemUIDialogManager;
+    @Mock
+    private SysUiState mSysUiState;
+    @Mock
+    private DialogTransitionAnimator mDialogTransitionAnimator;
+    @Mock
+    private ActivityStarter mActivityStarter;
+    @Mock
+    private LocalBluetoothManager mLocalBluetoothManager;
+    @Mock
+    private LocalBluetoothAdapter mLocalBluetoothAdapter;
+    @Mock
+    private CachedBluetoothDeviceManager mCachedDeviceManager;
+    @Mock
+    private BluetoothEventManager mBluetoothEventManager;
+    @Mock
+    private AudioManager mAudioManager;
+    @Mock
+    private CachedBluetoothDevice mCachedDevice;
+    @Mock
+    private DeviceItem mHearingDeviceItem;
+    private SystemUIDialog mDialog;
+    private HearingDevicesDialogDelegate mDialogDelegate;
+    private TestableLooper mTestableLooper;
+    private final List<CachedBluetoothDevice> mDevices = new ArrayList<>();
+
+    @Before
+    public void setUp() {
+        mTestableLooper = TestableLooper.get(this);
+        when(mLocalBluetoothManager.getBluetoothAdapter()).thenReturn(mLocalBluetoothAdapter);
+        when(mLocalBluetoothAdapter.isEnabled()).thenReturn(true);
+        when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mCachedDeviceManager);
+        when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mDevices);
+        when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
+        when(mSysUiState.setFlag(anyInt(), anyBoolean())).thenReturn(mSysUiState);
+        when(mCachedDevice.getAddress()).thenReturn(DEVICE_ADDRESS);
+        when(mHearingDeviceItem.getCachedBluetoothDevice()).thenReturn(mCachedDevice);
+
+        setUpPairNewDeviceDialog();
+
+        when(mSystemUIDialogFactory.create(any(SystemUIDialog.Delegate.class)))
+                .thenReturn(mDialog);
+    }
+
+    @Test
+    public void createDialog_dialogShown() {
+        assertThat(mDialogDelegate.createDialog()).isEqualTo(mDialog);
+    }
+
+    @Test
+    public void clickPairNewDeviceButton_intentActionMatch() {
+        mDialog.show();
+
+        getPairNewDeviceButton(mDialog).performClick();
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mActivityStarter).postStartActivityDismissingKeyguard(intentCaptor.capture(),
+                anyInt(), any());
+        assertThat(intentCaptor.getValue().getAction()).isEqualTo(
+                Settings.ACTION_HEARING_DEVICE_PAIRING_SETTINGS);
+    }
+
+    @Test
+    public void onDeviceItemGearClicked_intentActionMatch() {
+        setUpDeviceListDialog();
+
+        mDialogDelegate.onDeviceItemGearClicked(mHearingDeviceItem, new View(mContext));
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mActivityStarter).postStartActivityDismissingKeyguard(intentCaptor.capture(),
+                anyInt(), any());
+        assertThat(intentCaptor.getValue().getAction()).isEqualTo(
+                HearingDevicesDialogDelegate.ACTION_BLUETOOTH_DEVICE_DETAILS);
+
+    }
+
+    @Test
+    public void onDeviceItemOnClicked_connectedDevice_disconnect() {
+        when(mHearingDeviceItem.getType()).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE);
+
+        mDialogDelegate.onDeviceItemOnClicked(mHearingDeviceItem, new View(mContext));
+
+        verify(mCachedDevice).disconnect();
+    }
+
+    private void setUpPairNewDeviceDialog() {
+        mDialogDelegate = new HearingDevicesDialogDelegate(
+                true,
+                mSystemUIDialogFactory,
+                mActivityStarter,
+                mDialogTransitionAnimator,
+                mLocalBluetoothManager,
+                new Handler(mTestableLooper.getLooper()),
+                mAudioManager
+        );
+        mDialog = new SystemUIDialog(
+                mContext,
+                0,
+                DEFAULT_DISMISS_ON_DEVICE_LOCK,
+                mSystemUIDialogManager,
+                mSysUiState,
+                getFakeBroadcastDispatcher(),
+                mDialogTransitionAnimator,
+                mDialogDelegate
+        );
+    }
+
+    private void setUpDeviceListDialog() {
+        mDialogDelegate = new HearingDevicesDialogDelegate(
+                false,
+                mSystemUIDialogFactory,
+                mActivityStarter,
+                mDialogTransitionAnimator,
+                mLocalBluetoothManager,
+                new Handler(mTestableLooper.getLooper()),
+                mAudioManager
+        );
+        mDialog = new SystemUIDialog(
+                mContext,
+                0,
+                DEFAULT_DISMISS_ON_DEVICE_LOCK,
+                mSystemUIDialogManager,
+                mSysUiState,
+                getFakeBroadcastDispatcher(),
+                mDialogTransitionAnimator,
+                mDialogDelegate
+        );
+    }
+
+    private View getPairNewDeviceButton(SystemUIDialog dialog) {
+        return dialog.requireViewById(R.id.pair_new_device_button);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogManagerTest.java
new file mode 100644
index 0000000..abc12ed
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogManagerTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility.hearingaid;
+
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothDevice;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.View;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.animation.DialogTransitionAnimator;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Tests for {@link HearingDevicesDialogManager}. */
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+public class HearingDevicesDialogManagerTest extends SysuiTestCase {
+
+    @Rule
+    public MockitoRule mockito = MockitoJUnit.rule();
+
+    private final View mView = new View(mContext);
+    private final List<CachedBluetoothDevice> mCachedDevices = new ArrayList<>();
+    @Mock
+    private DialogTransitionAnimator mDialogTransitionAnimator;
+    @Mock
+    private HearingDevicesDialogDelegate.Factory mDialogFactory;
+    @Mock
+    private HearingDevicesDialogDelegate mDialogDelegate;
+    @Mock
+    private SystemUIDialog mDialog;
+    @Mock
+    private LocalBluetoothManager mLocalBluetoothManager;
+    @Mock
+    private LocalBluetoothAdapter mLocalBluetoothAdapter;
+    @Mock
+    private CachedBluetoothDeviceManager mCachedBluetoothDeviceManager;
+    @Mock
+    private CachedBluetoothDevice mCachedDevice;
+
+    private HearingDevicesDialogManager mManager;
+
+    @Before
+    public void setUp() {
+        when(mDialogFactory.create(anyBoolean())).thenReturn(mDialogDelegate);
+        when(mDialogDelegate.createDialog()).thenReturn(mDialog);
+        when(mLocalBluetoothManager.getBluetoothAdapter()).thenReturn(mLocalBluetoothAdapter);
+        when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(
+                mCachedBluetoothDeviceManager);
+        when(mCachedBluetoothDeviceManager.getCachedDevicesCopy()).thenReturn(mCachedDevices);
+
+        mManager = new HearingDevicesDialogManager(
+                mDialogTransitionAnimator,
+                mDialogFactory,
+                mLocalBluetoothManager
+        );
+    }
+
+    @Test
+    public void showDialog_bluetoothDisable_showPairNewDeviceTrue() {
+        when(mLocalBluetoothAdapter.isEnabled()).thenReturn(false);
+
+        mManager.showDialog(mView);
+
+        verify(mDialogFactory).create(eq(true));
+    }
+
+    @Test
+    public void showDialog_containsHearingAid_showPairNewDeviceFalse() {
+        when(mLocalBluetoothAdapter.isEnabled()).thenReturn(true);
+        when(mCachedDevice.isHearingAidDevice()).thenReturn(true);
+        when(mCachedDevice.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+        mCachedDevices.add(mCachedDevice);
+
+        mManager.showDialog(mView);
+
+        verify(mDialogFactory).create(eq(false));
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapterTest.java
new file mode 100644
index 0000000..95d5597
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesListAdapterTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility.hearingaid;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.qs.tiles.dialog.bluetooth.DeviceItem;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Tests for {@link HearingDevicesListAdapter}. */
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@SmallTest
+public class HearingDevicesListAdapterTest extends SysuiTestCase {
+    @Rule
+    public MockitoRule mockito = MockitoJUnit.rule();
+
+    private static final String DEVICE_ADDRESS = "AA:BB:CC:DD:EE:FF";
+
+    @Mock
+    private DeviceItem mHearingDeviceItem;
+    @Mock
+    private CachedBluetoothDevice mCachedDevice;
+    @Mock
+    private HearingDevicesListAdapter.HearingDeviceItemCallback mDeviceItemCallback;
+    private HearingDevicesListAdapter mAdapter;
+
+    @Before
+    public void setUp() {
+        when(mCachedDevice.getAddress()).thenReturn(DEVICE_ADDRESS);
+        when(mHearingDeviceItem.getCachedBluetoothDevice()).thenReturn(mCachedDevice);
+    }
+
+    @Test
+    public void constructor_oneItem_getOneCount() {
+        mAdapter = new HearingDevicesListAdapter(List.of(mHearingDeviceItem), mDeviceItemCallback);
+
+        assertThat(mAdapter.getItemCount()).isEqualTo(1);
+    }
+
+    @Test
+    public void refreshDeviceItemList_oneItem_getOneCount() {
+        mAdapter = new HearingDevicesListAdapter(new ArrayList<>(), mDeviceItemCallback);
+
+        mAdapter.refreshDeviceItemList(List.of(mHearingDeviceItem));
+
+        assertThat(mAdapter.getItemCount()).isEqualTo(1);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
index 75a49d7..41974f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityTransitionAnimatorTest.kt
@@ -246,6 +246,8 @@
  */
 private class TestTransitionAnimatorController(override var transitionContainer: ViewGroup) :
     ActivityTransitionAnimator.Controller {
+    override val isLaunching: Boolean = true
+
     override fun createAnimatorState() =
         TransitionAnimator.State(
             top = 100,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/TransitionAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/TransitionAnimatorTest.kt
new file mode 100644
index 0000000..c380a51
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/TransitionAnimatorTest.kt
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.animation
+
+import android.animation.AnimatorSet
+import android.graphics.drawable.GradientDrawable
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import androidx.test.ext.junit.rules.ActivityScenarioRule
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.activity.EmptyTestActivity
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import platform.test.motion.RecordedMotion
+import platform.test.motion.Sampling.Companion.evenlySampled
+import platform.test.motion.view.DrawableFeatureCaptures
+import platform.test.motion.view.ViewMotionTestRule
+import platform.test.screenshot.DeviceEmulationRule
+import platform.test.screenshot.DeviceEmulationSpec
+import platform.test.screenshot.DisplaySpec
+import platform.test.screenshot.GoldenPathManager
+import platform.test.screenshot.PathConfig
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class TransitionAnimatorTest : SysuiTestCase() {
+    companion object {
+        private const val GOLDENS_PATH = "frameworks/base/packages/SystemUI/tests/goldens"
+
+        private val emulationSpec =
+            DeviceEmulationSpec(
+                DisplaySpec(
+                    "phone",
+                    width = 320,
+                    height = 690,
+                    densityDpi = 160,
+                )
+            )
+    }
+
+    private val pathManager = GoldenPathManager(context, GOLDENS_PATH, pathConfig = PathConfig())
+    private val transitionAnimator =
+        TransitionAnimator(
+            ActivityTransitionAnimator.TIMINGS,
+            ActivityTransitionAnimator.INTERPOLATORS
+        )
+
+    @get:Rule(order = 0) val deviceEmulationRule = DeviceEmulationRule(emulationSpec)
+    @get:Rule(order = 1) val activityRule = ActivityScenarioRule(EmptyTestActivity::class.java)
+    @get:Rule(order = 2)
+    val motionRule =
+        ViewMotionTestRule<EmptyTestActivity>(
+            pathManager,
+            { activityRule.scenario },
+            context = context,
+            bitmapDiffer = null,
+        )
+
+    @Test
+    fun backgroundAnimation_whenLaunching() {
+        val backgroundLayer = GradientDrawable().apply { alpha = 0 }
+        val animator = setUpTest(backgroundLayer, isLaunching = true)
+
+        val recordedMotion = recordMotion(backgroundLayer, animator)
+
+        motionRule.assertThat(recordedMotion).timeSeriesMatchesGolden()
+    }
+
+    @Test
+    fun backgroundAnimation_whenReturning() {
+        val backgroundLayer = GradientDrawable().apply { alpha = 0 }
+        val animator = setUpTest(backgroundLayer, isLaunching = false)
+
+        val recordedMotion = recordMotion(backgroundLayer, animator)
+
+        motionRule.assertThat(recordedMotion).timeSeriesMatchesGolden()
+    }
+
+    @Test
+    fun backgroundAnimationWithoutFade_whenLaunching() {
+        val backgroundLayer = GradientDrawable().apply { alpha = 0 }
+        val animator =
+            setUpTest(backgroundLayer, isLaunching = true, fadeWindowBackgroundLayer = false)
+
+        val recordedMotion = recordMotion(backgroundLayer, animator)
+
+        motionRule.assertThat(recordedMotion).timeSeriesMatchesGolden()
+    }
+
+    @Test
+    fun backgroundAnimationWithoutFade_whenReturning() {
+        val backgroundLayer = GradientDrawable().apply { alpha = 0 }
+        val animator =
+            setUpTest(backgroundLayer, isLaunching = false, fadeWindowBackgroundLayer = false)
+
+        val recordedMotion = recordMotion(backgroundLayer, animator)
+
+        motionRule.assertThat(recordedMotion).timeSeriesMatchesGolden()
+    }
+
+    private fun setUpTest(
+        backgroundLayer: GradientDrawable,
+        isLaunching: Boolean,
+        fadeWindowBackgroundLayer: Boolean = true,
+    ): AnimatorSet {
+        lateinit var transitionContainer: ViewGroup
+        activityRule.scenario.onActivity { activity ->
+            transitionContainer = FrameLayout(activity).apply { setBackgroundColor(0x00FF00) }
+            activity.setContentView(transitionContainer)
+        }
+        waitForIdleSync()
+
+        val controller = TestController(transitionContainer, isLaunching)
+        val animator =
+            transitionAnimator.createAnimator(
+                controller,
+                createEndState(transitionContainer),
+                backgroundLayer,
+                fadeWindowBackgroundLayer
+            )
+        return AnimatorSet().apply {
+            duration = animator.duration
+            play(animator)
+        }
+    }
+
+    private fun createEndState(container: ViewGroup): TransitionAnimator.State {
+        val containerLocation = IntArray(2)
+        container.getLocationOnScreen(containerLocation)
+        return TransitionAnimator.State(
+            left = containerLocation[0],
+            top = containerLocation[1],
+            right = containerLocation[0] + emulationSpec.display.width,
+            bottom = containerLocation[1] + emulationSpec.display.height,
+            topCornerRadius = 0f,
+            bottomCornerRadius = 0f
+        )
+    }
+
+    private fun recordMotion(
+        backgroundLayer: GradientDrawable,
+        animator: AnimatorSet
+    ): RecordedMotion {
+        return motionRule.checkThat(animator).record(
+            backgroundLayer,
+            evenlySampled(20),
+            visualCapture = null
+        ) {
+            capture(DrawableFeatureCaptures.bounds, "bounds")
+            capture(DrawableFeatureCaptures.cornerRadii, "corner_radii")
+            capture(DrawableFeatureCaptures.alpha, "alpha")
+        }
+    }
+}
+
+/**
+ * A simple implementation of [TransitionAnimator.Controller] which throws if it is called outside
+ * of the main thread.
+ */
+private class TestController(
+    override var transitionContainer: ViewGroup,
+    override val isLaunching: Boolean
+) : TransitionAnimator.Controller {
+    override fun createAnimatorState(): TransitionAnimator.State {
+        val containerLocation = IntArray(2)
+        transitionContainer.getLocationOnScreen(containerLocation)
+        return TransitionAnimator.State(
+            left = containerLocation[0] + 100,
+            top = containerLocation[1] + 300,
+            right = containerLocation[0] + 200,
+            bottom = containerLocation[1] + 400,
+            topCornerRadius = 10f,
+            bottomCornerRadius = 20f
+        )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsUtilsTest.java
index 3dcb3f8..5b6aee6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsUtilsTest.java
@@ -65,7 +65,8 @@
                 mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
                         0 /* touchX */, 0/* touchY */,
                         new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation,
-                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL)
+                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL),
+                        true /* rotatedToPortrait */
                 )
         ).isEqualTo(mTouchHints[0]);
         // touch at 90 degrees
@@ -73,7 +74,8 @@
                 mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
                         0 /* touchX */, -1/* touchY */,
                         new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation,
-                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL)
+                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL),
+                        true /* rotatedToPortrait */
                 )
         ).isEqualTo(mTouchHints[1]);
         // touch at 180 degrees
@@ -81,7 +83,8 @@
                 mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
                         -1 /* touchX */, 0/* touchY */,
                         new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation,
-                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL)
+                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL),
+                        true /* rotatedToPortrait */
                 )
         ).isEqualTo(mTouchHints[2]);
         // touch at 270 degrees
@@ -89,7 +92,8 @@
                 mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
                         0 /* touchX */, 1/* touchY */,
                         new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation,
-                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL)
+                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL),
+                        true /* rotatedToPortrait */
                 )
         ).isEqualTo(mTouchHints[3]);
     }
@@ -103,7 +107,8 @@
                 mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
                         0 /* touchX */, 0 /* touchY */,
                         new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation,
-                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL)
+                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL),
+                        true /* rotatedToPortrait */
                 )
         ).isEqualTo(mTouchHints[1]);
         // touch at 90 degrees -> 180 degrees
@@ -111,7 +116,8 @@
                 mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
                         0 /* touchX */, -1 /* touchY */,
                         new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation,
-                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL)
+                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL),
+                        true /* rotatedToPortrait */
                 )
         ).isEqualTo(mTouchHints[2]);
         // touch at 180 degrees -> 270 degrees
@@ -119,7 +125,8 @@
                 mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
                         -1 /* touchX */, 0 /* touchY */,
                         new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation,
-                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL)
+                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL),
+                        true /* rotatedToPortrait */
                 )
         ).isEqualTo(mTouchHints[3]);
         // touch at 270 degrees -> 0 degrees
@@ -127,7 +134,8 @@
                 mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
                         0 /* touchX */, 1/* touchY */,
                         new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation,
-                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL)
+                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL),
+                        true /* rotatedToPortrait */
                 )
         ).isEqualTo(mTouchHints[0]);
     }
@@ -141,7 +149,8 @@
                 mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
                         0 /* touchX */, 0/* touchY */,
                         new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation,
-                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL)
+                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL),
+                        true /* rotatedToPortrait */
                 )
         ).isEqualTo(mTouchHints[3]);
         // touch at 90 degrees -> 0 degrees
@@ -149,7 +158,8 @@
                 mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
                         0 /* touchX */, -1/* touchY */,
                         new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation,
-                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL)
+                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL),
+                        true /* rotatedToPortrait */
                 )
         ).isEqualTo(mTouchHints[0]);
         // touch at 180 degrees -> 90 degrees
@@ -157,7 +167,8 @@
                 mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
                         -1 /* touchX */, 0/* touchY */,
                         new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation,
-                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL)
+                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL),
+                        true /* rotatedToPortrait */
                 )
         ).isEqualTo(mTouchHints[1]);
         // touch at 270 degrees -> 180 degrees
@@ -165,7 +176,8 @@
                 mUdfpsUtils.onTouchOutsideOfSensorArea(true, mContext,
                         0 /* touchX */, 1/* touchY */,
                         new UdfpsOverlayParams(new Rect(), new Rect(), 0, 0, 1f, rotation,
-                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL)
+                                FingerprintSensorProperties.TYPE_UDFPS_OPTICAL),
+                        true /* rotatedToPortrait */
                 )
         ).isEqualTo(mTouchHints[2]);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
index d4a0c8f..30c5e6e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/binder/SideFpsOverlayViewBinderTest.kt
@@ -77,6 +77,8 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.shared.Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
 import com.android.systemui.statusbar.phone.dozeServiceHost
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -85,7 +87,6 @@
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.eq
-import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import java.util.Optional
@@ -238,6 +239,8 @@
                 testScope.backgroundScope,
                 mContext,
                 deviceEntryFingerprintAuthRepository,
+                kosmos.fakeSceneContainerFlags,
+                kosmos.sceneInteractor,
                 primaryBouncerInteractor,
                 alternateBouncerInteractor,
                 keyguardUpdateMonitor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
index ae20c70..238a76e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/ui/viewmodel/SideFpsOverlayViewModelTest.kt
@@ -33,6 +33,7 @@
 import com.android.keyguard.KeyguardSecurityModel
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.settingslib.Utils
+import com.android.systemui.Flags.FLAG_CONSTRAINT_BP
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.FingerprintInteractiveToAuthProvider
 import com.android.systemui.biometrics.data.repository.FakeBiometricStatusRepository
@@ -75,6 +76,8 @@
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
 import com.android.systemui.shared.Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
 import com.android.systemui.statusbar.phone.dozeServiceHost
 import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -233,6 +236,8 @@
                 testScope.backgroundScope,
                 mContext,
                 deviceEntryFingerprintAuthRepository,
+                kosmos.fakeSceneContainerFlags,
+                kosmos.sceneInteractor,
                 primaryBouncerInteractor,
                 alternateBouncerInteractor,
                 keyguardUpdateMonitor
@@ -347,6 +352,7 @@
     @Test
     fun updatesOverlayViewParams_onDisplayRotationChange_xAlignedSensor() {
         testScope.runTest {
+            mSetFlagsRule.disableFlags(FLAG_CONSTRAINT_BP)
             setupTestConfiguration(
                 DeviceConfig.X_ALIGNED,
                 rotation = DisplayRotation.ROTATION_0,
@@ -388,6 +394,7 @@
     @Test
     fun updatesOverlayViewParams_onDisplayRotationChange_yAlignedSensor() {
         testScope.runTest {
+            mSetFlagsRule.disableFlags(FLAG_CONSTRAINT_BP)
             setupTestConfiguration(
                 DeviceConfig.Y_ALIGNED,
                 rotation = DisplayRotation.ROTATION_0,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
index 45d20dc..8e5ddc7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java
@@ -27,6 +27,7 @@
 
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 
 import androidx.test.filters.SmallTest;
@@ -202,6 +203,36 @@
     }
 
     @Test
+    public void testPassThroughEnterKeyEvent() {
+        KeyEvent enterDown = KeyEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER,
+                0, 0, 0, 0, 0, 0, 0, "");
+        KeyEvent enterUp = KeyEvent.obtain(0, 0, MotionEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER, 0,
+                0, 0, 0, 0, 0, 0, "");
+
+        mFalsingCollector.onKeyEvent(enterDown);
+        verify(mFalsingDataProvider, never()).onKeyEvent(any(KeyEvent.class));
+
+        mFalsingCollector.onKeyEvent(enterUp);
+        verify(mFalsingDataProvider, times(1)).onKeyEvent(enterUp);
+    }
+
+    @Test
+    public void testAvoidAKeyEvent() {
+        // Arbitrarily chose the "A" key, as it is not currently allowlisted. If this key is
+        // allowlisted in the future, please choose another key that will not be collected.
+        KeyEvent aKeyDown = KeyEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_A,
+                0, 0, 0, 0, 0, 0, 0, "");
+        KeyEvent aKeyUp = KeyEvent.obtain(0, 0, MotionEvent.ACTION_UP, KeyEvent.KEYCODE_A, 0,
+                0, 0, 0, 0, 0, 0, "");
+
+        mFalsingCollector.onKeyEvent(aKeyDown);
+        verify(mFalsingDataProvider, never()).onKeyEvent(any(KeyEvent.class));
+
+        mFalsingCollector.onKeyEvent(aKeyUp);
+        verify(mFalsingDataProvider, never()).onKeyEvent(any(KeyEvent.class));
+    }
+
+    @Test
     public void testPassThroughGesture() {
         MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
         MotionEvent up = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
index 0353f87..057b0a1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java
@@ -27,6 +27,7 @@
 import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
 import android.testing.AndroidTestingRunner;
 import android.util.DisplayMetrics;
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 
 import androidx.test.filters.SmallTest;
@@ -282,6 +283,22 @@
     }
 
     @Test
+    public void test_isFromKeyboard_disallowedKey_false() {
+        KeyEvent eventDown = KeyEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_A, 0,
+                0, 0, 0, 0, 0, 0, "");
+        KeyEvent eventUp = KeyEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_A, 0, 0,
+                0, 0, 0, 0, 0, "");
+
+        //events have not come in yet
+        assertThat(mDataProvider.isFromKeyboard()).isFalse();
+
+        mDataProvider.onKeyEvent(eventDown);
+        mDataProvider.onKeyEvent(eventUp);
+        assertThat(mDataProvider.isFromKeyboard()).isTrue();
+        mDataProvider.onSessionEnd();
+    }
+
+    @Test
     public void test_IsFromTrackpad() {
         MotionEvent motionEventOrigin = appendTrackpadDownEvent(0, 0);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedInputEventBufferTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedInputEventBufferTest.java
new file mode 100644
index 0000000..ad7afa3
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedInputEventBufferTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.classifier;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import android.testing.AndroidTestingRunner;
+import android.view.InputEvent;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class TimeLimitedInputEventBufferTest extends SysuiTestCase {
+
+    private static final long MAX_AGE_MS = 100;
+
+    private TimeLimitedInputEventBuffer<InputEvent> mBuffer;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mBuffer = new TimeLimitedInputEventBuffer<>(MAX_AGE_MS);
+    }
+
+    @After
+    public void tearDown() {
+        for (InputEvent inputEvent : mBuffer) {
+            inputEvent.recycle();
+        }
+        mBuffer.clear();
+    }
+
+    @Test
+    public void testMotionEventAllEventsRetained() {
+        MotionEvent eventA = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
+        MotionEvent eventB = MotionEvent.obtain(0, 1, MotionEvent.ACTION_MOVE, 0, 0, 0);
+        MotionEvent eventC = MotionEvent.obtain(0, 2, MotionEvent.ACTION_MOVE, 0, 0, 0);
+        MotionEvent eventD = MotionEvent.obtain(0, 3, MotionEvent.ACTION_UP, 0, 0, 0);
+
+        mBuffer.add(eventA);
+        mBuffer.add(eventB);
+        mBuffer.add(eventC);
+        mBuffer.add(eventD);
+
+        assertThat(mBuffer.size(), is(4));
+    }
+
+    @Test
+    public void testMotionEventOlderEventsRemoved() {
+        MotionEvent eventA = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
+        MotionEvent eventB = MotionEvent.obtain(0, 1, MotionEvent.ACTION_MOVE, 0, 0, 0);
+        MotionEvent eventC = MotionEvent.obtain(
+                0, MAX_AGE_MS + 1, MotionEvent.ACTION_MOVE, 0, 0, 0);
+        MotionEvent eventD = MotionEvent.obtain(
+                0, MAX_AGE_MS + 2, MotionEvent.ACTION_UP, 0, 0, 0);
+
+        mBuffer.add(eventA);
+        mBuffer.add(eventB);
+        assertThat(mBuffer.size(), is(2));
+
+        mBuffer.add(eventC);
+        mBuffer.add(eventD);
+        assertThat(mBuffer.size(), is(2));
+
+        assertThat(mBuffer.get(0), is(eventC));
+        assertThat(mBuffer.get(1), is(eventD));
+    }
+
+    @Test
+    public void testKeyEventAllEventsRetained() {
+        KeyEvent eventA = KeyEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_A, 0, 0,
+                0, 0, 0, 0, 0, "");
+        KeyEvent eventB = KeyEvent.obtain(0, 3, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A, 0, 0, 0, 0,
+                0, 0, 0, "");
+
+        mBuffer.add(eventA);
+        mBuffer.add(eventB);
+
+        assertThat(mBuffer.size(), is(2));
+    }
+
+    @Test
+    public void testKeyEventOlderEventsRemoved() {
+        KeyEvent eventA = KeyEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_A, 0, 0,
+                0, 0, 0, 0, 0, "");
+        KeyEvent eventB = KeyEvent.obtain(0, 1, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A, 0, 0, 0, 0,
+                0, 0, 0, "");
+        KeyEvent eventC = KeyEvent.obtain(0, MAX_AGE_MS + 1, MotionEvent.ACTION_DOWN,
+                KeyEvent.KEYCODE_A, 0, 0, 0, 0, 0, 0, 0, "");
+        KeyEvent eventD = KeyEvent.obtain(0, MAX_AGE_MS + 2, KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A,
+                0, 0, 0, 0, 0, 0, 0, "");
+
+        mBuffer.add(eventA);
+        mBuffer.add(eventB);
+        assertThat(mBuffer.size(), is(2));
+
+        mBuffer.add(eventC);
+        mBuffer.add(eventD);
+        assertThat(mBuffer.size(), is(2));
+
+        assertThat(mBuffer.get(0), is(eventC));
+        assertThat(mBuffer.get(1), is(eventD));
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java
deleted file mode 100644
index 901196f..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/TimeLimitedMotionEventBufferTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.classifier;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-import android.testing.AndroidTestingRunner;
-import android.view.MotionEvent;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class TimeLimitedMotionEventBufferTest extends SysuiTestCase {
-
-    private static final long MAX_AGE_MS = 100;
-
-    private TimeLimitedMotionEventBuffer mBuffer;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mBuffer = new TimeLimitedMotionEventBuffer(MAX_AGE_MS);
-    }
-
-    @After
-    public void tearDown() {
-        for (MotionEvent motionEvent : mBuffer) {
-            motionEvent.recycle();
-        }
-        mBuffer.clear();
-    }
-
-    @Test
-    public void testAllEventsRetained() {
-        MotionEvent eventA = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
-        MotionEvent eventB = MotionEvent.obtain(0, 1, MotionEvent.ACTION_MOVE, 0, 0, 0);
-        MotionEvent eventC = MotionEvent.obtain(0, 2, MotionEvent.ACTION_MOVE, 0, 0, 0);
-        MotionEvent eventD = MotionEvent.obtain(0, 3, MotionEvent.ACTION_UP, 0, 0, 0);
-
-        mBuffer.add(eventA);
-        mBuffer.add(eventB);
-        mBuffer.add(eventC);
-        mBuffer.add(eventD);
-
-        assertThat(mBuffer.size(), is(4));
-    }
-
-    @Test
-    public void testOlderEventsRemoved() {
-        MotionEvent eventA = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
-        MotionEvent eventB = MotionEvent.obtain(0, 1, MotionEvent.ACTION_MOVE, 0, 0, 0);
-        MotionEvent eventC = MotionEvent.obtain(
-                0, MAX_AGE_MS + 1, MotionEvent.ACTION_MOVE, 0, 0, 0);
-        MotionEvent eventD = MotionEvent.obtain(
-                0, MAX_AGE_MS + 2, MotionEvent.ACTION_UP, 0, 0, 0);
-
-        mBuffer.add(eventA);
-        mBuffer.add(eventB);
-        assertThat(mBuffer.size(), is(2));
-
-        mBuffer.add(eventC);
-        mBuffer.add(eventD);
-        assertThat(mBuffer.size(), is(2));
-
-        assertThat(mBuffer.get(0), is(eventC));
-        assertThat(mBuffer.get(1), is(eventD));
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/ui/viewmodel/UdfpsAccessibilityOverlayViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/ui/viewmodel/UdfpsAccessibilityOverlayViewModelTest.kt
index 9b8cf59..6a0462b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/ui/viewmodel/UdfpsAccessibilityOverlayViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/deviceentry/domain/ui/viewmodel/UdfpsAccessibilityOverlayViewModelTest.kt
@@ -122,7 +122,6 @@
         fingerprintPropertyRepository.supportsUdfps()
         biometricSettingsRepository.setIsFingerprintAuthEnrolledAndEnabled(true)
         deviceEntryFingerprintAuthRepository.setIsRunning(true)
-        deviceEntryRepository.setUnlocked(false)
 
         // Lockscreen
         keyguardTransitionRepository.sendTransitionStep(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
index 7311f4a..e7caf00 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeUiTest.java
@@ -41,6 +41,8 @@
 import com.android.systemui.DejankUtils;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
 import com.android.systemui.util.wakelock.WakeLockFake;
 
 import org.junit.After;
@@ -69,6 +71,7 @@
     private Handler mHandler;
     private HandlerThread mHandlerThread;
     private DozeUi mDozeUi;
+    private FakeExecutor mFakeExecutor;
 
     @Before
     public void setUp() throws Exception {
@@ -80,9 +83,9 @@
         mHandlerThread.start();
         mWakeLock = new WakeLockFake();
         mHandler = mHandlerThread.getThreadHandler();
-
+        mFakeExecutor = new FakeExecutor(new FakeSystemClock());
         mDozeUi = new DozeUi(mContext, mAlarmManager, mWakeLock, mHost, mHandler,
-                mDozeParameters, mDozeLog);
+                mDozeParameters, mFakeExecutor, mDozeLog);
         mDozeUi.setDozeMachine(mMachine);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java
index 1c6f251..a127631 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java
@@ -32,6 +32,7 @@
 import android.testing.AndroidTestingRunner;
 import android.util.Pair;
 import android.view.GestureDetector;
+import android.view.IWindowManager;
 import android.view.InputEvent;
 import android.view.MotionEvent;
 
@@ -83,11 +84,14 @@
         private final GestureDetector.OnGestureListener mGestureListener;
         private final DisplayHelper mDisplayHelper;
         private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
+        private final FakeExecutor mBackgroundExecutor = new FakeExecutor(new FakeSystemClock());
         private final Rect mDisplayBounds = Mockito.mock(Rect.class);
+        private final IWindowManager mIWindowManager;
 
         Environment(Set<DreamTouchHandler> handlers) {
             mLifecycle = Mockito.mock(Lifecycle.class);
             mLifecycleOwner = Mockito.mock(LifecycleOwner.class);
+            mIWindowManager = Mockito.mock(IWindowManager.class);
 
             mInputFactory = Mockito.mock(InputSessionComponent.Factory.class);
             final InputSessionComponent inputComponent = Mockito.mock(InputSessionComponent.class);
@@ -100,8 +104,8 @@
             mDisplayHelper = Mockito.mock(DisplayHelper.class);
             when(mDisplayHelper.getMaxBounds(anyInt(), anyInt()))
                     .thenReturn(mDisplayBounds);
-            mMonitor = new DreamOverlayTouchMonitor(mExecutor, mLifecycle, mInputFactory,
-                    mDisplayHelper, handlers);
+            mMonitor = new DreamOverlayTouchMonitor(mExecutor, mBackgroundExecutor,
+                    mLifecycle, mInputFactory, mDisplayHelper, handlers, mIWindowManager, 0);
             mMonitor.init();
 
             final ArgumentCaptor<LifecycleObserver> lifecycleObserverCaptor =
@@ -163,7 +167,8 @@
         environment.publishInputEvent(initialEvent);
 
         // Verify display bounds passed into TouchHandler#getTouchInitiationRegion
-        verify(touchHandler).getTouchInitiationRegion(eq(environment.getDisplayBounds()), any());
+        verify(touchHandler).getTouchInitiationRegion(
+                eq(environment.getDisplayBounds()), any(), any());
         final ArgumentCaptor<DreamTouchHandler.TouchSession> touchSessionArgumentCaptor =
                 ArgumentCaptor.forClass(DreamTouchHandler.TouchSession.class);
         verify(touchHandler).onSessionStart(touchSessionArgumentCaptor.capture());
@@ -182,7 +187,7 @@
             final Region region = (Region) invocation.getArguments()[1];
             region.set(touchArea);
             return null;
-        }).when(touchHandler).getTouchInitiationRegion(any(), any());
+        }).when(touchHandler).getTouchInitiationRegion(any(), any(), any());
 
         final Environment environment = new Environment(Stream.of(touchHandler)
                 .collect(Collectors.toCollection(HashSet::new)));
@@ -211,7 +216,7 @@
             final Region region = (Region) invocation.getArguments()[1];
             region.set(touchArea);
             return null;
-        }).when(touchHandler).getTouchInitiationRegion(any(), any());
+        }).when(touchHandler).getTouchInitiationRegion(any(), any(), any());
 
         final Environment environment = new Environment(Stream.of(touchHandler, unzonedTouchHandler)
                 .collect(Collectors.toCollection(HashSet::new)));
@@ -264,7 +269,7 @@
 
         // Make sure there is no active session.
         verify(touchHandler, never()).onSessionStart(any());
-        verify(touchHandler, never()).getTouchInitiationRegion(any(), any());
+        verify(touchHandler, never()).getTouchInitiationRegion(any(), any(), any());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
index 8700001..53560d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt
@@ -35,14 +35,16 @@
 import com.android.systemui.keyguard.shared.model.TransitionState
 import com.android.systemui.keyguard.shared.model.TransitionStep
 import com.android.systemui.keyguard.util.KeyguardTransitionRunner
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import java.math.BigDecimal
 import java.math.RoundingMode
 import java.util.UUID
+import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.dropWhile
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.After
@@ -54,6 +56,9 @@
 @RunWith(AndroidJUnit4::class)
 @FlakyTest(bugId = 270760395)
 class KeyguardTransitionRepositoryTest : SysuiTestCase() {
+    val kosmos = testKosmos()
+
+    private val testScope = kosmos.testScope
 
     private lateinit var underTest: KeyguardTransitionRepository
     private lateinit var oldWtfHandler: TerribleFailureHandler
@@ -62,7 +67,7 @@
 
     @Before
     fun setUp() {
-        underTest = KeyguardTransitionRepositoryImpl()
+        underTest = KeyguardTransitionRepositoryImpl(Dispatchers.Main)
         wtfHandler = WtfHandler()
         oldWtfHandler = Log.setWtfHandler(wtfHandler)
         runner = KeyguardTransitionRunner(underTest)
@@ -75,7 +80,7 @@
 
     @Test
     fun startTransitionRunsAnimatorToCompletion() =
-        TestScope().runTest {
+        testScope.runTest {
             val steps = mutableListOf<TransitionStep>()
             val job = underTest.transition(AOD, LOCKSCREEN).onEach { steps.add(it) }.launchIn(this)
 
@@ -91,7 +96,7 @@
 
     @Test
     fun startingSecondTransitionWillCancelTheFirstTransitionAndUseLastValue() =
-        TestScope().runTest {
+        testScope.runTest {
             val steps = mutableListOf<TransitionStep>()
             val job = underTest.transition(AOD, LOCKSCREEN).onEach { steps.add(it) }.launchIn(this)
             runner.startTransition(
@@ -126,7 +131,7 @@
 
     @Test
     fun startingSecondTransitionWillCancelTheFirstTransitionAndUseReset() =
-        TestScope().runTest {
+        testScope.runTest {
             val steps = mutableListOf<TransitionStep>()
             val job = underTest.transition(AOD, LOCKSCREEN).onEach { steps.add(it) }.launchIn(this)
             runner.startTransition(
@@ -161,7 +166,7 @@
 
     @Test
     fun startingSecondTransitionWillCancelTheFirstTransitionAndUseReverse() =
-        TestScope().runTest {
+        testScope.runTest {
             val steps = mutableListOf<TransitionStep>()
             val job = underTest.transition(AOD, LOCKSCREEN).onEach { steps.add(it) }.launchIn(this)
             runner.startTransition(
@@ -196,7 +201,7 @@
 
     @Test
     fun nullAnimatorEnablesManualControlWithUpdateTransition() =
-        TestScope().runTest {
+        testScope.runTest {
             val steps = mutableListOf<TransitionStep>()
             val job = underTest.transition(AOD, LOCKSCREEN).onEach { steps.add(it) }.launchIn(this)
 
@@ -228,7 +233,7 @@
 
     @Test
     fun startingSecondManualTransitionWillCancelPreviousManualTransition() =
-        TestScope().runTest {
+        testScope.runTest {
             // Drop initial steps from OFF which are sent in the constructor
             val steps = mutableListOf<TransitionStep>()
             val job =
@@ -274,7 +279,7 @@
 
     @Test
     fun startingSecondTransitionWillCancelPreviousManualTransition() =
-        TestScope().runTest {
+        testScope.runTest {
             // Drop initial steps from OFF which are sent in the constructor
             val steps = mutableListOf<TransitionStep>()
             val job =
@@ -328,42 +333,44 @@
     }
 
     @Test
-    fun attemptToManuallyUpdateTransitionAfterFINISHEDstateThrowsException() {
-        val uuid =
-            underTest.startTransition(
-                TransitionInfo(
-                    ownerName = OWNER_NAME,
-                    from = AOD,
-                    to = LOCKSCREEN,
-                    animator = null,
+    fun attemptToManuallyUpdateTransitionAfterFINISHEDstateThrowsException() =
+        testScope.runTest {
+            val uuid =
+                underTest.startTransition(
+                    TransitionInfo(
+                        ownerName = OWNER_NAME,
+                        from = AOD,
+                        to = LOCKSCREEN,
+                        animator = null,
+                    )
                 )
-            )
 
-        checkNotNull(uuid).let {
-            underTest.updateTransition(it, 1f, TransitionState.FINISHED)
-            underTest.updateTransition(it, 0.5f, TransitionState.RUNNING)
+            checkNotNull(uuid).let {
+                underTest.updateTransition(it, 1f, TransitionState.FINISHED)
+                underTest.updateTransition(it, 0.5f, TransitionState.RUNNING)
+            }
+            assertThat(wtfHandler.failed).isTrue()
         }
-        assertThat(wtfHandler.failed).isTrue()
-    }
 
     @Test
-    fun attemptToManuallyUpdateTransitionAfterCANCELEDstateThrowsException() {
-        val uuid =
-            underTest.startTransition(
-                TransitionInfo(
-                    ownerName = OWNER_NAME,
-                    from = AOD,
-                    to = LOCKSCREEN,
-                    animator = null,
+    fun attemptToManuallyUpdateTransitionAfterCANCELEDstateThrowsException() =
+        testScope.runTest {
+            val uuid =
+                underTest.startTransition(
+                    TransitionInfo(
+                        ownerName = OWNER_NAME,
+                        from = AOD,
+                        to = LOCKSCREEN,
+                        animator = null,
+                    )
                 )
-            )
 
-        checkNotNull(uuid).let {
-            underTest.updateTransition(it, 0.2f, TransitionState.CANCELED)
-            underTest.updateTransition(it, 0.5f, TransitionState.RUNNING)
+            checkNotNull(uuid).let {
+                underTest.updateTransition(it, 0.2f, TransitionState.CANCELED)
+                underTest.updateTransition(it, 0.5f, TransitionState.RUNNING)
+            }
+            assertThat(wtfHandler.failed).isTrue()
         }
-        assertThat(wtfHandler.failed).isTrue()
-    }
 
     private fun listWithStep(
         step: BigDecimal,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
index 3b4f683..9266af4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/DeviceEntrySideFpsOverlayInteractorTest.kt
@@ -36,16 +36,20 @@
 import com.android.systemui.keyguard.data.repository.FakeBiometricSettingsRepository
 import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.data.repository.FakeTrustRepository
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.sceneInteractor
+import com.android.systemui.scene.shared.flag.fakeSceneContainerFlags
+import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.shared.Flags.FLAG_SIDEFPS_CONTROLLER_REFACTOR
 import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.testKosmos
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.StandardTestDispatcher
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -69,6 +73,8 @@
     @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
     @Mock private lateinit var mSelectedUserInteractor: SelectedUserInteractor
 
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
     private val bouncerRepository = FakeKeyguardBouncerRepository()
     private val biometricSettingsRepository = FakeBiometricSettingsRepository()
     private val deviceEntryFingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository()
@@ -78,11 +84,11 @@
 
     private lateinit var underTest: DeviceEntrySideFpsOverlayInteractor
 
-    private val testScope = TestScope(StandardTestDispatcher())
-
     @Before
     fun setup() {
         mSetFlagsRule.enableFlags(FLAG_SIDEFPS_CONTROLLER_REFACTOR)
+        kosmos.fakeSceneContainerFlags.enabled = false
+
         primaryBouncerInteractor =
             PrimaryBouncerInteractor(
                 bouncerRepository,
@@ -100,6 +106,7 @@
                 mSelectedUserInteractor,
                 faceAuthInteractor
             )
+
         alternateBouncerInteractor =
             AlternateBouncerInteractor(
                 mock(StatusBarStateController::class.java),
@@ -114,11 +121,14 @@
                 { mock(KeyguardTransitionInteractor::class.java) },
                 testScope.backgroundScope,
             )
+
         underTest =
             DeviceEntrySideFpsOverlayInteractor(
                 testScope.backgroundScope,
                 mContext,
                 deviceEntryFingerprintAuthRepository,
+                kosmos.fakeSceneContainerFlags,
+                kosmos.sceneInteractor,
                 primaryBouncerInteractor,
                 alternateBouncerInteractor,
                 keyguardUpdateMonitor
@@ -138,7 +148,7 @@
                 fpsDetectionRunning = true,
                 isUnlockingWithFpAllowed = true
             )
-            assertThat(showIndicatorForDeviceEntry).isEqualTo(true)
+            assertThat(showIndicatorForDeviceEntry).isTrue()
         }
 
     @Test
@@ -154,7 +164,63 @@
                 fpsDetectionRunning = true,
                 isUnlockingWithFpAllowed = true
             )
-            assertThat(showIndicatorForDeviceEntry).isEqualTo(false)
+            assertThat(showIndicatorForDeviceEntry).isFalse()
+        }
+
+    @Test
+    fun updatesShowIndicatorForDeviceEntry_onBouncerSceneActive() =
+        testScope.runTest {
+            kosmos.fakeSceneContainerFlags.enabled = true
+            underTest =
+                DeviceEntrySideFpsOverlayInteractor(
+                    testScope.backgroundScope,
+                    mContext,
+                    deviceEntryFingerprintAuthRepository,
+                    kosmos.fakeSceneContainerFlags,
+                    kosmos.sceneInteractor,
+                    primaryBouncerInteractor,
+                    alternateBouncerInteractor,
+                    keyguardUpdateMonitor
+                )
+
+            val showIndicatorForDeviceEntry by
+                collectLastValue(underTest.showIndicatorForDeviceEntry)
+            runCurrent()
+
+            updateBouncerScene(
+                isActive = true,
+                fpsDetectionRunning = true,
+                isUnlockingWithFpAllowed = true
+            )
+            assertThat(showIndicatorForDeviceEntry).isTrue()
+        }
+
+    @Test
+    fun updatesShowIndicatorForDeviceEntry_onBouncerSceneInactive() =
+        testScope.runTest {
+            kosmos.fakeSceneContainerFlags.enabled = true
+            underTest =
+                DeviceEntrySideFpsOverlayInteractor(
+                    testScope.backgroundScope,
+                    mContext,
+                    deviceEntryFingerprintAuthRepository,
+                    kosmos.fakeSceneContainerFlags,
+                    kosmos.sceneInteractor,
+                    primaryBouncerInteractor,
+                    alternateBouncerInteractor,
+                    keyguardUpdateMonitor
+                )
+
+            val showIndicatorForDeviceEntry by
+                collectLastValue(underTest.showIndicatorForDeviceEntry)
+            runCurrent()
+
+            updateBouncerScene(
+                isActive = false,
+                fpsDetectionRunning = true,
+                isUnlockingWithFpAllowed = true
+            )
+            assertThat(showIndicatorForDeviceEntry).isFalse()
         }
 
     @Test
@@ -170,7 +236,7 @@
                 fpsDetectionRunning = false,
                 isUnlockingWithFpAllowed = true
             )
-            assertThat(showIndicatorForDeviceEntry).isEqualTo(false)
+            assertThat(showIndicatorForDeviceEntry).isFalse()
         }
     }
 
@@ -187,7 +253,39 @@
                 fpsDetectionRunning = true,
                 isUnlockingWithFpAllowed = false
             )
-            assertThat(showIndicatorForDeviceEntry).isEqualTo(false)
+            assertThat(showIndicatorForDeviceEntry).isFalse()
+        }
+    }
+
+    @Test
+    fun updatesShowIndicatorForDeviceEntry_fromBouncerScene_whenFpsDetectionNotRunning() {
+        testScope.runTest {
+            val showIndicatorForDeviceEntry by
+                collectLastValue(underTest.showIndicatorForDeviceEntry)
+            runCurrent()
+
+            updateBouncerScene(
+                isActive = true,
+                fpsDetectionRunning = false,
+                isUnlockingWithFpAllowed = true
+            )
+            assertThat(showIndicatorForDeviceEntry).isFalse()
+        }
+    }
+
+    @Test
+    fun updatesShowIndicatorForDeviceEntry_fromBouncerScene_onUnlockingWithFpDisallowed() {
+        testScope.runTest {
+            val showIndicatorForDeviceEntry by
+                collectLastValue(underTest.showIndicatorForDeviceEntry)
+            runCurrent()
+
+            updateBouncerScene(
+                isActive = true,
+                fpsDetectionRunning = true,
+                isUnlockingWithFpAllowed = false
+            )
+            assertThat(showIndicatorForDeviceEntry).isFalse()
         }
     }
 
@@ -204,7 +302,7 @@
                 fpsDetectionRunning = true,
                 isUnlockingWithFpAllowed = true
             )
-            assertThat(showIndicatorForDeviceEntry).isEqualTo(false)
+            assertThat(showIndicatorForDeviceEntry).isFalse()
         }
     }
 
@@ -216,10 +314,10 @@
             runCurrent()
 
             bouncerRepository.setAlternateVisible(true)
-            assertThat(showIndicatorForDeviceEntry).isEqualTo(true)
+            assertThat(showIndicatorForDeviceEntry).isTrue()
 
             bouncerRepository.setAlternateVisible(false)
-            assertThat(showIndicatorForDeviceEntry).isEqualTo(false)
+            assertThat(showIndicatorForDeviceEntry).isFalse()
         }
 
     @Test
@@ -266,4 +364,25 @@
             true
         )
     }
+
+    private fun TestScope.updateBouncerScene(
+        isActive: Boolean,
+        fpsDetectionRunning: Boolean,
+        isUnlockingWithFpAllowed: Boolean,
+    ) {
+        kosmos.sceneInteractor.changeScene(
+            if (isActive) Scenes.Bouncer else Scenes.Lockscreen,
+            "reason"
+        )
+
+        whenever(keyguardUpdateMonitor.isFingerprintDetectionRunning)
+            .thenReturn(fpsDetectionRunning)
+        whenever(keyguardUpdateMonitor.isUnlockingWithFingerprintAllowed)
+            .thenReturn(isUnlockingWithFpAllowed)
+        mContext.orCreateTestableResources.addOverride(
+            R.bool.config_show_sidefps_hint_on_bouncer,
+            true
+        )
+        runCurrent()
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt
index 3926f92..0a7e72c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractorTest.kt
@@ -288,4 +288,16 @@
             assertThat(transitionRepository)
                 .startedTransition(from = KeyguardState.AOD, to = KeyguardState.GONE)
         }
+
+    @Test
+    fun testTransitionToOccluded_onWake() =
+        testScope.runTest {
+            kosmos.fakeKeyguardRepository.setKeyguardOccluded(true)
+            powerInteractor.setAwakeForTest()
+            runCurrent()
+
+            // Waking up from AOD while occluded should transition to OCCLUDED.
+            assertThat(transitionRepository)
+                .startedTransition(from = KeyguardState.AOD, to = KeyguardState.OCCLUDED)
+        }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt
index c3e24d5..1ec7874 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractorTest.kt
@@ -37,17 +37,14 @@
 import com.android.systemui.shade.data.repository.FlingInfo
 import com.android.systemui.shade.data.repository.fakeShadeRepository
 import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.any
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mockito.never
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.spy
-import org.mockito.Mockito.verify
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SmallTest
@@ -125,7 +122,7 @@
     fun testTransitionsToGone_whenDismissFlingWhileDismissable_flagEnabled() =
         testScope.runTest {
             underTest.start()
-            verify(transitionRepository, never()).startTransition(any())
+            assertThatRepository(transitionRepository).noTransitionsStarted()
 
             keyguardRepository.setKeyguardDismissible(true)
             runCurrent()
@@ -146,7 +143,7 @@
     fun testDoesNotTransitionToGone_whenDismissFlingWhileDismissable_flagDisabled() =
         testScope.runTest {
             underTest.start()
-            verify(transitionRepository, never()).startTransition(any())
+            assertThatRepository(transitionRepository).noTransitionsStarted()
 
             keyguardRepository.setKeyguardDismissible(true)
             runCurrent()
@@ -163,7 +160,7 @@
     fun testDoesNotTransitionToGone_whenDismissFling_emitsNull() =
         testScope.runTest {
             underTest.start()
-            verify(transitionRepository, never()).startTransition(any())
+            assertThatRepository(transitionRepository).noTransitionsStarted()
 
             keyguardRepository.setKeyguardDismissible(true)
             runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
index 95606ae..2c0a51835 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionScenariosTest.kt
@@ -47,7 +47,6 @@
 import com.android.systemui.shade.data.repository.fakeShadeRepository
 import com.android.systemui.statusbar.commandQueue
 import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.whenever
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.cancelChildren
@@ -64,10 +63,8 @@
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.Mock
 import org.mockito.Mockito.clearInvocations
-import org.mockito.Mockito.never
 import org.mockito.Mockito.reset
 import org.mockito.Mockito.spy
-import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
 /**
@@ -521,7 +518,7 @@
             advanceTimeBy(100L)
 
             // THEN the transition is ignored
-            verify(transitionRepository, never()).startTransition(any())
+            assertThat(transitionRepository).noTransitionsStarted()
 
             coroutineContext.cancelChildren()
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt
index aa7f9a9..c47f0bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/ClockSectionTest.kt
@@ -23,13 +23,15 @@
 import android.view.View.VISIBLE
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.test.filters.SmallTest
+import com.android.internal.policy.SystemBarUtils
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardClockViewModel
 import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel
 import com.android.systemui.res.R
-import com.android.systemui.statusbar.policy.SplitShadeStateController
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.util.Utils
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
@@ -51,12 +53,13 @@
 class ClockSectionTest : SysuiTestCase() {
     @Mock private lateinit var keyguardClockInteractor: KeyguardClockInteractor
     @Mock private lateinit var keyguardClockViewModel: KeyguardClockViewModel
-    @Mock private lateinit var splitShadeStateController: SplitShadeStateController
+    @Mock private lateinit var shadeInteractor: ShadeInteractor
     @Mock private lateinit var smartspaceViewModel: KeyguardSmartspaceViewModel
     @Mock private lateinit var blueprintInteractor: Lazy<KeyguardBlueprintInteractor>
     private val bcSmartspaceVisibility: MutableStateFlow<Int> = MutableStateFlow(VISIBLE)
     private val clockShouldBeCentered: MutableStateFlow<Boolean> = MutableStateFlow(true)
     private val isAodIconsVisible: MutableStateFlow<Boolean> = MutableStateFlow(true)
+    private val shadeMode: MutableStateFlow<ShadeMode> = MutableStateFlow(ShadeMode.Single)
 
     private lateinit var underTest: ClockSection
 
@@ -68,7 +71,7 @@
             Utils.getStatusBarHeaderHeightKeyguard(context)
 
     private val LARGE_CLOCK_TOP_WITHOUT_SMARTSPACE =
-        context.resources.getDimensionPixelSize(R.dimen.status_bar_height) +
+        SystemBarUtils.getStatusBarHeight(context) +
             context.resources.getDimensionPixelSize(
                 com.android.systemui.customization.R.dimen.small_clock_padding_top
             ) +
@@ -114,14 +117,15 @@
 
         whenever(keyguardClockViewModel.clockShouldBeCentered).thenReturn(clockShouldBeCentered)
         whenever(keyguardClockViewModel.isAodIconsVisible).thenReturn(isAodIconsVisible)
+        whenever(shadeInteractor.shadeMode).thenReturn(shadeMode)
+        whenever(keyguardClockViewModel.shadeInteractor).thenReturn(shadeInteractor)
         whenever(smartspaceViewModel.bcSmartspaceVisibility).thenReturn(bcSmartspaceVisibility)
 
         underTest =
             ClockSection(
                 keyguardClockInteractor,
                 keyguardClockViewModel,
-                mContext,
-                splitShadeStateController,
+                context,
                 smartspaceViewModel,
                 blueprintInteractor
             )
@@ -138,7 +142,7 @@
         assertLargeClockTop(cs, expectedLargeClockTopMargin)
 
         val expectedSmallClockTopMargin = SMALL_CLOCK_TOP_SPLIT_SHADE
-        assertSmallClockTop(cs, expectedSmallClockTopMargin)
+        assertSmallClockTop(cs)
     }
 
     @Test
@@ -152,7 +156,7 @@
         assertLargeClockTop(cs, expectedLargeClockTopMargin)
 
         val expectedSmallClockTopMargin = SMALL_CLOCK_TOP_NON_SPLIT_SHADE
-        assertSmallClockTop(cs, expectedSmallClockTopMargin)
+        assertSmallClockTop(cs)
     }
 
     @Test
@@ -167,7 +171,7 @@
         assertLargeClockTop(cs, expectedLargeClockTopMargin)
 
         val expectedSmallClockTopMargin = SMALL_CLOCK_TOP_SPLIT_SHADE
-        assertSmallClockTop(cs, expectedSmallClockTopMargin)
+        assertSmallClockTop(cs)
     }
 
     @Test
@@ -182,7 +186,7 @@
         assertLargeClockTop(cs, expectedLargeClockTopMargin)
 
         val expectedSmallClockTopMargin = SMALL_CLOCK_TOP_NON_SPLIT_SHADE
-        assertSmallClockTop(cs, expectedSmallClockTopMargin)
+        assertSmallClockTop(cs)
     }
 
     @Test
@@ -196,7 +200,7 @@
         assertLargeClockTop(cs, expectedLargeClockTopMargin)
 
         val expectedSmallClockTopMargin = SMALL_CLOCK_TOP_SPLIT_SHADE
-        assertSmallClockTop(cs, expectedSmallClockTopMargin)
+        assertSmallClockTop(cs)
     }
 
     @Test
@@ -209,7 +213,7 @@
         assertLargeClockTop(cs, expectedLargeClockTopMargin)
 
         val expectedSmallClockTopMargin = SMALL_CLOCK_TOP_NON_SPLIT_SHADE
-        assertSmallClockTop(cs, expectedSmallClockTopMargin)
+        assertSmallClockTop(cs)
     }
 
     @Test
@@ -251,8 +255,11 @@
     }
 
     private fun setSplitShade(isInSplitShade: Boolean) {
-        whenever(splitShadeStateController.shouldUseSplitNotificationShade(context.resources))
-            .thenReturn(isInSplitShade)
+        if (isInSplitShade) {
+            shadeMode.value = ShadeMode.Split
+        } else {
+            shadeMode.value = ShadeMode.Single
+        }
     }
 
     private fun assertLargeClockTop(cs: ConstraintSet, expectedLargeClockTopMargin: Int) {
@@ -261,11 +268,9 @@
         assertThat(largeClockConstraint.layout.topMargin).isEqualTo(expectedLargeClockTopMargin)
     }
 
-    private fun assertSmallClockTop(cs: ConstraintSet, expectedSmallClockTopMargin: Int) {
+    private fun assertSmallClockTop(cs: ConstraintSet) {
         val smallClockGuidelineConstraint = cs.getConstraint(R.id.small_clock_guideline_top)
         assertThat(smallClockGuidelineConstraint.layout.topToTop).isEqualTo(-1)
-        assertThat(smallClockGuidelineConstraint.layout.guideBegin)
-            .isEqualTo(expectedSmallClockTopMargin)
 
         val smallClockConstraint = cs.getConstraint(R.id.lockscreen_clock_view)
         assertThat(smallClockConstraint.layout.topToBottom)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySectionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySectionTest.kt
index 58273d6..b5f668c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySectionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/view/layout/sections/DefaultDeviceEntrySectionTest.kt
@@ -22,7 +22,7 @@
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.constraintlayout.widget.ConstraintSet
 import androidx.test.filters.SmallTest
-import com.android.keyguard.LockIconViewController
+import com.android.keyguard.LegacyLockIconViewController
 import com.android.systemui.Flags as AConfigFlags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.biometrics.AuthController
@@ -38,6 +38,7 @@
 import com.android.systemui.statusbar.VibratorHelper
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.test.TestScope
@@ -58,7 +59,7 @@
     @Mock(answer = Answers.RETURNS_DEEP_STUBS) private lateinit var windowManager: WindowManager
     @Mock private lateinit var notificationPanelView: NotificationPanelView
     private lateinit var featureFlags: FakeFeatureFlags
-    @Mock private lateinit var lockIconViewController: LockIconViewController
+    @Mock private lateinit var lockIconViewController: LegacyLockIconViewController
     @Mock private lateinit var falsingManager: FalsingManager
     @Mock private lateinit var deviceEntryIconViewModel: DeviceEntryIconViewModel
     private lateinit var underTest: DefaultDeviceEntrySection
@@ -85,6 +86,7 @@
                 { mock(DeviceEntryBackgroundViewModel::class.java) },
                 { falsingManager },
                 { mock(VibratorHelper::class.java) },
+                mock(CoroutineDispatcher::class.java),
             )
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt
index 0322301..7b5dd1f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardClockViewModelTest.kt
@@ -30,14 +30,16 @@
 import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
+import com.android.systemui.keyguard.shared.ComposeLockscreen
 import com.android.systemui.plugins.clocks.ClockController
 import com.android.systemui.plugins.clocks.ClockFaceConfig
 import com.android.systemui.plugins.clocks.ClockFaceController
+import com.android.systemui.res.R
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shade.shared.model.ShadeMode
 import com.android.systemui.shared.clocks.ClockRegistry
 import com.android.systemui.statusbar.notification.domain.interactor.NotificationsKeyguardInteractor
-import com.android.systemui.statusbar.policy.SplitShadeStateController
+import com.android.systemui.util.Utils
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.settings.FakeSettings
 import com.google.common.truth.Truth.assertThat
@@ -67,12 +69,12 @@
     private lateinit var keyguardClockInteractor: KeyguardClockInteractor
     private lateinit var keyguardClockRepository: KeyguardClockRepository
     private lateinit var fakeSettings: FakeSettings
+    private val shadeMode = MutableStateFlow<ShadeMode>(ShadeMode.Single)
     @Mock private lateinit var clockRegistry: ClockRegistry
     @Mock private lateinit var clock: ClockController
     @Mock private lateinit var largeClock: ClockFaceController
     @Mock private lateinit var clockFaceConfig: ClockFaceConfig
     @Mock private lateinit var eventController: ClockEventController
-    @Mock private lateinit var splitShadeStateController: SplitShadeStateController
     @Mock private lateinit var notifsKeyguardInteractor: NotificationsKeyguardInteractor
     @Mock private lateinit var areNotificationsFullyHidden: Flow<Boolean>
     @Mock private lateinit var shadeInteractor: ShadeInteractor
@@ -100,7 +102,7 @@
         keyguardClockInteractor = KeyguardClockInteractor(keyguardClockRepository)
         whenever(notifsKeyguardInteractor.areNotificationsFullyHidden)
             .thenReturn(areNotificationsFullyHidden)
-        whenever(shadeInteractor.shadeMode).thenReturn(MutableStateFlow(ShadeMode.Single))
+        whenever(shadeInteractor.shadeMode).thenReturn(shadeMode)
         underTest =
             KeyguardClockViewModel(
                 keyguardInteractor,
@@ -153,6 +155,44 @@
             assertThat(value()).isEqualTo(false)
         }
 
+    @Test
+    fun testSmallClockTop_splitshade() =
+        scope.runTest {
+            shadeMode.value = ShadeMode.Split
+            if (!ComposeLockscreen.isEnabled) {
+                assertThat(underTest.getSmallClockTopMargin(context))
+                    .isEqualTo(
+                        context.resources.getDimensionPixelSize(
+                            R.dimen.keyguard_split_shade_top_margin
+                        )
+                    )
+            } else {
+                assertThat(underTest.getSmallClockTopMargin(context))
+                    .isEqualTo(
+                        context.resources.getDimensionPixelSize(
+                            R.dimen.keyguard_split_shade_top_margin
+                        ) - Utils.getStatusBarHeaderHeightKeyguard(context)
+                    )
+            }
+        }
+
+    @Test
+    fun testSmallClockTop_nonSplitshade() =
+        scope.runTest {
+            if (!ComposeLockscreen.isEnabled) {
+                assertThat(underTest.getSmallClockTopMargin(context))
+                    .isEqualTo(
+                        context.resources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin) +
+                            Utils.getStatusBarHeaderHeightKeyguard(context)
+                    )
+            } else {
+                assertThat(underTest.getSmallClockTopMargin(context))
+                    .isEqualTo(
+                        context.resources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin)
+                    )
+            }
+        }
+
     private fun setupMockClock() {
         whenever(clock.largeClock).thenReturn(largeClock)
         whenever(largeClock.config).thenReturn(clockFaceConfig)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/util/KeyguardTransitionRepositorySpySubject.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/util/KeyguardTransitionRepositorySpySubject.kt
index 655a551..a08e491 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/util/KeyguardTransitionRepositorySpySubject.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/util/KeyguardTransitionRepositorySpySubject.kt
@@ -21,8 +21,6 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionInfo
 import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.FailureMetadata
 import com.google.common.truth.Subject
 import com.google.common.truth.Truth
@@ -30,8 +28,6 @@
 import junit.framework.Assert.assertEquals
 import kotlin.test.fail
 import org.mockito.Mockito
-import org.mockito.Mockito.never
-import org.mockito.Mockito.verify
 
 /** [Subject] used to make assertions about a [Mockito.spy] KeyguardTransitionRepository. */
 class KeyguardTransitionRepositorySpySubject
@@ -45,7 +41,7 @@
      * parameters. If an animator param or assertion is not provided, we will not assert anything
      * about the animator.
      */
-    fun startedTransition(
+    suspend fun startedTransition(
         ownerName: String? = null,
         from: KeyguardState? = null,
         to: KeyguardState,
@@ -58,7 +54,7 @@
      * Asserts that we started a transition to the given state, optionally verifying additional
      * params.
      */
-    fun startedTransition(
+    suspend fun startedTransition(
         ownerName: String? = null,
         from: KeyguardState? = null,
         to: KeyguardState,
@@ -72,26 +68,41 @@
      * Asserts that we started a transition to the given state, optionally verifying additional
      * params.
      */
-    fun startedTransition(
+    suspend fun startedTransition(
         ownerName: String? = null,
         from: KeyguardState? = null,
         to: KeyguardState,
         animatorAssertion: (Subject) -> Unit,
         modeOnCanceled: TransitionModeOnCanceled? = null,
     ) {
-        withArgCaptor<TransitionInfo> { verify(repository).startTransition(capture()) }
-            .also { transitionInfo ->
+        // TODO(b/331799060): Remove this workaround once atest supports mocking suspend functions.
+        Mockito.mockingDetails(repository).invocations.forEach { invocation ->
+            if (invocation.method.equals(KeyguardTransitionRepository::startTransition.name)) {
+                val transitionInfo = invocation.arguments.firstOrNull() as TransitionInfo
                 assertEquals(to, transitionInfo.to)
                 animatorAssertion.invoke(Truth.assertThat(transitionInfo.animator))
                 from?.let { assertEquals(it, transitionInfo.from) }
                 ownerName?.let { assertEquals(it, transitionInfo.ownerName) }
                 modeOnCanceled?.let { assertEquals(it, transitionInfo.modeOnCanceled) }
+                invocation.markVerified()
             }
+        }
     }
 
     /** Verifies that [KeyguardTransitionRepository.startTransition] was never called. */
-    fun noTransitionsStarted() {
-        verify(repository, never()).startTransition(any())
+    suspend fun noTransitionsStarted() {
+        // TODO(b/331799060): Remove this workaround once atest supports mocking suspend functions.
+        Mockito.mockingDetails(repository).invocations.forEach {
+            if (
+                it.method.equals(KeyguardTransitionRepository::startTransition.name) &&
+                    !it.isVerified
+            ) {
+                fail(
+                    "Expected no transitions started, however this transition was started: " +
+                        it.arguments.firstOrNull()
+                )
+            }
+        }
     }
 
     companion object {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
index 564bdc3..b70cc30 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/domain/pipeline/MediaDataFilterImplTest.kt
@@ -64,6 +64,7 @@
 private const val PRIVATE_PROFILE = 12
 private const val PACKAGE = "PKG"
 private val INSTANCE_ID = InstanceId.fakeInstanceId(123)!!
+private val INSTANCE_ID_GUEST = InstanceId.fakeInstanceId(321)!!
 private const val APP_UID = 99
 private const val SMARTSPACE_KEY = "SMARTSPACE_KEY"
 private const val SMARTSPACE_PACKAGE = "SMARTSPACE_PKG"
@@ -75,7 +76,7 @@
 @TestableLooper.RunWithLooper
 class MediaDataFilterImplTest : SysuiTestCase() {
 
-    @Mock private lateinit var listener: MediaDataManager.Listener
+    @Mock private lateinit var listener: MediaDataFilterImpl.Listener
     @Mock private lateinit var userTracker: UserTracker
     @Mock private lateinit var broadcastSender: BroadcastSender
     @Mock private lateinit var mediaDataManager: MediaDataManager
@@ -128,8 +129,8 @@
                 instanceId = INSTANCE_ID,
                 appUid = APP_UID
             )
-        dataGuest = dataMain.copy(userId = USER_GUEST)
-        dataPrivateProfile = dataMain.copy(userId = PRIVATE_PROFILE)
+        dataGuest = dataMain.copy(userId = USER_GUEST, instanceId = INSTANCE_ID_GUEST)
+        dataPrivateProfile = dataMain.copy(userId = PRIVATE_PROFILE, instanceId = INSTANCE_ID_GUEST)
 
         whenever(smartspaceData.targetId).thenReturn(SMARTSPACE_KEY)
         whenever(smartspaceData.isActive).thenReturn(true)
@@ -166,8 +167,7 @@
         mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain)
 
         // THEN we should tell the listener
-        verify(listener)
-            .onMediaDataLoaded(eq(KEY), eq(null), eq(dataMain), eq(true), eq(0), eq(false))
+        verify(listener).onMediaDataLoaded(eq(dataMain.instanceId), eq(true), eq(0), eq(false))
     }
 
     @Test
@@ -176,8 +176,7 @@
         mediaDataFilter.onMediaDataLoaded(KEY, null, dataGuest)
 
         // THEN we should NOT tell the listener
-        verify(listener, never())
-            .onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt(), anyBoolean())
+        verify(listener, never()).onMediaDataLoaded(any(), anyBoolean(), anyInt(), anyBoolean())
     }
 
     @Test
@@ -187,7 +186,7 @@
         mediaDataFilter.onMediaDataRemoved(KEY)
 
         // THEN we should tell the listener
-        verify(listener).onMediaDataRemoved(eq(KEY))
+        verify(listener).onMediaDataRemoved(eq(dataMain.instanceId))
     }
 
     @Test
@@ -197,7 +196,7 @@
         mediaDataFilter.onMediaDataRemoved(KEY)
 
         // THEN we should NOT tell the listener
-        verify(listener, never()).onMediaDataRemoved(eq(KEY))
+        verify(listener, never()).onMediaDataRemoved(eq(dataGuest.instanceId))
     }
 
     @Test
@@ -209,7 +208,7 @@
         setUser(USER_GUEST)
 
         // THEN we should remove the main user's media
-        verify(listener).onMediaDataRemoved(eq(KEY))
+        verify(listener).onMediaDataRemoved(eq(dataMain.instanceId))
     }
 
     @Test
@@ -223,12 +222,11 @@
         setUser(USER_GUEST)
 
         // THEN we should add back the guest user media
-        verify(listener)
-            .onMediaDataLoaded(eq(KEY_ALT), eq(null), eq(dataGuest), eq(true), eq(0), eq(false))
+        verify(listener).onMediaDataLoaded(eq(dataGuest.instanceId), eq(true), eq(0), eq(false))
 
         // but not the main user's
         verify(listener, never())
-            .onMediaDataLoaded(eq(KEY), any(), eq(dataMain), anyBoolean(), anyInt(), anyBoolean())
+            .onMediaDataLoaded(eq(dataMain.instanceId), anyBoolean(), anyInt(), anyBoolean())
     }
 
     @Test
@@ -242,7 +240,7 @@
         setPrivateProfileUnavailable()
 
         // THEN we should add the private profile media
-        verify(listener).onMediaDataRemoved(eq(KEY_ALT))
+        verify(listener).onMediaDataRemoved(eq(dataPrivateProfile.instanceId))
     }
 
     @Test
@@ -311,7 +309,7 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
             val data = dataMain.copy(active = false)
             mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = data)
 
@@ -330,7 +328,7 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
             val data = dataMain.copy(active = true)
             mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = data)
 
@@ -349,7 +347,7 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
             whenever(smartspaceData.isActive).thenReturn(false)
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
@@ -368,7 +366,7 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
             whenever(smartspaceData.isValid()).thenReturn(false)
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
@@ -387,7 +385,7 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
             whenever(smartspaceData.isActive).thenReturn(true)
             whenever(smartspaceData.isValid()).thenReturn(true)
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
@@ -421,7 +419,7 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
             assertThat(
                     hasActiveMediaOrRecommendation(
                         selectedUserEntries,
@@ -470,12 +468,11 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
 
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
-            verify(listener)
-                .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(true))
+            verify(listener).onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(true))
             assertThat(
                     hasActiveMediaOrRecommendation(
                         selectedUserEntries,
@@ -494,15 +491,14 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
 
             whenever(smartspaceData.isActive).thenReturn(false)
 
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
-            verify(listener, never())
-                .onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt(), anyBoolean())
-            verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
+            verify(listener, never()).onMediaDataLoaded(any(), anyBoolean(), anyInt(), anyBoolean())
+            verify(listener, never()).onSmartspaceMediaDataLoaded(any(), anyBoolean())
             assertThat(
                     hasActiveMediaOrRecommendation(
                         selectedUserEntries,
@@ -521,14 +517,13 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
             val dataOld = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
             mediaDataFilter.onMediaDataLoaded(KEY, null, dataOld)
             clock.advanceTime(MediaDataFilterImpl.SMARTSPACE_MAX_AGE + 100)
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
-            verify(listener)
-                .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(true))
+            verify(listener).onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(true))
             assertThat(
                     hasActiveMediaOrRecommendation(
                         selectedUserEntries,
@@ -547,7 +542,7 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
             whenever(smartspaceData.isActive).thenReturn(false)
 
             val dataOld = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
@@ -555,7 +550,7 @@
             clock.advanceTime(MediaDataFilterImpl.SMARTSPACE_MAX_AGE + 100)
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
-            verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
+            verify(listener, never()).onSmartspaceMediaDataLoaded(any(), anyBoolean())
             assertThat(
                     hasActiveMediaOrRecommendation(
                         selectedUserEntries,
@@ -574,7 +569,7 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
 
             whenever(smartspaceData.isActive).thenReturn(false)
 
@@ -582,15 +577,15 @@
             val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
             mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
             verify(listener)
-                .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
+                .onMediaDataLoaded(eq(dataCurrent.instanceId), eq(true), eq(0), eq(false))
 
+            reset(listener)
             // AND we get a smartspace signal
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
             // THEN we should tell listeners to treat the media as not active instead
-            verify(listener, never())
-                .onMediaDataLoaded(eq(KEY), eq(KEY), any(), anyBoolean(), anyInt(), anyBoolean())
-            verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
+            verify(listener, never()).onMediaDataLoaded(any(), anyBoolean(), anyInt(), anyBoolean())
+            verify(listener, never()).onSmartspaceMediaDataLoaded(any(), anyBoolean())
             assertThat(
                     hasActiveMediaOrRecommendation(
                         selectedUserEntries,
@@ -609,14 +604,14 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
             whenever(smartspaceData.isValid()).thenReturn(false)
 
             // WHEN we have media that was recently played, but not currently active
             val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
             mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
             verify(listener)
-                .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
+                .onMediaDataLoaded(eq(dataCurrent.instanceId), eq(true), eq(0), eq(false))
 
             // AND we get a smartspace signal
             runCurrent()
@@ -625,14 +620,7 @@
             // THEN we should tell listeners to treat the media as active instead
             val dataCurrentAndActive = dataCurrent.copy(active = true)
             verify(listener)
-                .onMediaDataLoaded(
-                    eq(KEY),
-                    eq(KEY),
-                    eq(dataCurrentAndActive),
-                    eq(true),
-                    eq(100),
-                    eq(true)
-                )
+                .onMediaDataLoaded(eq(dataCurrentAndActive.instanceId), eq(true), eq(100), eq(true))
             assertThat(
                     hasActiveMediaOrRecommendation(
                         selectedUserEntries,
@@ -642,7 +630,7 @@
                 )
                 .isTrue()
             // Smartspace update shouldn't be propagated for the empty rec list.
-            verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
+            verify(listener, never()).onSmartspaceMediaDataLoaded(any(), anyBoolean())
             verify(logger, never()).logRecommendationAdded(any(), any())
             verify(logger).logRecommendationActivated(eq(APP_UID), eq(PACKAGE), eq(INSTANCE_ID))
         }
@@ -652,12 +640,12 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
             // WHEN we have media that was recently played, but not currently active
             val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
             mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
             verify(listener)
-                .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
+                .onMediaDataLoaded(eq(dataCurrent.instanceId), eq(true), eq(0), eq(false))
 
             // AND we get a smartspace signal
             runCurrent()
@@ -666,14 +654,7 @@
             // THEN we should tell listeners to treat the media as active instead
             val dataCurrentAndActive = dataCurrent.copy(active = true)
             verify(listener)
-                .onMediaDataLoaded(
-                    eq(KEY),
-                    eq(KEY),
-                    eq(dataCurrentAndActive),
-                    eq(true),
-                    eq(100),
-                    eq(true)
-                )
+                .onMediaDataLoaded(eq(dataCurrentAndActive.instanceId), eq(true), eq(100), eq(true))
             assertThat(
                     hasActiveMediaOrRecommendation(
                         selectedUserEntries,
@@ -683,8 +664,7 @@
                 )
                 .isTrue()
             // Smartspace update should also be propagated but not prioritized.
-            verify(listener)
-                .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
+            verify(listener).onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(false))
             verify(logger).logRecommendationAdded(SMARTSPACE_PACKAGE, SMARTSPACE_INSTANCE_ID)
             verify(logger).logRecommendationActivated(eq(APP_UID), eq(PACKAGE), eq(INSTANCE_ID))
         }
@@ -694,7 +674,7 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
 
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
             mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
@@ -716,25 +696,18 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
             val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
             mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
             verify(listener)
-                .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
+                .onMediaDataLoaded(eq(dataCurrent.instanceId), eq(true), eq(0), eq(false))
 
             runCurrent()
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
             val dataCurrentAndActive = dataCurrent.copy(active = true)
             verify(listener)
-                .onMediaDataLoaded(
-                    eq(KEY),
-                    eq(KEY),
-                    eq(dataCurrentAndActive),
-                    eq(true),
-                    eq(100),
-                    eq(true)
-                )
+                .onMediaDataLoaded(eq(dataCurrentAndActive.instanceId), eq(true), eq(100), eq(true))
 
             mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
 
@@ -755,14 +728,13 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
             whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(true)
             whenever(smartspaceData.isActive).thenReturn(false)
 
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
-            verify(listener)
-                .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
+            verify(listener).onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(false))
             assertThat(
                     hasActiveMediaOrRecommendation(
                         selectedUserEntries,
@@ -780,7 +752,7 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
 
             whenever(mediaFlags.isPersistentSsCardEnabled()).thenReturn(true)
             whenever(smartspaceData.isActive).thenReturn(false)
@@ -789,16 +761,15 @@
             val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
             mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
             verify(listener)
-                .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
+                .onMediaDataLoaded(eq(dataCurrent.instanceId), eq(true), eq(0), eq(false))
 
+            reset(listener)
             // And an inactive recommendation is loaded
             mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
             // Smartspace is loaded but the media stays inactive
-            verify(listener)
-                .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
-            verify(listener, never())
-                .onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt(), anyBoolean())
+            verify(listener).onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(false))
+            verify(listener, never()).onMediaDataLoaded(any(), anyBoolean(), anyInt(), anyBoolean())
             assertThat(
                     hasActiveMediaOrRecommendation(
                         selectedUserEntries,
@@ -835,12 +806,12 @@
         testScope.runTest {
             val selectedUserEntries by collectLastValue(mediaFilterRepository.selectedUserEntries)
             val smartspaceMediaData by collectLastValue(mediaFilterRepository.smartspaceMediaData)
-            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedKey)
+            val reactivatedKey by collectLastValue(mediaFilterRepository.reactivatedId)
             // WHEN we have media that was recently played, but not currently active
             val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
             mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
             verify(listener)
-                .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
+                .onMediaDataLoaded(eq(dataCurrent.instanceId), eq(true), eq(0), eq(false))
 
             // AND we get a smartspace signal with extra to trigger resume
             runCurrent()
@@ -851,14 +822,7 @@
             // THEN we should tell listeners to treat the media as active instead
             val dataCurrentAndActive = dataCurrent.copy(active = true)
             verify(listener)
-                .onMediaDataLoaded(
-                    eq(KEY),
-                    eq(KEY),
-                    eq(dataCurrentAndActive),
-                    eq(true),
-                    eq(100),
-                    eq(true)
-                )
+                .onMediaDataLoaded(eq(dataCurrentAndActive.instanceId), eq(true), eq(100), eq(true))
             assertThat(
                     hasActiveMediaOrRecommendation(
                         selectedUserEntries,
@@ -868,8 +832,7 @@
                 )
                 .isTrue()
             // And send the smartspace data, but not prioritized
-            verify(listener)
-                .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
+            verify(listener).onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(false))
         }
 
     @Test
@@ -877,8 +840,7 @@
         // WHEN we have media that was recently played, but not currently active
         val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
         mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
-        verify(listener)
-            .onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true), eq(0), eq(false))
+        verify(listener).onMediaDataLoaded(eq(dataCurrent.instanceId), eq(true), eq(0), eq(false))
 
         // AND we get a smartspace signal with extra to not trigger resume
         val extras = Bundle().apply { putBoolean(EXTRA_KEY_TRIGGER_RESUME, false) }
@@ -886,32 +848,30 @@
         mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
 
         // THEN listeners are not updated to show media
-        verify(listener, never())
-            .onMediaDataLoaded(eq(KEY), eq(KEY), any(), eq(true), eq(100), eq(true))
+        verify(listener, never()).onMediaDataLoaded(any(), eq(true), eq(100), eq(true))
         // But the smartspace update is still propagated
-        verify(listener)
-            .onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
+        verify(listener).onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(false))
     }
 
     private fun hasActiveMediaOrRecommendation(
-        entries: Map<String, MediaData>?,
+        entries: Map<InstanceId, MediaData>?,
         smartspaceMediaData: SmartspaceMediaData?,
-        reactivatedKey: String?
+        reactivatedId: InstanceId?
     ): Boolean {
         if (entries == null || smartspaceMediaData == null) {
             return false
         }
         return entries.any { it.value.active } ||
             (smartspaceMediaData.isActive &&
-                (smartspaceMediaData.isValid() || reactivatedKey != null))
+                (smartspaceMediaData.isValid() || reactivatedId != null))
     }
 
-    private fun hasActiveMedia(entries: Map<String, MediaData>?): Boolean {
+    private fun hasActiveMedia(entries: Map<InstanceId, MediaData>?): Boolean {
         return entries?.any { it.value.active } ?: false
     }
 
     private fun hasAnyMediaOrRecommendation(
-        entries: Map<String, MediaData>?,
+        entries: Map<InstanceId, MediaData>?,
         smartspaceMediaData: SmartspaceMediaData?
     ): Boolean {
         if (entries == null || smartspaceMediaData == null) {
@@ -925,7 +885,7 @@
             })
     }
 
-    private fun hasAnyMedia(entries: Map<String, MediaData>?): Boolean {
+    private fun hasAnyMedia(entries: Map<InstanceId, MediaData>?): Boolean {
         return entries?.isNotEmpty() ?: false
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index 695d3b2..ca403e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -19,6 +19,7 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -47,6 +48,7 @@
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+import com.android.settingslib.media.LocalMediaManager;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.DialogTransitionAnimator;
 import com.android.systemui.broadcast.BroadcastSender;
@@ -127,6 +129,12 @@
                 mNearbyMediaDevicesManager, mAudioManager, mPowerExemptionManager,
                 mKeyguardManager, mFlags, mUserTracker);
 
+        // Using a fake package will cause routing operations to fail, so we intercept
+        // scanning-related operations.
+        mMediaOutputController.mLocalMediaManager = mock(LocalMediaManager.class);
+        doNothing().when(mMediaOutputController.mLocalMediaManager).startScan();
+        doNothing().when(mMediaOutputController.mLocalMediaManager).stopScan();
+
         mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext, mBroadcastSender,
                 mMediaOutputController);
         mMediaOutputBaseDialogImpl.onCreate(new Bundle());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
index e5ba569..a702dda 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/NavBarHelperTest.java
@@ -41,6 +41,7 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.accessibility.AccessibilityButtonModeObserver;
 import com.android.systemui.accessibility.AccessibilityButtonTargetsObserver;
@@ -56,6 +57,8 @@
 import com.android.systemui.statusbar.phone.CentralSurfaces;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 
+import dagger.Lazy;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -67,8 +70,6 @@
 import java.util.Optional;
 import java.util.concurrent.Executor;
 
-import dagger.Lazy;
-
 /**
  * Tests for {@link NavBarHelper}.
  */
@@ -269,8 +270,8 @@
 
     @Test
     public void initNavBarHelper_buttonModeNavBar_a11yButtonClickableState() {
-        when(mAccessibilityManager.getAccessibilityShortcutTargets(
-                AccessibilityManager.ACCESSIBILITY_BUTTON)).thenReturn(createFakeShortcutTargets());
+        when(mAccessibilityManager.getAccessibilityShortcutTargets(UserShortcutType.SOFTWARE))
+                .thenReturn(createFakeShortcutTargets());
 
         mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
 
@@ -294,8 +295,8 @@
         when(mAccessibilityButtonModeObserver.getCurrentAccessibilityButtonMode()).thenReturn(
                 ACCESSIBILITY_BUTTON_MODE_NAVIGATION_BAR);
 
-        when(mAccessibilityManager.getAccessibilityShortcutTargets(
-                AccessibilityManager.ACCESSIBILITY_BUTTON)).thenReturn(createFakeShortcutTargets());
+        when(mAccessibilityManager.getAccessibilityShortcutTargets(UserShortcutType.SOFTWARE))
+                .thenReturn(createFakeShortcutTargets());
         mAccessibilityServicesStateChangeListener.onAccessibilityServicesStateChanged(
                 mAccessibilityManager);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HearingDevicesTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HearingDevicesTileTest.java
index 326df5c..73aa54c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HearingDevicesTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/HearingDevicesTileTest.java
@@ -21,6 +21,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.content.Intent;
 import android.os.Handler;
@@ -29,12 +30,14 @@
 import android.provider.Settings;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.view.View;
 
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.accessibility.hearingaid.HearingDevicesDialogManager;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -73,6 +76,8 @@
     private ActivityStarter mActivityStarter;
     @Mock
     private QSLogger mQSLogger;
+    @Mock
+    HearingDevicesDialogManager mHearingDevicesDialogManager;
 
     private TestableLooper mTestableLooper;
     private HearingDevicesTile mTile;
@@ -80,6 +85,7 @@
     @Before
     public void setUp() throws Exception {
         mTestableLooper = TestableLooper.get(this);
+        when(mHost.getContext()).thenReturn(mContext);
 
         mTile = new HearingDevicesTile(
                 mHost,
@@ -90,7 +96,8 @@
                 mMetricsLogger,
                 mStatusBarStateController,
                 mActivityStarter,
-                mQSLogger);
+                mQSLogger,
+                mHearingDevicesDialogManager);
 
         mTile.initialize();
         mTestableLooper.processAllMessages();
@@ -125,4 +132,13 @@
         assertThat(IntentCaptor.getValue().getAction()).isEqualTo(
                 Settings.ACTION_HEARING_DEVICES_SETTINGS);
     }
+
+    @Test
+    public void handleClick_dialogShown() {
+        View view = new View(mContext);
+        mTile.handleClick(view);
+        mTestableLooper.processAllMessages();
+
+        verify(mHearingDevicesDialogManager).showDialog(view);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
index 2d18f92..122d9e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java
@@ -58,7 +58,6 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.res.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManagerFake;
 import com.android.systemui.plugins.ActivityStarter;
@@ -68,6 +67,7 @@
 import com.android.systemui.qs.QsEventLogger;
 import com.android.systemui.qs.logging.QSLogger;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.res.R;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
 import com.android.systemui.util.settings.SecureSettings;
 import com.android.systemui.wallet.controller.QuickAccessWalletController;
@@ -198,7 +198,8 @@
     }
 
     @Test
-    public void testIsAvailable_qawFeatureAvailable() {
+    public void testIsAvailable_qawFeatureAvailableWalletUnavailable() {
+        when(mController.isWalletRoleAvailable()).thenReturn(false);
         when(mPackageManager.hasSystemFeature(FEATURE_NFC_HOST_CARD_EMULATION)).thenReturn(true);
         when(mPackageManager.hasSystemFeature("org.chromium.arc")).thenReturn(false);
         when(mSecureSettings.getStringForUser(NFC_PAYMENT_DEFAULT_COMPONENT,
@@ -208,6 +209,16 @@
     }
 
     @Test
+    public void testIsAvailable_nfcUnavailableWalletAvailable() {
+        when(mController.isWalletRoleAvailable()).thenReturn(true);
+        when(mHost.getUserId()).thenReturn(PRIMARY_USER_ID);
+        when(mPackageManager.hasSystemFeature(FEATURE_NFC_HOST_CARD_EMULATION)).thenReturn(false);
+        when(mPackageManager.hasSystemFeature("org.chromium.arc")).thenReturn(false);
+
+        assertTrue(mTile.isAvailable());
+    }
+
+    @Test
     public void testHandleClick_startQuickAccessUiIntent_noCard() {
         setUpWalletCard(/* hasCard= */ false);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt
index ea2b22c..0ec8552 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt
@@ -77,7 +77,7 @@
         underTest =
             QSTileViewModelImpl(
                 QSTileConfigTestBuilder.build {
-                    policy = QSTilePolicy.Restricted("test_restriction")
+                    policy = QSTilePolicy.Restricted(listOf("test_restriction"))
                 },
                 { tileUserActionInteractor },
                 { tileDataInteractor },
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java
index 74f50df..b384fe8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateControllerTest.java
@@ -37,6 +37,7 @@
 import android.net.ConnectivityManager;
 import android.net.Network;
 import android.net.NetworkCapabilities;
+import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.os.Handler;
 import android.telephony.ServiceState;
@@ -176,6 +177,8 @@
     private WifiStateWorker mWifiStateWorker;
     @Mock
     private SignalStrength mSignalStrength;
+    @Mock
+    private WifiConfiguration mWifiConfiguration;
 
     private FakeFeatureFlags mFlags = new FakeFeatureFlags();
 
@@ -1037,9 +1040,19 @@
     }
 
     @Test
+    public void getConfiguratorQrCodeGeneratorIntentOrNull_configurationNull_returnNull() {
+        mFlags.set(Flags.SHARE_WIFI_QS_BUTTON, true);
+        when(mConnectedEntry.canShare()).thenReturn(true);
+        when(mConnectedEntry.getWifiConfiguration()).thenReturn(null);
+        assertThat(mInternetDialogController.getConfiguratorQrCodeGeneratorIntentOrNull(
+                mConnectedEntry)).isNull();
+    }
+
+    @Test
     public void getConfiguratorQrCodeGeneratorIntentOrNull_wifiShareable() {
         mFlags.set(Flags.SHARE_WIFI_QS_BUTTON, true);
         when(mConnectedEntry.canShare()).thenReturn(true);
+        when(mConnectedEntry.getWifiConfiguration()).thenReturn(mWifiConfiguration);
         assertThat(mInternetDialogController.getConfiguratorQrCodeGeneratorIntentOrNull(
                 mConnectedEntry)).isNotNull();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt
index 1cfca68..9104f8e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/recordissue/RecordIssueDialogDelegateTest.kt
@@ -94,7 +94,7 @@
         MockitoAnnotations.initMocks(this)
         whenever(dprLazy.get()).thenReturn(devicePolicyResolver)
         whenever(sysuiState.setFlag(anyInt(), anyBoolean())).thenReturn(sysuiState)
-        whenever(screenCaptureDisabledDialogDelegate.createDialog())
+        whenever(screenCaptureDisabledDialogDelegate.createSysUIDialog())
             .thenReturn(screenCaptureDisabledDialog)
         whenever(
                 userFileManager.getSharedPreferences(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
index b3df12ee..9e559de 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/RecordingControllerTest.java
@@ -128,7 +128,7 @@
         );
 
         mFeatureFlags = new FakeFeatureFlags();
-        when(mScreenCaptureDisabledDialogDelegate.createDialog())
+        when(mScreenCaptureDisabledDialogDelegate.createSysUIDialog())
                 .thenReturn(mScreenCaptureDisabledDialog);
         when(mScreenRecordDialogFactory.create(any(), any()))
                 .thenReturn(mScreenRecordDialogDelegate);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt
index 6e48074..9432451 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordPermissionDialogDelegateTest.kt
@@ -39,7 +39,6 @@
 import com.android.systemui.settings.UserContextProvider
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.statusbar.phone.SystemUIDialogManager
-import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
@@ -50,6 +49,7 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.eq
+import org.mockito.Mockito.never
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
@@ -59,7 +59,6 @@
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 class ScreenRecordPermissionDialogDelegateTest : SysuiTestCase() {
 
-    //@Mock private lateinit var dialogFactory: SystemUIDialog.Factory
     @Mock private lateinit var starter: ActivityStarter
     @Mock private lateinit var controller: RecordingController
     @Mock private lateinit var userContextProvider: UserContextProvider
@@ -76,13 +75,13 @@
         whenever(flags.isEnabled(Flags.WM_ENABLE_PARTIAL_SCREEN_SHARING)).thenReturn(true)
 
         val systemUIDialogFactory =
-                SystemUIDialog.Factory(
-                        context,
-                        Dependency.get(SystemUIDialogManager::class.java),
-                        Dependency.get(SysUiState::class.java),
-                        Dependency.get(BroadcastDispatcher::class.java),
-                        Dependency.get(DialogTransitionAnimator::class.java),
-                )
+            SystemUIDialog.Factory(
+                context,
+                Dependency.get(SystemUIDialogManager::class.java),
+                Dependency.get(SysUiState::class.java),
+                Dependency.get(BroadcastDispatcher::class.java),
+                Dependency.get(DialogTransitionAnimator::class.java),
+            )
 
         val delegate =
             ScreenRecordPermissionDialogDelegate(
@@ -94,6 +93,7 @@
                 onStartRecordingClicked,
                 mediaProjectionMetricsLogger,
                 systemUIDialogFactory,
+                context,
             )
         dialog = delegate.createDialog()
     }
@@ -189,6 +189,17 @@
         verify(mediaProjectionMetricsLogger).notifyProjectionRequestCancelled(TEST_HOST_UID)
     }
 
+    @Test
+    fun showDialog_singleAppSelected_clickOnStart_projectionRequestCancelledIsNotLoggedOnce() {
+        showDialog()
+        onSpinnerItemSelected(SINGLE_APP)
+
+        clickOnStart()
+
+        verify(mediaProjectionMetricsLogger, never())
+            .notifyProjectionRequestCancelled(TEST_HOST_UID)
+    }
+
     private fun showDialog() {
         dialog.show()
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt
new file mode 100644
index 0000000..4a5cf57
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/DefaultScreenshotActionsProviderTest.kt
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.screenshot
+
+import android.app.ActivityOptions
+import android.app.ExitTransitionCoordinator
+import android.app.Notification
+import android.app.PendingIntent
+import android.content.Intent
+import android.net.Uri
+import android.os.UserHandle
+import android.testing.AndroidTestingRunner
+import android.view.accessibility.AccessibilityManager
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.clipboardoverlay.EditTextActivity
+import com.android.systemui.res.R
+import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import kotlin.test.Ignore
+import kotlin.test.Test
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestCoroutineScheduler
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Assert.assertNotNull
+import org.junit.Before
+import org.junit.runner.RunWith
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.kotlin.any
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.verifyBlocking
+import org.mockito.kotlin.whenever
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class DefaultScreenshotActionsProviderTest : SysuiTestCase() {
+    private val scheduler = TestCoroutineScheduler()
+    private val mainDispatcher = StandardTestDispatcher(scheduler)
+    private val testScope = TestScope(mainDispatcher)
+
+    private val actionIntentExecutor = mock<ActionIntentExecutor>()
+    private val accessibilityManager = mock<AccessibilityManager>()
+    private val uiEventLogger = mock<UiEventLogger>()
+    private val smartActionsProvider = mock<SmartActionsProvider>()
+    private val transition = mock<android.util.Pair<ActivityOptions, ExitTransitionCoordinator>>()
+    private val requestDismissal = mock<() -> Unit>()
+
+    private val request = ScreenshotData.forTesting()
+    private val invalidResult = ScreenshotController.SavedImageData()
+    private val validResult =
+        ScreenshotController.SavedImageData().apply {
+            uri = Uri.EMPTY
+            owner = UserHandle.OWNER
+            subject = "Test"
+            imageTime = 0
+        }
+
+    private lateinit var viewModel: ScreenshotViewModel
+    private lateinit var actionsProvider: ScreenshotActionsProvider
+
+    @Before
+    fun setUp() {
+        viewModel = ScreenshotViewModel(accessibilityManager)
+        request.userHandle = UserHandle.OWNER
+    }
+
+    @Test
+    fun previewActionAccessed_beforeScreenshotCompleted_doesNothing() {
+        actionsProvider = createActionsProvider()
+
+        assertNotNull(viewModel.previewAction.value)
+        viewModel.previewAction.value!!.invoke()
+        verifyNoMoreInteractions(actionIntentExecutor)
+    }
+
+    @Test
+    fun actionButtonsAccessed_beforeScreenshotCompleted_doesNothing() {
+        actionsProvider = createActionsProvider()
+
+        assertThat(viewModel.actions.value.size).isEqualTo(2)
+        val firstAction = viewModel.actions.value[0]
+        assertThat(firstAction.onClicked).isNotNull()
+        val secondAction = viewModel.actions.value[1]
+        assertThat(secondAction.onClicked).isNotNull()
+        firstAction.onClicked!!.invoke()
+        secondAction.onClicked!!.invoke()
+        verifyNoMoreInteractions(actionIntentExecutor)
+    }
+
+    @Test
+    fun actionAccessed_withInvalidResult_doesNothing() {
+        actionsProvider = createActionsProvider()
+
+        actionsProvider.setCompletedScreenshot(invalidResult)
+        viewModel.previewAction.value!!.invoke()
+        viewModel.actions.value[1].onClicked!!.invoke()
+
+        verifyNoMoreInteractions(actionIntentExecutor)
+    }
+
+    @Test
+    @Ignore("b/332526567")
+    fun actionAccessed_withResult_launchesIntent() = runTest {
+        actionsProvider = createActionsProvider()
+
+        actionsProvider.setCompletedScreenshot(validResult)
+        viewModel.actions.value[0].onClicked!!.invoke()
+        scheduler.advanceUntilIdle()
+
+        verify(uiEventLogger).log(eq(ScreenshotEvent.SCREENSHOT_EDIT_TAPPED), eq(0), eq(""))
+        val intentCaptor = argumentCaptor<Intent>()
+        verifyBlocking(actionIntentExecutor) {
+            launchIntent(capture(intentCaptor), eq(transition), eq(UserHandle.CURRENT), eq(true))
+        }
+        assertThat(intentCaptor.value.action).isEqualTo(Intent.ACTION_EDIT)
+    }
+
+    @Test
+    @Ignore("b/332526567")
+    fun actionAccessed_whilePending_launchesMostRecentAction() = runTest {
+        actionsProvider = createActionsProvider()
+
+        viewModel.actions.value[0].onClicked!!.invoke()
+        viewModel.previewAction.value!!.invoke()
+        viewModel.actions.value[1].onClicked!!.invoke()
+        actionsProvider.setCompletedScreenshot(validResult)
+        scheduler.advanceUntilIdle()
+
+        verify(uiEventLogger).log(eq(ScreenshotEvent.SCREENSHOT_SHARE_TAPPED), eq(0), eq(""))
+        val intentCaptor = argumentCaptor<Intent>()
+        verifyBlocking(actionIntentExecutor) {
+            launchIntent(capture(intentCaptor), eq(transition), eq(UserHandle.CURRENT), eq(false))
+        }
+        assertThat(intentCaptor.value.action).isEqualTo(Intent.ACTION_CHOOSER)
+    }
+
+    @Test
+    fun quickShareTapped_wrapsAndSendsIntent() = runTest {
+        val quickShare =
+            Notification.Action(
+                R.drawable.ic_screenshot_edit,
+                "TestQuickShare",
+                PendingIntent.getActivity(
+                    context,
+                    0,
+                    Intent(context, EditTextActivity::class.java),
+                    PendingIntent.FLAG_MUTABLE
+                )
+            )
+        whenever(smartActionsProvider.requestQuickShare(any(), any(), any())).then {
+            (it.getArgument(2) as ((Notification.Action) -> Unit)).invoke(quickShare)
+        }
+        whenever(smartActionsProvider.wrapIntent(any(), any(), any(), any())).thenAnswer {
+            it.getArgument(0)
+        }
+        actionsProvider = createActionsProvider()
+
+        viewModel.actions.value[2].onClicked?.invoke()
+        verify(uiEventLogger, never())
+            .log(eq(ScreenshotEvent.SCREENSHOT_SMART_ACTION_TAPPED), any(), any())
+        verify(smartActionsProvider, never()).wrapIntent(any(), any(), any(), any())
+        actionsProvider.setCompletedScreenshot(validResult)
+        verify(smartActionsProvider)
+            .wrapIntent(eq(quickShare), eq(validResult.uri), eq(validResult.subject), eq("testid"))
+        verify(uiEventLogger).log(eq(ScreenshotEvent.SCREENSHOT_SMART_ACTION_TAPPED), eq(0), eq(""))
+    }
+
+    private fun createActionsProvider(): ScreenshotActionsProvider {
+        return DefaultScreenshotActionsProvider(
+            context,
+            viewModel,
+            actionIntentExecutor,
+            smartActionsProvider,
+            uiEventLogger,
+            testScope,
+            request,
+            "testid",
+            { transition },
+            requestDismissal,
+        )
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
index 5ca6cf1..e611da0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/GlanceableHubContainerControllerTest.kt
@@ -36,22 +36,30 @@
 import com.android.systemui.communal.domain.interactor.setCommunalAvailable
 import com.android.systemui.communal.shared.model.CommunalScenes
 import com.android.systemui.communal.ui.viewmodel.CommunalViewModel
+import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
+import com.android.systemui.keyguard.data.repository.fakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.res.R
 import com.android.systemui.scene.shared.model.sceneDataSourceDelegator
+import com.android.systemui.shade.data.repository.fakeShadeRepository
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.statusbar.phone.SystemUIDialogFactory
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
 import org.junit.After
 import org.junit.Assert.assertThrows
 import org.junit.Before
@@ -75,10 +83,11 @@
         }
 
     @Mock private lateinit var communalViewModel: CommunalViewModel
-    @Mock private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
-    @Mock private lateinit var shadeInteractor: ShadeInteractor
     @Mock private lateinit var powerManager: PowerManager
     @Mock private lateinit var dialogFactory: SystemUIDialogFactory
+    private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
+    private lateinit var shadeInteractor: ShadeInteractor
+    private lateinit var keyguardInteractor: KeyguardInteractor
 
     private lateinit var parentView: FrameLayout
     private lateinit var containerView: View
@@ -88,15 +97,15 @@
     private lateinit var communalRepository: FakeCommunalRepository
     private lateinit var underTest: GlanceableHubContainerController
 
-    private val bouncerShowingFlow = MutableStateFlow(false)
-    private val shadeShowingFlow = MutableStateFlow(false)
-
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
 
         communalInteractor = kosmos.communalInteractor
         communalRepository = kosmos.fakeCommunalRepository
+        keyguardTransitionInteractor = kosmos.keyguardTransitionInteractor
+        keyguardInteractor = kosmos.keyguardInteractor
+        shadeInteractor = kosmos.shadeInteractor
 
         underTest =
             GlanceableHubContainerController(
@@ -104,16 +113,13 @@
                 communalViewModel,
                 dialogFactory,
                 keyguardTransitionInteractor,
+                keyguardInteractor,
                 shadeInteractor,
                 powerManager,
                 kosmos.sceneDataSourceDelegator,
             )
         testableLooper = TestableLooper.get(this)
 
-        whenever(keyguardTransitionInteractor.isFinishedInStateWhere(any()))
-            .thenReturn(bouncerShowingFlow)
-        whenever(shadeInteractor.isAnyFullyExpanded).thenReturn(shadeShowingFlow)
-
         overrideResource(R.dimen.communal_right_edge_swipe_region_width, RIGHT_SWIPE_REGION_WIDTH)
         overrideResource(R.dimen.communal_top_edge_swipe_region_height, TOP_SWIPE_REGION_WIDTH)
         overrideResource(
@@ -138,116 +144,182 @@
     }
 
     @Test
-    fun initView_calledTwice_throwsException() {
-        underTest =
-            GlanceableHubContainerController(
-                communalInteractor,
-                communalViewModel,
-                dialogFactory,
-                keyguardTransitionInteractor,
-                shadeInteractor,
-                powerManager,
-                kosmos.sceneDataSourceDelegator,
-            )
+    fun initView_calledTwice_throwsException() =
+        with(kosmos) {
+            testScope.runTest {
+                underTest =
+                    GlanceableHubContainerController(
+                        communalInteractor,
+                        communalViewModel,
+                        dialogFactory,
+                        keyguardTransitionInteractor,
+                        keyguardInteractor,
+                        shadeInteractor,
+                        powerManager,
+                        kosmos.sceneDataSourceDelegator,
+                    )
 
-        // First call succeeds.
-        underTest.initView(context)
+                // First call succeeds.
+                underTest.initView(context)
 
-        // Second call throws.
-        assertThrows(RuntimeException::class.java) { underTest.initView(context) }
-    }
+                // Second call throws.
+                assertThrows(RuntimeException::class.java) { underTest.initView(context) }
+            }
+        }
 
     @Test
-    fun onTouchEvent_communalClosed_doesNotIntercept() {
-        // Communal is closed.
-        goToScene(CommunalScenes.Blank)
+    fun onTouchEvent_communalClosed_doesNotIntercept() =
+        with(kosmos) {
+            testScope.runTest {
+                // Communal is closed.
+                goToScene(CommunalScenes.Blank)
 
-        assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
-    }
+                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
+            }
+        }
 
     @Test
-    fun onTouchEvent_openGesture_interceptsTouches() {
-        // Communal is closed.
-        goToScene(CommunalScenes.Blank)
+    fun onTouchEvent_openGesture_interceptsTouches() =
+        with(kosmos) {
+            testScope.runTest {
+                // Communal is closed.
+                goToScene(CommunalScenes.Blank)
 
-        // Initial touch down is intercepted, and so are touches outside of the region, until an
-        // up event is received.
-        assertThat(underTest.onTouchEvent(DOWN_IN_RIGHT_SWIPE_REGION_EVENT)).isTrue()
-        assertThat(underTest.onTouchEvent(MOVE_EVENT)).isTrue()
-        assertThat(underTest.onTouchEvent(UP_EVENT)).isTrue()
-        assertThat(underTest.onTouchEvent(MOVE_EVENT)).isFalse()
-    }
+                // Initial touch down is intercepted, and so are touches outside of the region,
+                // until an
+                // up event is received.
+                assertThat(underTest.onTouchEvent(DOWN_IN_RIGHT_SWIPE_REGION_EVENT)).isTrue()
+                assertThat(underTest.onTouchEvent(MOVE_EVENT)).isTrue()
+                assertThat(underTest.onTouchEvent(UP_EVENT)).isTrue()
+                assertThat(underTest.onTouchEvent(MOVE_EVENT)).isFalse()
+            }
+        }
 
     @Test
-    fun onTouchEvent_communalOpen_interceptsTouches() {
-        // Communal is open.
-        goToScene(CommunalScenes.Communal)
+    fun onTouchEvent_communalOpen_interceptsTouches() =
+        with(kosmos) {
+            testScope.runTest {
+                // Communal is open.
+                goToScene(CommunalScenes.Communal)
 
-        // Touch events are intercepted outside of any gesture areas.
-        assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
-        // User activity sent to PowerManager.
-        verify(powerManager).userActivity(any(), any(), any())
-    }
+                // Touch events are intercepted outside of any gesture areas.
+                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
+                // User activity sent to PowerManager.
+                verify(powerManager).userActivity(any(), any(), any())
+            }
+        }
 
     @Test
-    fun onTouchEvent_topSwipeWhenCommunalOpen_doesNotIntercept() {
-        // Communal is open.
-        goToScene(CommunalScenes.Communal)
+    fun onTouchEvent_topSwipeWhenCommunalOpen_doesNotIntercept() =
+        with(kosmos) {
+            testScope.runTest {
+                // Communal is open.
+                goToScene(CommunalScenes.Communal)
 
-        // Touch event in the top swipe reqgion is not intercepted.
-        assertThat(underTest.onTouchEvent(DOWN_IN_TOP_SWIPE_REGION_EVENT)).isFalse()
-    }
+                // Touch event in the top swipe region is not intercepted.
+                assertThat(underTest.onTouchEvent(DOWN_IN_TOP_SWIPE_REGION_EVENT)).isFalse()
+            }
+        }
 
     @Test
-    fun onTouchEvent_bottomSwipeWhenCommunalOpen_doesNotIntercept() {
-        // Communal is open.
-        goToScene(CommunalScenes.Communal)
+    fun onTouchEvent_bottomSwipeWhenCommunalOpen_doesNotIntercept() =
+        with(kosmos) {
+            testScope.runTest {
+                // Communal is open.
+                goToScene(CommunalScenes.Communal)
 
-        // Touch event in the bottom swipe reqgion is not intercepted.
-        assertThat(underTest.onTouchEvent(DOWN_IN_BOTTOM_SWIPE_REGION_EVENT)).isFalse()
-    }
+                // Touch event in the bottom swipe region is not intercepted.
+                assertThat(underTest.onTouchEvent(DOWN_IN_BOTTOM_SWIPE_REGION_EVENT)).isFalse()
+            }
+        }
 
     @Test
-    fun onTouchEvent_communalAndBouncerShowing_doesNotIntercept() {
-        // Communal is open.
-        goToScene(CommunalScenes.Communal)
+    fun onTouchEvent_topSwipeWhenDreaming_doesNotIntercept() =
+        with(kosmos) {
+            testScope.runTest {
+                // Communal is open.
+                goToScene(CommunalScenes.Communal)
 
-        // Bouncer is visible.
-        bouncerShowingFlow.value = true
-        testableLooper.processAllMessages()
+                // Device is dreaming.
+                fakeKeyguardRepository.setDreaming(true)
+                runCurrent()
 
-        // Touch events are not intercepted.
-        assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
-        // User activity is not sent to PowerManager.
-        verify(powerManager, times(0)).userActivity(any(), any(), any())
-    }
+                // Touch event in the top swipe region is not intercepted.
+                assertThat(underTest.onTouchEvent(DOWN_IN_TOP_SWIPE_REGION_EVENT)).isFalse()
+            }
+        }
 
     @Test
-    fun onTouchEvent_communalAndShadeShowing_doesNotIntercept() {
-        // Communal is open.
-        goToScene(CommunalScenes.Communal)
+    fun onTouchEvent_bottomSwipeWhenDreaming_doesNotIntercept() =
+        with(kosmos) {
+            testScope.runTest {
+                // Communal is open.
+                goToScene(CommunalScenes.Communal)
 
-        shadeShowingFlow.value = true
-        testableLooper.processAllMessages()
+                // Device is dreaming.
+                fakeKeyguardRepository.setDreaming(true)
+                runCurrent()
 
-        // Touch events are not intercepted.
-        assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
-    }
+                // Touch event in the bottom swipe region is not intercepted.
+                assertThat(underTest.onTouchEvent(DOWN_IN_BOTTOM_SWIPE_REGION_EVENT)).isFalse()
+            }
+        }
 
     @Test
-    fun onTouchEvent_containerViewDisposed_doesNotIntercept() {
-        // Communal is open.
-        goToScene(CommunalScenes.Communal)
+    fun onTouchEvent_communalAndBouncerShowing_doesNotIntercept() =
+        with(kosmos) {
+            testScope.runTest {
+                // Communal is open.
+                goToScene(CommunalScenes.Communal)
 
-        // Touch events are intercepted.
-        assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
+                // Bouncer is visible.
+                fakeKeyguardTransitionRepository.sendTransitionSteps(
+                    KeyguardState.GLANCEABLE_HUB,
+                    KeyguardState.PRIMARY_BOUNCER,
+                    testScope
+                )
+                testableLooper.processAllMessages()
 
-        // Container view disposed.
-        underTest.disposeView()
+                // Touch events are not intercepted.
+                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
+                // User activity is not sent to PowerManager.
+                verify(powerManager, times(0)).userActivity(any(), any(), any())
+            }
+        }
 
-        // Touch events are not intercepted.
-        assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
-    }
+    @Test
+    fun onTouchEvent_communalAndShadeShowing_doesNotIntercept() =
+        with(kosmos) {
+            testScope.runTest {
+                // Communal is open.
+                goToScene(CommunalScenes.Communal)
+
+                // Shade shows up.
+                fakeShadeRepository.setQsExpansion(1.0f)
+                testableLooper.processAllMessages()
+
+                // Touch events are not intercepted.
+                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
+            }
+        }
+
+    @Test
+    fun onTouchEvent_containerViewDisposed_doesNotIntercept() =
+        with(kosmos) {
+            testScope.runTest {
+                // Communal is open.
+                goToScene(CommunalScenes.Communal)
+
+                // Touch events are intercepted.
+                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isTrue()
+
+                // Container view disposed.
+                underTest.disposeView()
+
+                // Touch events are not intercepted.
+                assertThat(underTest.onTouchEvent(DOWN_EVENT)).isFalse()
+            }
+        }
 
     private fun initAndAttachContainerView() {
         containerView = View(context)
@@ -259,6 +331,8 @@
 
         // Attach the view so that flows start collecting.
         ViewUtils.attachView(parentView)
+        // Attaching is async so processAllMessages is required for view.repeatWhenAttached to run.
+        testableLooper.processAllMessages()
 
         // Give the view a fixed size to simplify testing for edge swipes.
         val lp =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index e957ca2..dfe72cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -73,7 +73,7 @@
 import com.android.keyguard.KeyguardStatusView;
 import com.android.keyguard.KeyguardStatusViewController;
 import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.LockIconViewController;
+import com.android.keyguard.LegacyLockIconViewController;
 import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
 import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
 import com.android.keyguard.dagger.KeyguardStatusViewComponent;
@@ -278,7 +278,7 @@
     @Mock protected AmbientState mAmbientState;
     @Mock protected UserManager mUserManager;
     @Mock protected UiEventLogger mUiEventLogger;
-    @Mock protected LockIconViewController mLockIconViewController;
+    @Mock protected LegacyLockIconViewController mLockIconViewController;
     @Mock protected KeyguardViewConfigurator mKeyguardViewConfigurator;
     @Mock protected KeyguardRootView mKeyguardRootView;
     @Mock protected View mKeyguardRootViewChild;
@@ -604,6 +604,7 @@
                 new NotificationsKeyguardInteractor(notifsKeyguardViewStateRepository);
         NotificationWakeUpCoordinator coordinator =
                 new NotificationWakeUpCoordinator(
+                        mKosmos.getTestScope().getBackgroundScope(),
                         mDumpManager,
                         mock(HeadsUpManager.class),
                         new StatusBarStateControllerImpl(
@@ -618,7 +619,8 @@
                         mDozeParameters,
                         mScreenOffAnimationController,
                         new NotificationWakeUpCoordinatorLogger(logcatLogBuffer()),
-                        notifsKeyguardInteractor);
+                        notifsKeyguardInteractor,
+                        mKosmos.getCommunalInteractor());
         mConfigurationController = new ConfigurationControllerImpl(mContext);
         PulseExpansionHandler expansionHandler = new PulseExpansionHandler(
                 mContext,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
index 02f2e16..cf7c6f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
@@ -20,6 +20,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SENSITIVE_FOR_TRACING;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -436,6 +437,10 @@
 
         verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
         assertThat((mLayoutParameters.getValue().flags & FLAG_SECURE) != 0).isTrue();
+        assertThat(
+                (mLayoutParameters.getValue().inputFeatures & INPUT_FEATURE_SENSITIVE_FOR_TRACING)
+                        != 0)
+                .isTrue();
     }
 
     @Test
@@ -444,6 +449,10 @@
 
         verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
         assertThat((mLayoutParameters.getValue().flags & FLAG_SECURE) == 0).isTrue();
+        assertThat(
+                (mLayoutParameters.getValue().inputFeatures & INPUT_FEATURE_SENSITIVE_FOR_TRACING)
+                        == 0)
+                .isTrue();
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
index 7a3b561..2c0a15d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -25,7 +25,7 @@
 import android.view.ViewGroup
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardSecurityContainerController
-import com.android.keyguard.LockIconViewController
+import com.android.keyguard.LegacyLockIconViewController
 import com.android.keyguard.dagger.KeyguardBouncerComponent
 import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
@@ -69,7 +69,6 @@
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
-import java.util.Optional
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.emptyFlow
@@ -87,6 +86,8 @@
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
+import kotlin.test.assertEquals
+import java.util.Optional
 import org.mockito.Mockito.`when` as whenever
 
 @OptIn(ExperimentalCoroutinesApi::class)
@@ -115,7 +116,7 @@
     @Mock private lateinit var quickSettingsController: QuickSettingsControllerImpl
     @Mock
     private lateinit var lockscreenShadeTransitionController: LockscreenShadeTransitionController
-    @Mock private lateinit var lockIconViewController: LockIconViewController
+    @Mock private lateinit var lockIconViewController: LegacyLockIconViewController
     @Mock private lateinit var phoneStatusBarViewController: PhoneStatusBarViewController
     @Mock private lateinit var pulsingGestureListener: PulsingGestureListener
     @Mock
@@ -138,6 +139,7 @@
     private val notificationLaunchAnimationInteractor =
         NotificationLaunchAnimationInteractor(notificationLaunchAnimationRepository)
 
+    private lateinit var falsingCollector: FalsingCollectorFake
     private lateinit var fakeClock: FakeSystemClock
     private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
     private lateinit var interactionEventHandler: InteractionEventHandler
@@ -170,11 +172,12 @@
         mSetFlagsRule.enableFlags(Flags.FLAG_REVAMPED_BOUNCER_MESSAGES)
 
         testScope = TestScope()
+        falsingCollector = FalsingCollectorFake()
         fakeClock = FakeSystemClock()
         underTest =
             NotificationShadeWindowViewController(
                 lockscreenShadeTransitionController,
-                FalsingCollectorFake(),
+                falsingCollector,
                 sysuiStatusBarStateController,
                 dockManager,
                 notificationShadeDepthController,
@@ -566,6 +569,13 @@
         verify(sysUIKeyEventHandler).interceptMediaKey(keyEvent)
     }
 
+    @Test
+    fun forwardsCollectKeyEvent() {
+        val keyEvent = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A)
+        interactionEventHandler.collectKeyEvent(keyEvent)
+        assertEquals(keyEvent, falsingCollector.lastKeyEvent)
+    }
+
     companion object {
         private val DOWN_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
         private val MOVE_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
index 0f54e07..98a815c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
@@ -22,7 +22,7 @@
 import android.widget.FrameLayout
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardSecurityContainerController
-import com.android.keyguard.LockIconViewController
+import com.android.keyguard.LegacyLockIconViewController
 import com.android.keyguard.dagger.KeyguardBouncerComponent
 import com.android.systemui.Flags as AConfigFlags
 import com.android.systemui.SysuiTestCase
@@ -103,7 +103,7 @@
     @Mock private lateinit var statusBarWindowStateController: StatusBarWindowStateController
     @Mock
     private lateinit var lockscreenShadeTransitionController: LockscreenShadeTransitionController
-    @Mock private lateinit var lockIconViewController: LockIconViewController
+    @Mock private lateinit var lockIconViewController: LegacyLockIconViewController
     @Mock private lateinit var keyguardUnlockAnimationController: KeyguardUnlockAnimationController
     @Mock private lateinit var ambientState: AmbientState
     @Mock private lateinit var shadeLogger: ShadeLogger
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginInstanceTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginInstanceTest.java
index 722387c..02954b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginInstanceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginInstanceTest.java
@@ -28,7 +28,7 @@
 import android.content.pm.ApplicationInfo;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
-import androidx.test.filters.FlakyTest;
+
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.systemui.SysuiTestCase;
@@ -46,11 +46,10 @@
 import java.util.Collections;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Supplier;
 
-@FlakyTest(bugId = 327655994) // Also b/324682425
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class PluginInstanceTest extends SysuiTestCase {
@@ -177,7 +176,7 @@
     }
 
     @Test
-    public void testLoadUnloadSimultaneous_HoldsUnload() throws Exception {
+    public void testLoadUnloadSimultaneous_HoldsUnload() throws Throwable {
         final Semaphore loadLock = new Semaphore(1);
         final Semaphore unloadLock = new Semaphore(1);
 
@@ -190,16 +189,16 @@
             Thread.yield();
             boolean isLocked = getLock(unloadLock, 1000);
 
-            // Ensure the bg thread failed to do delete the plugin
+            // Ensure the bg thread failed to delete the plugin
             assertNotNull(mPluginInstance.getPlugin());
             // We expect that bgThread deadlocked holding the semaphore
             assertFalse(isLocked);
         };
 
-        AtomicBoolean isBgThreadFailed = new AtomicBoolean(false);
+        AtomicReference<Throwable> bgFailure = new AtomicReference<Throwable>(null);
         Thread bgThread = new Thread(() -> {
             assertTrue(getLock(unloadLock, 10));
-            assertTrue(getLock(loadLock, 4000)); // Wait for the foreground thread
+            assertTrue(getLock(loadLock, 10000)); // Wait for the foreground thread
             assertNotNull(mPluginInstance.getPlugin());
             // Attempt to delete the plugin, this should block until the load completes
             mPluginInstance.unloadPlugin();
@@ -210,8 +209,9 @@
 
         // This protects the test suite from crashing due to the uncaught exception.
         bgThread.setUncaughtExceptionHandler((Thread t, Throwable ex) -> {
-            Log.e("testLoadUnloadSimultaneous_HoldsUnload", "Exception from BG Thread", ex);
-            isBgThreadFailed.set(true);
+            Log.e("PluginInstanceTest#testLoadUnloadSimultaneous_HoldsUnload",
+                    "Exception from BG Thread", ex);
+            bgFailure.set(ex);
         });
 
         loadLock.acquire();
@@ -222,7 +222,13 @@
         mPluginInstance.loadPlugin();
 
         bgThread.join(5000);
-        assertFalse(isBgThreadFailed.get());
+
+        // Rethrow final background exception on test thread
+        Throwable bgEx = bgFailure.get();
+        if (bgEx != null) {
+            throw bgEx;
+        }
+
         assertNull(mPluginInstance.getPlugin());
     }
 
@@ -230,6 +236,8 @@
         try {
             return lock.tryAcquire(millis, TimeUnit.MILLISECONDS);
         } catch (InterruptedException ex) {
+            Log.e("PluginInstanceTest#getLock",
+                    "Interrupted Exception getting lock", ex);
             fail();
             return false;
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt
new file mode 100644
index 0000000..9c59f9b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar
+
+import android.telephony.ServiceState
+import android.telephony.SubscriptionInfo
+import android.telephony.TelephonyManager
+import android.telephony.telephonyManager
+import androidx.test.filters.SmallTest
+import com.android.keyguard.keyguardUpdateMonitor
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.plugins.DarkIconDispatcher
+import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
+import com.android.systemui.statusbar.pipeline.mobile.util.FakeSubscriptionManagerProxy
+import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
+import com.android.systemui.tuner.TunerService
+import com.android.systemui.util.CarrierConfigTracker
+import com.android.systemui.util.kotlin.JavaAdapter
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.google.common.truth.Truth.assertThat
+import junit.framework.Assert.assertTrue
+import kotlin.test.Test
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+class OperatorNameViewControllerTest : SysuiTestCase() {
+    private lateinit var underTest: OperatorNameViewController
+    private lateinit var airplaneModeInteractor: AirplaneModeInteractor
+
+    private val kosmos = Kosmos()
+    private val testScope = TestScope()
+
+    private val view = OperatorNameView(mContext)
+    private val javaAdapter = JavaAdapter(testScope.backgroundScope)
+
+    @Mock private lateinit var darkIconDispatcher: DarkIconDispatcher
+    @Mock private lateinit var tunerService: TunerService
+    private var telephonyManager = kosmos.telephonyManager
+    private val keyguardUpdateMonitor = kosmos.keyguardUpdateMonitor
+    @Mock private lateinit var carrierConfigTracker: CarrierConfigTracker
+    private val subscriptionManagerProxy = FakeSubscriptionManagerProxy()
+
+    private val airplaneModeRepository = FakeAirplaneModeRepository()
+    private val connectivityRepository = FakeConnectivityRepository()
+    private val mobileConnectionsRepository = FakeMobileConnectionsRepository()
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+
+        airplaneModeInteractor =
+            AirplaneModeInteractor(
+                airplaneModeRepository,
+                connectivityRepository,
+                mobileConnectionsRepository,
+            )
+
+        underTest =
+            OperatorNameViewController.Factory(
+                    darkIconDispatcher,
+                    tunerService,
+                    telephonyManager,
+                    keyguardUpdateMonitor,
+                    carrierConfigTracker,
+                    airplaneModeInteractor,
+                    subscriptionManagerProxy,
+                    javaAdapter,
+                )
+                .create(view)
+    }
+
+    @Test
+    fun updateFromSubInfo_showsCarrieName() =
+        testScope.runTest {
+            whenever(telephonyManager.isDataCapable).thenReturn(true)
+
+            val mockSubInfo =
+                mock<SubscriptionInfo>().also {
+                    whenever(it.subscriptionId).thenReturn(1)
+                    whenever(it.carrierName).thenReturn("test_carrier")
+                }
+            whenever(keyguardUpdateMonitor.getSubscriptionInfoForSubId(any()))
+                .thenReturn(mockSubInfo)
+            whenever(keyguardUpdateMonitor.getSimState(any()))
+                .thenReturn(TelephonyManager.SIM_STATE_READY)
+            whenever(keyguardUpdateMonitor.getServiceState(any()))
+                .thenReturn(ServiceState().also { it.state = ServiceState.STATE_IN_SERVICE })
+            subscriptionManagerProxy.defaultDataSubId = 1
+            airplaneModeRepository.setIsAirplaneMode(false)
+
+            underTest.onViewAttached()
+            runCurrent()
+
+            assertThat(view.text).isEqualTo("test_carrier")
+        }
+
+    @Test
+    fun notDataCapable_doesNotShowOperatorName() =
+        testScope.runTest {
+            whenever(telephonyManager.isDataCapable).thenReturn(false)
+
+            val mockSubInfo =
+                mock<SubscriptionInfo>().also {
+                    whenever(it.subscriptionId).thenReturn(1)
+                    whenever(it.carrierName).thenReturn("test_carrier")
+                }
+            whenever(keyguardUpdateMonitor.getSubscriptionInfoForSubId(any()))
+                .thenReturn(mockSubInfo)
+            whenever(keyguardUpdateMonitor.getSimState(any()))
+                .thenReturn(TelephonyManager.SIM_STATE_READY)
+            whenever(keyguardUpdateMonitor.getServiceState(any()))
+                .thenReturn(ServiceState().also { it.state = ServiceState.STATE_IN_SERVICE })
+            subscriptionManagerProxy.defaultDataSubId = 1
+            airplaneModeRepository.setIsAirplaneMode(false)
+
+            underTest.onViewAttached()
+            runCurrent()
+
+            assertTrue(view.text.isNullOrEmpty())
+        }
+
+    @Test
+    fun airplaneMode_doesNotShowOperatorName() =
+        testScope.runTest {
+            whenever(telephonyManager.isDataCapable).thenReturn(false)
+            val mockSubInfo =
+                mock<SubscriptionInfo>().also {
+                    whenever(it.subscriptionId).thenReturn(1)
+                    whenever(it.carrierName).thenReturn("test_carrier")
+                }
+            whenever(keyguardUpdateMonitor.getSubscriptionInfoForSubId(any()))
+                .thenReturn(mockSubInfo)
+            whenever(keyguardUpdateMonitor.getSimState(any()))
+                .thenReturn(TelephonyManager.SIM_STATE_READY)
+            whenever(keyguardUpdateMonitor.getServiceState(any()))
+                .thenReturn(ServiceState().also { it.state = ServiceState.STATE_IN_SERVICE })
+            subscriptionManagerProxy.defaultDataSubId = 1
+            airplaneModeRepository.setIsAirplaneMode(true)
+
+            underTest.onViewAttached()
+            runCurrent()
+
+            assertTrue(view.text.isNullOrEmpty())
+        }
+
+    @Test
+    fun notInService_doesNotShowOperatorName() =
+        testScope.runTest {
+            // Data capable
+            whenever(telephonyManager.isDataCapable).thenReturn(true)
+
+            // Valid subscription
+            val mockSubInfo =
+                mock<SubscriptionInfo>().also {
+                    whenever(it.subscriptionId).thenReturn(1)
+                    whenever(it.carrierName).thenReturn("test_carrier")
+                }
+            whenever(keyguardUpdateMonitor.getSubscriptionInfoForSubId(any()))
+                .thenReturn(mockSubInfo)
+            whenever(keyguardUpdateMonitor.getSimState(any()))
+                .thenReturn(TelephonyManager.SIM_STATE_READY)
+
+            // Not in service
+            whenever(keyguardUpdateMonitor.getServiceState(any()))
+                .thenReturn(ServiceState().also { it.state = ServiceState.STATE_OUT_OF_SERVICE })
+            // Subscription is default for data
+            subscriptionManagerProxy.defaultDataSubId = 1
+            // Not airplane mode
+            airplaneModeRepository.setIsAirplaneMode(false)
+
+            underTest.onViewAttached()
+            runCurrent()
+
+            assertTrue(view.text.isNullOrEmpty())
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
index e54b532..de61086 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
 import com.android.systemui.common.ui.domain.interactor.ConfigurationInteractor
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository
 import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
 import com.android.systemui.flags.EnableSceneContainer
@@ -42,6 +41,7 @@
 import com.android.systemui.keyguard.data.repository.FakeCommandQueue
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.domain.interactor.FromLockscreenTransitionInteractor
 import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
@@ -50,6 +50,7 @@
 import com.android.systemui.keyguard.domain.interactor.fromPrimaryBouncerTransitionInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardClockInteractor
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.power.data.repository.FakePowerRepository
@@ -309,17 +310,20 @@
             underTest.addCallback(listener)
 
             val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene)
+            val deviceUnlockStatus by
+                collectLastValue(kosmos.deviceUnlockedInteractor.deviceUnlockStatus)
+
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.Password
             )
-            kosmos.fakeDeviceEntryRepository.setUnlocked(false)
             runCurrent()
+            assertThat(deviceUnlockStatus!!.isUnlocked).isFalse()
+
             kosmos.sceneInteractor.changeScene(
                 toScene = Scenes.Lockscreen,
                 loggingReason = "reason"
             )
             runCurrent()
-            assertThat(kosmos.deviceUnlockedInteractor.isDeviceUnlocked.value).isFalse()
             assertThat(currentScene).isEqualTo(Scenes.Lockscreen)
 
             // Call start to begin hydrating based on the scene framework:
@@ -371,14 +375,20 @@
             underTest.addCallback(listener)
 
             val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene)
+            val deviceUnlockStatus by
+                collectLastValue(kosmos.deviceUnlockedInteractor.deviceUnlockStatus)
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(
                 AuthenticationMethodModel.Password
             )
-            kosmos.fakeDeviceEntryRepository.setUnlocked(true)
+            kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus(
+                SuccessFingerprintAuthenticationStatus(0, true)
+            )
             runCurrent()
+
+            assertThat(deviceUnlockStatus!!.isUnlocked).isTrue()
+
             kosmos.sceneInteractor.changeScene(toScene = Scenes.Gone, loggingReason = "reason")
             runCurrent()
-            assertThat(kosmos.deviceUnlockedInteractor.isDeviceUnlocked.value).isTrue()
             assertThat(currentScene).isEqualTo(Scenes.Gone)
 
             // Call start to begin hydrating based on the scene framework:
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
index 82093ad..67b540c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinatorTest.kt
@@ -19,10 +19,15 @@
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
+import com.android.compose.animation.scene.ObservableTransitionState
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.AnimatorTestRule
+import com.android.systemui.communal.data.repository.communalRepository
+import com.android.systemui.communal.domain.interactor.communalInteractor
+import com.android.systemui.communal.shared.model.CommunalScenes
 import com.android.systemui.dump.DumpManager
-import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.log.logcatLogBuffer
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.shade.ShadeViewController.Companion.WAKEUP_ANIMATION_DELAY_MS
@@ -34,11 +39,16 @@
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController
 import com.android.systemui.statusbar.policy.HeadsUpManager
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -49,6 +59,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.verifyNoMoreInteractions
 
+@OptIn(ExperimentalCoroutinesApi::class)
 @RunWith(AndroidTestingRunner::class)
 @SmallTest
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
@@ -56,7 +67,8 @@
 
     @get:Rule val animatorTestRule = AnimatorTestRule(this)
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
+    private val testScope = kosmos.testScope
 
     private val dumpManager: DumpManager = mock()
     private val headsUpManager: HeadsUpManager = mock()
@@ -97,6 +109,7 @@
         whenever(statusBarStateController.state).then { statusBarState }
         notificationWakeUpCoordinator =
             NotificationWakeUpCoordinator(
+                kosmos.applicationCoroutineScope,
                 dumpManager,
                 headsUpManager,
                 statusBarStateController,
@@ -105,6 +118,7 @@
                 screenOffAnimationController,
                 logger,
                 kosmos.notificationsKeyguardInteractor,
+                kosmos.communalInteractor,
             )
         statusBarStateCallback = withArgCaptor {
             verify(statusBarStateController).addCallback(capture())
@@ -161,6 +175,39 @@
     }
 
     @Test
+    fun setDozeToZeroWhenCommunalShowingWillFullyHideNotifications() =
+        testScope.runTest {
+            val transitionState =
+                MutableStateFlow<ObservableTransitionState>(
+                    ObservableTransitionState.Idle(CommunalScenes.Communal)
+                )
+            kosmos.communalRepository.setTransitionState(transitionState)
+            runCurrent()
+            setDozeAmount(0f)
+            verifyStackScrollerDozeAndHideAmount(dozeAmount = 1f, hideAmount = 1f)
+            assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isTrue()
+        }
+
+    @Test
+    fun closingCommunalWillShowNotifications() =
+        testScope.runTest {
+            val transitionState =
+                MutableStateFlow<ObservableTransitionState>(
+                    ObservableTransitionState.Idle(CommunalScenes.Communal)
+                )
+            kosmos.communalRepository.setTransitionState(transitionState)
+            runCurrent()
+            setDozeAmount(0f)
+            verifyStackScrollerDozeAndHideAmount(dozeAmount = 1f, hideAmount = 1f)
+            assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isTrue()
+
+            transitionState.value = ObservableTransitionState.Idle(CommunalScenes.Blank)
+            runCurrent()
+            verifyStackScrollerDozeAndHideAmount(dozeAmount = 0f, hideAmount = 0f)
+            assertThat(notificationWakeUpCoordinator.notificationsFullyHidden).isFalse()
+        }
+
+    @Test
     fun switchingToShadeWithBypassEnabledWillShowNotifications() {
         setDozeToZeroWithBypassWillFullyHideNotifications()
         clearInvocations(stackScrollerController)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt
new file mode 100644
index 0000000..ab55a7d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/SectionStyleProviderTest.kt
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.statusbar.notification.collection
+
+import android.app.Flags
+import android.os.UserHandle
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
+import android.service.notification.StatusBarNotification
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
+import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
+import com.android.systemui.statusbar.notification.stack.BUCKET_FOREGROUND_SERVICE
+import com.android.systemui.statusbar.notification.stack.BUCKET_PEOPLE
+import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
+import com.android.systemui.statusbar.notification.stack.BUCKET_UNKNOWN
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
+import com.google.common.collect.ImmutableList
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class SectionStyleProviderTest : SysuiTestCase() {
+
+    @Rule @JvmField public val setFlagsRule = SetFlagsRule()
+
+    @Mock private lateinit var highPriorityProvider: HighPriorityProvider
+
+    @Mock private lateinit var peopleMixedSectioner : NotifSectioner
+    @Mock private lateinit var allSilentSectioner : NotifSectioner
+    @Mock private lateinit var allAlertingSectioner : NotifSectioner
+
+    private lateinit var sectionStyleProvider: SectionStyleProvider
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        sectionStyleProvider = SectionStyleProvider(highPriorityProvider)
+
+        whenever(peopleMixedSectioner.bucket).thenReturn(BUCKET_PEOPLE);
+        whenever(allSilentSectioner.bucket).thenReturn(BUCKET_SILENT);
+        whenever(allAlertingSectioner.bucket).thenReturn(BUCKET_ALERTING);
+
+        sectionStyleProvider.setSilentSections(ImmutableList.of(allSilentSectioner))
+    }
+
+    @Test
+    fun testIsSilent_silentSection() {
+        assertThat(sectionStyleProvider.isSilent(fakeNotification(allSilentSectioner))).isTrue()
+    }
+
+    @Test
+    fun testIsSilent_alertingSection() {
+        val listEntry = fakeNotification(allAlertingSectioner)
+        // this line should not matter for any non-people sections
+        whenever(highPriorityProvider.isHighPriorityConversation(listEntry)).thenReturn(true)
+
+        assertThat(sectionStyleProvider.isSilent(fakeNotification(allAlertingSectioner))).isFalse()
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_SORT_SECTION_BY_TIME)
+    fun testIsSilent_silentPeople() {
+        val listEntry = fakeNotification(peopleMixedSectioner)
+        whenever(highPriorityProvider.isHighPriorityConversation(listEntry)).thenReturn(false)
+        assertThat(sectionStyleProvider.isSilent(listEntry)).isTrue()
+    }
+
+    @Test
+    fun testIsSilent_alertingPeople() {
+        val listEntry = fakeNotification(peopleMixedSectioner)
+        whenever(highPriorityProvider.isHighPriorityConversation(listEntry)).thenReturn(true)
+
+        assertThat(sectionStyleProvider.isSilent(listEntry)).isFalse()
+    }
+
+    private fun fakeNotification(inputSectioner: NotifSectioner): ListEntry {
+        val mockUserHandle =
+                mock<UserHandle>().apply { whenever(identifier).thenReturn(0) }
+        val mockSbn: StatusBarNotification =
+                mock<StatusBarNotification>().apply { whenever(user).thenReturn(mockUserHandle) }
+        val mockRow: ExpandableNotificationRow = mock<ExpandableNotificationRow>()
+        val mockEntry = mock<NotificationEntry>().apply {
+            whenever(sbn).thenReturn(mockSbn)
+            whenever(row).thenReturn(mockRow)
+        }
+        whenever(mockEntry.rowExists()).thenReturn(true)
+        return object : ListEntry("key", 0) {
+            override fun getRepresentativeEntry(): NotificationEntry = mockEntry
+            override fun getSection(): NotifSection? = NotifSection(inputSectioner, 1)
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
index 36f643a..c5d7e1f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
@@ -16,10 +16,14 @@
 
 package com.android.systemui.statusbar.notification.collection.coordinator
 
+import android.app.Flags
 import android.app.NotificationChannel
 import android.app.NotificationManager.IMPORTANCE_DEFAULT
 import android.app.NotificationManager.IMPORTANCE_HIGH
 import android.app.NotificationManager.IMPORTANCE_LOW
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
@@ -29,6 +33,7 @@
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.collection.SortBySectionTimeFlag
 import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifComparator
@@ -48,12 +53,13 @@
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.Before
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
 
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
@@ -77,6 +83,8 @@
 
     private lateinit var coordinator: ConversationCoordinator
 
+    @Rule @JvmField public val setFlagsRule = SetFlagsRule()
+
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
@@ -99,7 +107,8 @@
 
         peopleAlertingSectioner = coordinator.peopleAlertingSectioner
         peopleSilentSectioner = coordinator.peopleSilentSectioner
-        peopleComparator = peopleAlertingSectioner.comparator!!
+        if (!SortBySectionTimeFlag.isEnabled)
+            peopleComparator = peopleAlertingSectioner.comparator!!
 
         entry = NotificationEntryBuilder().setChannel(channel).build()
 
@@ -150,6 +159,20 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_SORT_SECTION_BY_TIME)
+    fun testInAlertingPeopleSectionWhenTheImportanceIsLowerThanDefault() {
+        // GIVEN
+        val silentEntry =
+                NotificationEntryBuilder().setChannel(channel).setImportance(IMPORTANCE_LOW).build()
+        whenever(peopleNotificationIdentifier.getPeopleNotificationType(silentEntry))
+                .thenReturn(TYPE_PERSON)
+
+        // THEN put silent people notifications in alerting section
+        assertThat(peopleAlertingSectioner.isInSection(silentEntry)).isTrue()
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_SORT_SECTION_BY_TIME)
     fun testInSilentPeopleSectionWhenTheImportanceIsLowerThanDefault() {
         // GIVEN
         val silentEntry =
@@ -178,7 +201,8 @@
             .thenReturn(TYPE_NON_PERSON)
 
         // THEN - only put people notification either silent or alerting
-        assertThat(peopleSilentSectioner.isInSection(entry)).isFalse()
+        if (!SortBySectionTimeFlag.isEnabled)
+            assertThat(peopleSilentSectioner.isInSection(entry)).isFalse()
         assertThat(peopleAlertingSectioner.isInSection(importantEntry)).isFalse()
     }
 
@@ -207,6 +231,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_SORT_SECTION_BY_TIME)
     fun testComparatorPutsImportantPeopleFirst() {
         whenever(peopleNotificationIdentifier.getPeopleNotificationType(entryA))
             .thenReturn(TYPE_IMPORTANT_PERSON)
@@ -218,6 +243,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_SORT_SECTION_BY_TIME)
     fun testComparatorEquatesPeopleWithSameType() {
         whenever(peopleNotificationIdentifier.getPeopleNotificationType(entryA))
             .thenReturn(TYPE_PERSON)
@@ -227,4 +253,10 @@
         // only put people notifications in this section
         assertThat(peopleComparator.compare(entryA, entryB)).isEqualTo(0)
     }
+
+    @Test
+    @EnableFlags(Flags.FLAG_SORT_SECTION_BY_TIME)
+    fun testNoSecondarySortForConversations() {
+        assertThat(peopleAlertingSectioner.comparator).isNull()
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
index 118d27a..cceaaea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
@@ -64,6 +64,7 @@
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
 import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
 import com.android.systemui.statusbar.notification.collection.render.NotifViewBarn;
@@ -112,7 +113,9 @@
     @Mock private Handler mHandler;
     @Mock private SecureSettings mSecureSettings;
     @Spy private FakeNotifInflater mNotifInflater = new FakeNotifInflater();
-    private final SectionStyleProvider mSectionStyleProvider = new SectionStyleProvider();
+    @Mock
+    HighPriorityProvider mHighPriorityProvider;
+    private SectionStyleProvider mSectionStyleProvider;
     @Mock private UserTracker mUserTracker;
     @Mock private GroupMembershipManager mGroupMembershipManager;
 
@@ -126,6 +129,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        mSectionStyleProvider = new SectionStyleProvider(mHighPriorityProvider);
         mAdjustmentProvider = new NotifUiAdjustmentProvider(
                 mHandler,
                 mSecureSettings,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt
index b4dadaf..ea4f692 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt
@@ -20,6 +20,8 @@
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper.RunWithLooper
 import androidx.test.filters.SmallTest
+import com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING
+import com.android.systemui.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -36,6 +38,7 @@
 import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
 import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
 import com.android.systemui.statusbar.phone.NotificationIconAreaController
+import com.android.systemui.statusbar.policy.SensitiveNotificationProtectionController
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.withArgCaptor
 import org.junit.Before
@@ -43,6 +46,7 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyZeroInteractions
 import org.mockito.MockitoAnnotations.initMocks
 import org.mockito.Mockito.`when` as whenever
 
@@ -60,12 +64,18 @@
     @Mock private lateinit var notificationIconAreaController: NotificationIconAreaController
     @Mock private lateinit var renderListInteractor: RenderNotificationListInteractor
     @Mock private lateinit var activeNotificationsInteractor: ActiveNotificationsInteractor
+    @Mock private lateinit var sensitiveNotificationProtectionController:
+        SensitiveNotificationProtectionController
     @Mock private lateinit var stackController: NotifStackController
     @Mock private lateinit var section: NotifSection
 
     @Before
     fun setUp() {
         initMocks(this)
+
+        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive)
+            .thenReturn(false)
+
         entry = NotificationEntryBuilder().setSection(section).build()
         coordinator =
             StackCoordinator(
@@ -73,6 +83,7 @@
                 notificationIconAreaController,
                 renderListInteractor,
                 activeNotificationsInteractor,
+                sensitiveNotificationProtectionController,
             )
         coordinator.attach(pipeline)
         afterRenderListListener = withArgCaptor {
@@ -107,6 +118,18 @@
         whenever(section.bucket).thenReturn(BUCKET_ALERTING)
         afterRenderListListener.onAfterRenderList(listOf(entry), stackController)
         verify(stackController).setNotifStats(NotifStats(1, false, true, false, false))
+        verifyZeroInteractions(activeNotificationsInteractor)
+    }
+
+    @Test
+    @DisableFlags(FooterViewRefactor.FLAG_NAME)
+    @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING, FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX)
+    fun testSetNotificationStats_isSensitiveStateActive_nonClearableAlerting() {
+        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+        whenever(section.bucket).thenReturn(BUCKET_ALERTING)
+        afterRenderListListener.onAfterRenderList(listOf(entry), stackController)
+        verify(stackController).setNotifStats(NotifStats(1, true, false, false, false))
+        verifyZeroInteractions(activeNotificationsInteractor)
     }
 
     @Test
@@ -115,5 +138,67 @@
         whenever(section.bucket).thenReturn(BUCKET_SILENT)
         afterRenderListListener.onAfterRenderList(listOf(entry), stackController)
         verify(stackController).setNotifStats(NotifStats(1, false, false, false, true))
+        verifyZeroInteractions(activeNotificationsInteractor)
+    }
+
+    @Test
+    @DisableFlags(FooterViewRefactor.FLAG_NAME)
+    @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING, FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX)
+    fun testSetNotificationStats_isSensitiveStateActive_nonClearableSilent() {
+        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+        whenever(section.bucket).thenReturn(BUCKET_SILENT)
+        afterRenderListListener.onAfterRenderList(listOf(entry), stackController)
+        verify(stackController).setNotifStats(NotifStats(1, false, false, true, false))
+        verifyZeroInteractions(activeNotificationsInteractor)
+    }
+
+    @Test
+    @EnableFlags(FooterViewRefactor.FLAG_NAME)
+    fun testSetNotificationStats_footerFlagOn_clearableAlerting() {
+        whenever(section.bucket).thenReturn(BUCKET_ALERTING)
+        afterRenderListListener.onAfterRenderList(listOf(entry), stackController)
+        verify(activeNotificationsInteractor)
+            .setNotifStats(NotifStats(1, false, true, false, false))
+        verifyZeroInteractions(stackController)
+    }
+
+    @Test
+    @EnableFlags(
+        FooterViewRefactor.FLAG_NAME,
+        FLAG_SCREENSHARE_NOTIFICATION_HIDING,
+        FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX
+    )
+    fun testSetNotificationStats_footerFlagOn_isSensitiveStateActive_nonClearableAlerting() {
+        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+        whenever(section.bucket).thenReturn(BUCKET_ALERTING)
+        afterRenderListListener.onAfterRenderList(listOf(entry), stackController)
+        verify(activeNotificationsInteractor)
+            .setNotifStats(NotifStats(1, true, false, false, false))
+        verifyZeroInteractions(stackController)
+    }
+
+    @Test
+    @EnableFlags(FooterViewRefactor.FLAG_NAME)
+    fun testSetNotificationStats_footerFlagOn_clearableSilent() {
+        whenever(section.bucket).thenReturn(BUCKET_SILENT)
+        afterRenderListListener.onAfterRenderList(listOf(entry), stackController)
+        verify(activeNotificationsInteractor)
+            .setNotifStats(NotifStats(1, false, false, false, true))
+        verifyZeroInteractions(stackController)
+    }
+
+    @Test
+    @EnableFlags(
+        FooterViewRefactor.FLAG_NAME,
+        FLAG_SCREENSHARE_NOTIFICATION_HIDING,
+        FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX
+    )
+    fun testSetNotificationStats_footerFlagOn_isSensitiveStateActive_nonClearableSilent() {
+        whenever(sensitiveNotificationProtectionController.isSensitiveStateActive).thenReturn(true)
+        whenever(section.bucket).thenReturn(BUCKET_SILENT)
+        afterRenderListListener.onAfterRenderList(listOf(entry), stackController)
+        verify(activeNotificationsInteractor)
+            .setNotifStats(NotifStats(1, false, false, true, false))
+        verifyZeroInteractions(stackController)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
index ea5a6e7..6f0a19d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
@@ -29,15 +29,19 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import static kotlinx.coroutines.flow.StateFlowKt.MutableStateFlow;
+
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.keyguard.TestScopeProvider;
+import com.android.compose.animation.scene.ObservableTransitionState;
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.communal.shared.model.CommunalScenes;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.kosmos.KosmosJavaAdapter;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.shade.data.repository.FakeShadeRepository;
 import com.android.systemui.shade.data.repository.ShadeAnimationRepository;
@@ -67,6 +71,7 @@
 import org.mockito.MockitoAnnotations;
 import org.mockito.verification.VerificationMode;
 
+import kotlinx.coroutines.flow.MutableStateFlow;
 import kotlinx.coroutines.test.TestScope;
 
 @SmallTest
@@ -89,9 +94,10 @@
     @Captor private ArgumentCaptor<StatusBarStateController.StateListener> mSBStateListenerCaptor;
     @Captor private ArgumentCaptor<NotifStabilityManager> mNotifStabilityManagerCaptor;
 
+    private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
     private FakeSystemClock mFakeSystemClock = new FakeSystemClock();
     private FakeExecutor mFakeExecutor = new FakeExecutor(mFakeSystemClock);
-    private final TestScope mTestScope = TestScopeProvider.getTestScope();
+    private final TestScope mTestScope = mKosmos.getTestScope();
     private final JavaAdapter mJavaAdapter = new JavaAdapter(mTestScope.getBackgroundScope());
 
     private ShadeAnimationInteractor mShadeAnimationInteractor;
@@ -118,8 +124,10 @@
                 mStatusBarStateController,
                 mVisibilityLocationProvider,
                 mVisualStabilityProvider,
-                mWakefulnessLifecycle);
+                mWakefulnessLifecycle,
+                mKosmos.getCommunalInteractor());
         mCoordinator.attach(mNotifPipeline);
+        mTestScope.getTestScheduler().runCurrent();
 
         // capture arguments:
         verify(mWakefulnessLifecycle).addObserver(mWakefulnessObserverCaptor.capture());
@@ -496,6 +504,7 @@
         setFullyDozed(false);
         setSleepy(false);
         setPanelExpanded(true);
+        setCommunalShowing(false);
 
         assertFalse(mNotifStabilityManager.isEntryReorderingAllowed(mEntry));
         // The pipeline still has to report back that entry reordering was suppressed
@@ -509,6 +518,19 @@
     }
 
     @Test
+    public void testCommunalShowingWillNotSuppressReordering() {
+        // GIVEN panel is expanded and communal is showing
+        setPulsing(false);
+        setFullyDozed(false);
+        setSleepy(false);
+        setPanelExpanded(true);
+        setCommunalShowing(true);
+
+        // Reordering should be allowed
+        assertTrue(mNotifStabilityManager.isEntryReorderingAllowed(mEntry));
+    }
+
+    @Test
     public void testQueryingEntryReorderingButNotReportingReorderSuppressedDoesNotInvalidate() {
         // GIVEN visual stability is being maintained b/c panel is expanded
         setPulsing(false);
@@ -561,6 +583,16 @@
         mTestScope.getTestScheduler().runCurrent();
     }
 
+    private void setCommunalShowing(boolean isShowing) {
+        final MutableStateFlow<ObservableTransitionState> showingFlow =
+                MutableStateFlow(
+                        new ObservableTransitionState.Idle(
+                                isShowing ? CommunalScenes.Communal : CommunalScenes.Blank)
+                );
+        mKosmos.getCommunalRepository().setTransitionState(showingFlow);
+        mTestScope.getTestScheduler().runCurrent();
+    }
+
     private void setPulsing(boolean pulsing) {
         mStatusBarStateListener.onPulsingChanged(pulsing);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java
index cac4a8d..6bda4d4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/view/FooterViewTest.java
@@ -299,8 +299,6 @@
     @Test
     public void testSetFooterLabelVisible() {
         mView.setFooterLabelVisible(true);
-        assertThat(mView.findViewById(R.id.manage_text).getVisibility()).isEqualTo(View.GONE);
-        assertThat(mView.findSecondaryView().getVisibility()).isEqualTo(View.GONE);
         assertThat(mView.findViewById(R.id.unlock_prompt_footer).getVisibility())
                 .isEqualTo(View.VISIBLE);
     }
@@ -308,8 +306,6 @@
     @Test
     public void testSetFooterLabelInvisible() {
         mView.setFooterLabelVisible(false);
-        assertThat(mView.findViewById(R.id.manage_text).getVisibility()).isEqualTo(View.VISIBLE);
-        assertThat(mView.findSecondaryView().getVisibility()).isEqualTo(View.VISIBLE);
         assertThat(mView.findViewById(R.id.unlock_prompt_footer).getVisibility())
                 .isEqualTo(View.GONE);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt
index 620d972..158f38d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/footer/ui/viewmodel/FooterViewModelTest.kt
@@ -66,7 +66,7 @@
     val underTest = kosmos.footerViewModel
 
     @Test
-    fun testMessageVisible_whenFilteredNotifications() =
+    fun messageVisible_whenFilteredNotifications() =
         testScope.runTest {
             val visible by collectLastValue(underTest.message.isVisible)
 
@@ -76,7 +76,7 @@
         }
 
     @Test
-    fun testMessageVisible_whenNoFilteredNotifications() =
+    fun messageVisible_whenNoFilteredNotifications() =
         testScope.runTest {
             val visible by collectLastValue(underTest.message.isVisible)
 
@@ -86,7 +86,7 @@
         }
 
     @Test
-    fun testClearAllButtonVisible_whenHasClearableNotifs() =
+    fun clearAllButtonVisible_whenHasClearableNotifs() =
         testScope.runTest {
             val visible by collectLastValue(underTest.clearAllButton.isVisible)
 
@@ -104,7 +104,7 @@
         }
 
     @Test
-    fun testClearAllButtonVisible_whenHasNoClearableNotifs() =
+    fun clearAllButtonVisible_whenHasNoClearableNotifs() =
         testScope.runTest {
             val visible by collectLastValue(underTest.clearAllButton.isVisible)
 
@@ -122,7 +122,26 @@
         }
 
     @Test
-    fun testClearAllButtonAnimating_whenShadeExpandedAndTouchable() =
+    fun clearAllButtonVisible_whenMessageVisible() =
+        testScope.runTest {
+            val visible by collectLastValue(underTest.clearAllButton.isVisible)
+
+            activeNotificationListRepository.notifStats.value =
+                NotifStats(
+                    numActiveNotifs = 2,
+                    hasNonClearableAlertingNotifs = false,
+                    hasClearableAlertingNotifs = true,
+                    hasNonClearableSilentNotifs = false,
+                    hasClearableSilentNotifs = true,
+                )
+            activeNotificationListRepository.hasFilteredOutSeenNotifications.value = true
+            runCurrent()
+
+            assertThat(visible?.value).isFalse()
+        }
+
+    @Test
+    fun clearAllButtonAnimating_whenShadeExpandedAndTouchable() =
         testScope.runTest {
             val visible by collectLastValue(underTest.clearAllButton.isVisible)
             runCurrent()
@@ -156,7 +175,7 @@
         }
 
     @Test
-    fun testClearAllButtonAnimating_whenShadeNotExpanded() =
+    fun clearAllButtonAnimating_whenShadeNotExpanded() =
         testScope.runTest {
             val visible by collectLastValue(underTest.clearAllButton.isVisible)
             runCurrent()
@@ -190,7 +209,7 @@
         }
 
     @Test
-    fun testManageButton_whenHistoryDisabled() =
+    fun manageButton_whenHistoryDisabled() =
         testScope.runTest {
             val buttonLabel by collectLastValue(underTest.manageOrHistoryButton.labelId)
             runCurrent()
@@ -203,7 +222,7 @@
         }
 
     @Test
-    fun testHistoryButton_whenHistoryEnabled() =
+    fun historyButton_whenHistoryEnabled() =
         testScope.runTest {
             val buttonLabel by collectLastValue(underTest.manageOrHistoryButton.labelId)
             runCurrent()
@@ -214,4 +233,24 @@
             // THEN label is "History"
             assertThat(buttonLabel).isEqualTo(R.string.manage_notifications_history_text)
         }
+
+    @Test
+    fun manageButtonVisible_whenMessageVisible() =
+        testScope.runTest {
+            val visible by collectLastValue(underTest.manageOrHistoryButton.isVisible)
+
+            activeNotificationListRepository.hasFilteredOutSeenNotifications.value = true
+
+            assertThat(visible?.value).isFalse()
+        }
+
+    @Test
+    fun manageButtonVisible_whenMessageNotVisible() =
+        testScope.runTest {
+            val visible by collectLastValue(underTest.manageOrHistoryButton.isVisible)
+
+            activeNotificationListRepository.hasFilteredOutSeenNotifications.value = false
+
+            assertThat(visible?.value).isTrue()
+        }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index 10d2191..912ecb3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -37,7 +37,6 @@
 import static org.mockito.Mockito.when;
 
 import static kotlinx.coroutines.flow.FlowKt.emptyFlow;
-import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher;
 
 import android.metrics.LogMaker;
 import android.platform.test.annotations.DisableFlags;
@@ -69,7 +68,6 @@
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.power.domain.interactor.PowerInteractor;
-import com.android.systemui.scene.shared.flag.SceneContainerFlags;
 import com.android.systemui.scene.ui.view.WindowRootView;
 import com.android.systemui.shade.ShadeController;
 import com.android.systemui.statusbar.LockscreenShadeTransitionController;
@@ -89,7 +87,6 @@
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
 import com.android.systemui.statusbar.notification.data.repository.ActiveNotificationListRepository;
-import com.android.systemui.statusbar.notification.domain.interactor.ActiveNotificationsInteractor;
 import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor;
 import com.android.systemui.statusbar.notification.footer.shared.FooterViewRefactor;
 import com.android.systemui.statusbar.notification.init.NotificationsController;
@@ -97,10 +94,8 @@
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController.NotificationPanelEvent;
 import com.android.systemui.statusbar.notification.stack.NotificationSwipeHelper.NotificationCallback;
-import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor;
 import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationListViewBinder;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.ScrimController;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -155,7 +150,6 @@
     @Mock(answer = Answers.RETURNS_SELF)
     private NotificationSwipeHelper.Builder mNotificationSwipeHelperBuilder;
     @Mock private NotificationSwipeHelper mNotificationSwipeHelper;
-    @Mock private ScrimController mScrimController;
     @Mock private GroupExpansionManager mGroupExpansionManager;
     @Mock private SectionHeaderController mSilentHeaderController;
     @Mock private NotifPipeline mNotifPipeline;
@@ -165,9 +159,7 @@
     @Mock private NotificationRemoteInputManager mRemoteInputManager;
     @Mock private VisibilityLocationProviderDelegator mVisibilityLocationProviderDelegator;
     @Mock private ShadeController mShadeController;
-    @Mock private SceneContainerFlags mSceneContainerFlags;
     @Mock private Provider<WindowRootView> mWindowRootView;
-    @Mock private NotificationStackAppearanceInteractor mNotificationStackAppearanceInteractor;
     private final StackStateLogger mStackLogger = new StackStateLogger(logcatLogBuffer(),
             logcatLogBuffer());
     private final NotificationStackScrollLogger mLogger = new NotificationStackScrollLogger(
@@ -191,10 +183,6 @@
     private final ActiveNotificationListRepository mActiveNotificationsRepository =
             new ActiveNotificationListRepository();
 
-    private final ActiveNotificationsInteractor mActiveNotificationsInteractor =
-            new ActiveNotificationsInteractor(mActiveNotificationsRepository,
-                    StandardTestDispatcher(/* scheduler = */ null, /* name = */ null));
-
     private final SeenNotificationsInteractor mSeenNotificationsInteractor =
             new SeenNotificationsInteractor(mActiveNotificationsRepository);
 
@@ -1014,7 +1002,6 @@
                 new FalsingCollectorFake(),
                 new FalsingManagerFake(),
                 mNotificationSwipeHelperBuilder,
-                mScrimController,
                 mGroupExpansionManager,
                 mSilentHeaderController,
                 mNotifPipeline,
@@ -1023,13 +1010,10 @@
                 mUiEventLogger,
                 mRemoteInputManager,
                 mVisibilityLocationProviderDelegator,
-                mActiveNotificationsInteractor,
                 mSeenNotificationsInteractor,
                 mViewBinder,
                 mShadeController,
-                mSceneContainerFlags,
                 mWindowRootView,
-                mNotificationStackAppearanceInteractor,
                 mKosmos.getInteractionJankMonitor(),
                 mStackLogger,
                 mLogger,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
index c07f289..42bbe3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/domain/interactor/DeviceBasedSatelliteInteractorTest.kt
@@ -26,6 +26,8 @@
 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.satellite.data.prod.FakeDeviceBasedSatelliteRepository
 import com.android.systemui.statusbar.pipeline.satellite.shared.model.SatelliteConnectionState
+import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository
+import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
@@ -48,6 +50,9 @@
         )
 
     private val repo = FakeDeviceBasedSatelliteRepository()
+    private val deviceProvisionedRepository = FakeDeviceProvisioningRepository()
+    private val deviceProvisioningInteractor =
+        DeviceProvisioningInteractor(deviceProvisionedRepository)
 
     @Before
     fun setUp() {
@@ -55,6 +60,7 @@
             DeviceBasedSatelliteInteractor(
                 repo,
                 iconsInteractor,
+                deviceProvisioningInteractor,
                 testScope.backgroundScope,
             )
     }
@@ -96,6 +102,7 @@
                 DeviceBasedSatelliteInteractor(
                     repo,
                     iconsInteractor,
+                    deviceProvisioningInteractor,
                     testScope.backgroundScope,
                 )
 
@@ -142,6 +149,7 @@
                 DeviceBasedSatelliteInteractor(
                     repo,
                     iconsInteractor,
+                    deviceProvisioningInteractor,
                     testScope.backgroundScope,
                 )
 
@@ -196,6 +204,7 @@
                 DeviceBasedSatelliteInteractor(
                     repo,
                     iconsInteractor,
+                    deviceProvisioningInteractor,
                     testScope.backgroundScope,
                 )
 
@@ -327,6 +336,7 @@
                 DeviceBasedSatelliteInteractor(
                     repo,
                     iconsInteractor,
+                    deviceProvisioningInteractor,
                     testScope.backgroundScope,
                 )
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
index ec6642d..1d6cd37 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/satellite/ui/viewmodel/DeviceBasedSatelliteViewModelTest.kt
@@ -26,6 +26,8 @@
 import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.satellite.data.prod.FakeDeviceBasedSatelliteRepository
 import com.android.systemui.statusbar.pipeline.satellite.domain.interactor.DeviceBasedSatelliteInteractor
+import com.android.systemui.statusbar.policy.data.repository.FakeDeviceProvisioningRepository
+import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
@@ -45,6 +47,9 @@
 
     private val repo = FakeDeviceBasedSatelliteRepository()
     private val mobileIconsInteractor = FakeMobileIconsInteractor(FakeMobileMappingsProxy(), mock())
+    private val deviceProvisionedRepository = FakeDeviceProvisioningRepository()
+    private val deviceProvisioningInteractor =
+        DeviceProvisioningInteractor(deviceProvisionedRepository)
 
     private val testScope = TestScope()
 
@@ -57,6 +62,7 @@
             DeviceBasedSatelliteInteractor(
                 repo,
                 mobileIconsInteractor,
+                deviceProvisioningInteractor,
                 testScope.backgroundScope,
             )
 
@@ -214,4 +220,37 @@
             // THEN icon is null immediately
             assertThat(latest).isNull()
         }
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    fun icon_deviceIsProvisioned() =
+        testScope.runTest {
+            val latest by collectLastValue(underTest.icon)
+
+            // GIVEN satellite is allowed
+            repo.isSatelliteAllowedForCurrentLocation.value = true
+
+            // GIVEN all icons are OOS
+            val i1 = mobileIconsInteractor.getMobileConnectionInteractorForSubId(1)
+            i1.isInService.value = false
+            i1.isEmergencyOnly.value = false
+
+            // GIVEN apm is disabled
+            airplaneModeRepository.setIsAirplaneMode(false)
+
+            // GIVEN device is not provisioned
+            deviceProvisionedRepository.setDeviceProvisioned(false)
+
+            // THEN icon is null because the device is not provisioned
+            assertThat(latest).isNull()
+
+            // GIVEN device becomes provisioned
+            deviceProvisionedRepository.setDeviceProvisioned(true)
+
+            // Wait for delay to be completed
+            advanceTimeBy(10.seconds)
+
+            // THEN icon is null because the device is not provisioned
+            assertThat(latest).isInstanceOf(Icon::class.java)
+        }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt
index 867476f..4ace163 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SensitiveNotificationProtectionControllerTest.kt
@@ -28,7 +28,10 @@
 import android.content.pm.PackageManager
 import android.media.projection.MediaProjectionInfo
 import android.media.projection.MediaProjectionManager
+import android.os.Process
+import android.os.UserHandle
 import android.permission.flags.Flags.FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION
+import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
 import android.platform.test.annotations.RequiresFlagsDisabled
 import android.platform.test.annotations.RequiresFlagsEnabled
@@ -40,7 +43,8 @@
 import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
 import com.android.dx.mockito.inline.extended.ExtendedMockito.verify
 import com.android.internal.util.FrameworkStatsLog
-import com.android.server.notification.Flags
+import com.android.server.notification.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING
+import com.android.systemui.Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.log.logcatLogBuffer
 import com.android.systemui.statusbar.RankingBuilder
@@ -76,7 +80,7 @@
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 @RunWithLooper
-@EnableFlags(Flags.FLAG_SCREENSHARE_NOTIFICATION_HIDING)
+@EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING)
 class SensitiveNotificationProtectionControllerTest : SysuiTestCase() {
     @get:Rule val checkFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule()
 
@@ -85,7 +89,6 @@
     @Mock private lateinit var activityManager: IActivityManager
     @Mock private lateinit var mediaProjectionManager: MediaProjectionManager
     @Mock private lateinit var packageManager: PackageManager
-    @Mock private lateinit var mediaProjectionInfo: MediaProjectionInfo
     @Mock private lateinit var listener1: Runnable
     @Mock private lateinit var listener2: Runnable
     @Mock private lateinit var listener3: Runnable
@@ -95,6 +98,7 @@
     private lateinit var globalSettings: FakeGlobalSettings
     private lateinit var mediaProjectionCallback: MediaProjectionManager.Callback
     private lateinit var controller: SensitiveNotificationProtectionControllerImpl
+    private lateinit var mediaProjectionInfo: MediaProjectionInfo
 
     @Before
     fun setUp() {
@@ -109,14 +113,29 @@
         setShareFullScreen()
         whenever(activityManager.bugreportWhitelistedPackages)
             .thenReturn(listOf(BUGREPORT_PACKAGE_NAME))
-        whenever(packageManager.getPackageUid(TEST_PROJECTION_PACKAGE_NAME, 0))
+        whenever(
+                packageManager.getPackageUidAsUser(
+                    TEST_PROJECTION_PACKAGE_NAME,
+                    UserHandle.CURRENT.identifier
+                )
+            )
             .thenReturn(TEST_PROJECTION_PACKAGE_UID)
-        whenever(packageManager.getPackageUid(BUGREPORT_PACKAGE_NAME, 0))
+        whenever(
+                packageManager.getPackageUidAsUser(
+                    BUGREPORT_PACKAGE_NAME,
+                    UserHandle.CURRENT.identifier
+                )
+            )
             .thenReturn(BUGREPORT_PACKAGE_UID)
         // SystemUi context package name is exempt, but in test scenarios its
         // com.android.systemui.tests so use that instead of hardcoding. Setup packagemanager to
         // return the correct uid in this scenario
-        whenever(packageManager.getPackageUid(mContext.packageName, 0))
+        whenever(
+                packageManager.getPackageUidAsUser(
+                    mContext.packageName,
+                    UserHandle.CURRENT.identifier
+                )
+            )
             .thenReturn(mContext.applicationInfo.uid)
 
         whenever(packageManager.checkPermission(anyString(), anyString()))
@@ -271,7 +290,7 @@
     fun isSensitiveStateActive_projectionActive_sysuiExempt_false() {
         // SystemUi context package name is exempt, but in test scenarios its
         // com.android.systemui.tests so use that instead of hardcoding
-        whenever(mediaProjectionInfo.packageName).thenReturn(mContext.packageName)
+        setShareFullScreenViaSystemUi()
         mediaProjectionCallback.onStart(mediaProjectionInfo)
 
         assertFalse(controller.isSensitiveStateActive)
@@ -309,7 +328,7 @@
 
     @Test
     fun isSensitiveStateActive_projectionActive_bugReportHandlerExempt_false() {
-        whenever(mediaProjectionInfo.packageName).thenReturn(BUGREPORT_PACKAGE_NAME)
+        setShareFullScreenViaBugReportHandler()
         mediaProjectionCallback.onStart(mediaProjectionInfo)
 
         assertFalse(controller.isSensitiveStateActive)
@@ -368,13 +387,33 @@
     }
 
     @Test
+    @DisableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX)
+    fun shouldProtectNotification_projectionActive_isFromCoreApp_fixDisabled_true() {
+        mediaProjectionCallback.onStart(mediaProjectionInfo)
+
+        val notificationEntry = setupCoreAppNotificationEntry(TEST_PROJECTION_PACKAGE_NAME)
+
+        assertTrue(controller.shouldProtectNotification(notificationEntry))
+    }
+
+    @Test
+    @EnableFlags(FLAG_SCREENSHARE_NOTIFICATION_HIDING_BUG_FIX)
+    fun shouldProtectNotification_projectionActive_isFromCoreApp_false() {
+        mediaProjectionCallback.onStart(mediaProjectionInfo)
+
+        val notificationEntry = setupCoreAppNotificationEntry(TEST_PROJECTION_PACKAGE_NAME)
+
+        assertFalse(controller.shouldProtectNotification(notificationEntry))
+    }
+
+    @Test
     fun shouldProtectNotification_projectionActive_sysuiExempt_false() {
         // SystemUi context package name is exempt, but in test scenarios its
         // com.android.systemui.tests so use that instead of hardcoding
-        whenever(mediaProjectionInfo.packageName).thenReturn(mContext.packageName)
+        setShareFullScreenViaSystemUi()
         mediaProjectionCallback.onStart(mediaProjectionInfo)
 
-        val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME, false)
+        val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME)
 
         assertFalse(controller.shouldProtectNotification(notificationEntry))
     }
@@ -391,7 +430,7 @@
             .thenReturn(PackageManager.PERMISSION_GRANTED)
         mediaProjectionCallback.onStart(mediaProjectionInfo)
 
-        val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME, false)
+        val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME)
 
         assertTrue(controller.shouldProtectNotification(notificationEntry))
     }
@@ -408,17 +447,17 @@
             .thenReturn(PackageManager.PERMISSION_GRANTED)
         mediaProjectionCallback.onStart(mediaProjectionInfo)
 
-        val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME, false)
+        val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME)
 
         assertFalse(controller.shouldProtectNotification(notificationEntry))
     }
 
     @Test
     fun shouldProtectNotification_projectionActive_bugReportHandlerExempt_false() {
-        whenever(mediaProjectionInfo.packageName).thenReturn(BUGREPORT_PACKAGE_NAME)
+        setShareFullScreenViaBugReportHandler()
         mediaProjectionCallback.onStart(mediaProjectionInfo)
 
-        val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME, false)
+        val notificationEntry = setupNotificationEntry(TEST_PACKAGE_NAME)
 
         assertFalse(controller.shouldProtectNotification(notificationEntry))
     }
@@ -548,9 +587,7 @@
     fun logSensitiveContentProtectionSession_exemptViaSystemUi() {
         // SystemUi context package name is exempt, but in test scenarios its
         // com.android.systemui.tests so use that instead of hardcoding
-        val testPackageName = mContext.packageName
-        val testUid = mContext.applicationInfo.uid
-        whenever(mediaProjectionInfo.packageName).thenReturn(testPackageName)
+        setShareFullScreenViaSystemUi()
 
         mediaProjectionCallback.onStart(mediaProjectionInfo)
 
@@ -558,7 +595,7 @@
             FrameworkStatsLog.write(
                 eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION),
                 anyLong(),
-                eq(testUid),
+                eq(mContext.applicationInfo.uid),
                 eq(true),
                 eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__START),
                 eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI)
@@ -571,7 +608,7 @@
             FrameworkStatsLog.write(
                 eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION),
                 anyLong(),
-                eq(testUid),
+                eq(mContext.applicationInfo.uid),
                 eq(true),
                 eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__STATE__STOP),
                 eq(FrameworkStatsLog.SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION__SOURCE__SYS_UI)
@@ -582,8 +619,7 @@
     @Test
     fun logSensitiveContentProtectionSession_exemptViaBugReportHandler() {
         // Setup exempt via bugreport handler
-        whenever(mediaProjectionInfo.packageName).thenReturn(BUGREPORT_PACKAGE_NAME)
-
+        setShareFullScreenViaBugReportHandler()
         mediaProjectionCallback.onStart(mediaProjectionInfo)
 
         verify {
@@ -619,18 +655,32 @@
     }
 
     private fun setShareFullScreen() {
-        whenever(mediaProjectionInfo.packageName).thenReturn(TEST_PROJECTION_PACKAGE_NAME)
-        whenever(mediaProjectionInfo.launchCookie).thenReturn(null)
+        setShareScreen(TEST_PROJECTION_PACKAGE_NAME, true)
+    }
+
+    private fun setShareFullScreenViaBugReportHandler() {
+        setShareScreen(BUGREPORT_PACKAGE_NAME, true)
+    }
+
+    private fun setShareFullScreenViaSystemUi() {
+        // SystemUi context package name is exempt, but in test scenarios its
+        // com.android.systemui.tests so use that instead of hardcoding
+        setShareScreen(mContext.packageName, true)
     }
 
     private fun setShareSingleApp() {
-        whenever(mediaProjectionInfo.packageName).thenReturn(TEST_PROJECTION_PACKAGE_NAME)
-        whenever(mediaProjectionInfo.launchCookie).thenReturn(ActivityOptions.LaunchCookie())
+        setShareScreen(TEST_PROJECTION_PACKAGE_NAME, false)
+    }
+
+    private fun setShareScreen(packageName: String, fullScreen: Boolean) {
+        val launchCookie = if (fullScreen) null else ActivityOptions.LaunchCookie()
+        mediaProjectionInfo = MediaProjectionInfo(packageName, UserHandle.CURRENT, launchCookie)
     }
 
     private fun setupNotificationEntry(
         packageName: String,
         isFgs: Boolean = false,
+        isCoreApp: Boolean = false,
         overrideVisibility: Boolean = false,
         overrideChannelVisibility: Boolean = false,
     ): NotificationEntry {
@@ -642,8 +692,14 @@
             // Developer has marked notification as public
             notification.visibility = VISIBILITY_PUBLIC
         }
-        val notificationEntry =
-            NotificationEntryBuilder().setNotification(notification).setPkg(packageName).build()
+        val notificationEntryBuilder =
+            NotificationEntryBuilder().setNotification(notification).setPkg(packageName)
+        if (isCoreApp) {
+            notificationEntryBuilder.setUid(Process.FIRST_APPLICATION_UID - 10)
+        } else {
+            notificationEntryBuilder.setUid(Process.FIRST_APPLICATION_UID + 10)
+        }
+        val notificationEntry = notificationEntryBuilder.build()
         val channel = NotificationChannel("1", "1", IMPORTANCE_HIGH)
         if (overrideChannelVisibility) {
             // User doesn't allow private notifications at the channel level
@@ -662,6 +718,10 @@
         return setupNotificationEntry(packageName, isFgs = true)
     }
 
+    private fun setupCoreAppNotificationEntry(packageName: String): NotificationEntry {
+        return setupNotificationEntry(packageName, isCoreApp = true)
+    }
+
     private fun setupPublicNotificationEntry(packageName: String): NotificationEntry {
         return setupNotificationEntry(packageName, overrideVisibility = true)
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
index cb7d276..e1797c4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldAodAnimationControllerTest.kt
@@ -29,6 +29,7 @@
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
+import com.android.systemui.keyguard.domain.interactor.ToAodFoldTransitionInteractor
 import com.android.systemui.shade.ShadeFoldAnimator
 import com.android.systemui.shade.ShadeViewController
 import com.android.systemui.statusbar.LightRevealScrim
@@ -79,6 +80,8 @@
 
     @Mock lateinit var shadeFoldAnimator: ShadeFoldAnimator
 
+    @Mock lateinit var foldTransitionInteractor: ToAodFoldTransitionInteractor
+
     @Captor private lateinit var foldStateListenerCaptor: ArgumentCaptor<FoldStateListener>
 
     private lateinit var deviceStates: FoldableDeviceStates
@@ -96,6 +99,7 @@
 
         // TODO(b/254878364): remove this call to NPVC.getView()
         whenever(shadeViewController.shadeFoldAnimator).thenReturn(shadeFoldAnimator)
+        whenever(foldTransitionInteractor.foldAnimator).thenReturn(shadeFoldAnimator)
         whenever(shadeFoldAnimator.view).thenReturn(viewGroup)
         whenever(viewGroup.viewTreeObserver).thenReturn(viewTreeObserver)
         whenever(wakefulnessLifecycle.lastSleepReason)
@@ -120,6 +124,7 @@
                         globalSettings,
                         latencyTracker,
                         { keyguardInteractor },
+                        { foldTransitionInteractor },
                     )
                     .apply { initialize(centralSurfaces, shadeViewController, lightRevealScrim) }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt
new file mode 100644
index 0000000..dddc712
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.unfold
+
+import android.os.PowerManager
+import android.os.SystemProperties
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.internal.foldables.FoldLockSettingAvailabilityProvider
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.display.data.repository.DeviceStateRepository.DeviceState
+import com.android.systemui.display.data.repository.fakeDeviceStateRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
+import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setScreenPowerState
+import com.android.systemui.power.domain.interactor.powerInteractor
+import com.android.systemui.power.shared.model.ScreenPowerState
+import com.android.systemui.util.animation.data.repository.fakeAnimationStatusRepository
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.atLeast
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@RunWith(AndroidTestingRunner::class)
+@OptIn(ExperimentalCoroutinesApi::class)
+class FoldLightRevealOverlayAnimationTest : SysuiTestCase() {
+    private val kosmos = Kosmos()
+    private val testScope: TestScope = kosmos.testScope
+    private val fakeDeviceStateRepository = kosmos.fakeDeviceStateRepository
+    private val powerInteractor = kosmos.powerInteractor
+    private val fakeAnimationStatusRepository = kosmos.fakeAnimationStatusRepository
+    private val mockControllerFactory = kosmos.fullscreenLightRevealAnimationControllerFactory
+    private val mockFullScreenController = kosmos.fullscreenLightRevealAnimationController
+    private val mockFoldLockSettingAvailabilityProvider =
+        mock<FoldLockSettingAvailabilityProvider>()
+    private val onOverlayReady = mock<Runnable>()
+    private lateinit var foldLightRevealAnimation: FoldLightRevealOverlayAnimation
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        whenever(mockFoldLockSettingAvailabilityProvider.isFoldLockBehaviorAvailable)
+            .thenReturn(true)
+        fakeAnimationStatusRepository.onAnimationStatusChanged(true)
+
+        foldLightRevealAnimation =
+            FoldLightRevealOverlayAnimation(
+                kosmos.testDispatcher,
+                fakeDeviceStateRepository,
+                powerInteractor,
+                testScope.backgroundScope,
+                fakeAnimationStatusRepository,
+                mockControllerFactory,
+                mockFoldLockSettingAvailabilityProvider
+            )
+        foldLightRevealAnimation.init()
+    }
+
+    @Test
+    fun foldToScreenOn_playFoldAnimation() =
+        testScope.runTest {
+            foldDeviceToScreenOff()
+            turnScreenOn()
+
+            verifyFoldAnimationPlayed()
+        }
+
+    @Test
+    fun foldToAod_doNotPlayFoldAnimation() =
+        testScope.runTest {
+            foldDeviceToScreenOff()
+            emitLastWakefulnessEventStartingToSleep()
+            advanceTimeBy(SHORT_DELAY_MS)
+            turnScreenOn()
+            advanceTimeBy(ANIMATION_DURATION)
+
+            verifyFoldAnimationDidNotPlay()
+        }
+
+    @Test
+    fun foldToScreenOff_doNotPlayFoldAnimation() =
+        testScope.runTest {
+            foldDeviceToScreenOff()
+            emitLastWakefulnessEventStartingToSleep()
+            advanceTimeBy(SHORT_DELAY_MS)
+            advanceTimeBy(ANIMATION_DURATION)
+
+            verifyFoldAnimationDidNotPlay()
+        }
+
+    @Test
+    fun foldToScreenOnWithDelay_doNotPlayFoldAnimation() =
+        testScope.runTest {
+            foldDeviceToScreenOff()
+            foldLightRevealAnimation.onScreenTurningOn {}
+            advanceTimeBy(WAIT_FOR_ANIMATION_TIMEOUT_MS)
+            powerInteractor.setScreenPowerState(ScreenPowerState.SCREEN_ON)
+            advanceTimeBy(SHORT_DELAY_MS)
+            advanceTimeBy(ANIMATION_DURATION)
+
+            verifyFoldAnimationDidNotPlay()
+        }
+
+    @Test
+    fun immediateUnfoldAfterFold_removeOverlayAfterCancellation() =
+        testScope.runTest {
+            foldDeviceToScreenOff()
+            foldLightRevealAnimation.onScreenTurningOn {}
+            advanceTimeBy(SHORT_DELAY_MS)
+            advanceTimeBy(ANIMATION_DURATION)
+            fakeDeviceStateRepository.emit(DeviceState.HALF_FOLDED)
+            advanceTimeBy(SHORT_DELAY_MS)
+            powerInteractor.setScreenPowerState(ScreenPowerState.SCREEN_ON)
+
+            verifyOverlayWasRemoved()
+        }
+
+    @Test
+    fun foldToScreenOn_removeOverlayAfterCompletion() =
+        testScope.runTest {
+            foldDeviceToScreenOff()
+            turnScreenOn()
+            advanceTimeBy(ANIMATION_DURATION)
+
+            verifyOverlayWasRemoved()
+        }
+
+    @Test
+    fun unfold_immediatelyRunRunnable() =
+        testScope.runTest {
+            foldLightRevealAnimation.onScreenTurningOn(onOverlayReady)
+
+            verify(onOverlayReady).run()
+        }
+
+    private suspend fun TestScope.foldDeviceToScreenOff() {
+        fakeDeviceStateRepository.emit(DeviceState.HALF_FOLDED)
+        powerInteractor.setScreenPowerState(ScreenPowerState.SCREEN_ON)
+        advanceTimeBy(SHORT_DELAY_MS)
+        fakeDeviceStateRepository.emit(DeviceState.FOLDED)
+        advanceTimeBy(SHORT_DELAY_MS)
+        powerInteractor.setScreenPowerState(ScreenPowerState.SCREEN_OFF)
+        advanceTimeBy(SHORT_DELAY_MS)
+    }
+
+    private fun TestScope.turnScreenOn() {
+        foldLightRevealAnimation.onScreenTurningOn {}
+        advanceTimeBy(SHORT_DELAY_MS)
+        powerInteractor.setScreenPowerState(ScreenPowerState.SCREEN_ON)
+        advanceTimeBy(SHORT_DELAY_MS)
+    }
+
+    private fun emitLastWakefulnessEventStartingToSleep() =
+        powerInteractor.setAsleepForTest(PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD)
+
+    private fun verifyFoldAnimationPlayed() =
+        verify(mockFullScreenController, atLeast(1)).updateRevealAmount(any())
+
+    private fun verifyFoldAnimationDidNotPlay() =
+        verify(mockFullScreenController, never()).updateRevealAmount(any())
+
+    private fun verifyOverlayWasRemoved() =
+        verify(mockFullScreenController, atLeast(1)).ensureOverlayRemoved()
+
+    private companion object {
+        const val WAIT_FOR_ANIMATION_TIMEOUT_MS = 2000L
+        val ANIMATION_DURATION: Long
+            get() = SystemProperties.getLong("persist.fold_animation_duration", 200L)
+        const val SHORT_DELAY_MS = 50L
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
index fccb936..dc5597a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallet/controller/QuickAccessWalletControllerTest.java
@@ -29,6 +29,7 @@
 import static org.mockito.Mockito.when;
 
 import android.app.PendingIntent;
+import android.app.role.RoleManager;
 import android.content.Intent;
 import android.service.quickaccesswallet.GetWalletCardsRequest;
 import android.service.quickaccesswallet.QuickAccessWalletClient;
@@ -54,11 +55,14 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.List;
+
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 @SmallTest
 public class QuickAccessWalletControllerTest extends SysuiTestCase {
 
+    private static final String WALLET_ROLE_HOLDER = "wallet.role.holder";
     @Mock
     private QuickAccessWalletClient mQuickAccessWalletClient;
     @Mock
@@ -69,6 +73,8 @@
     private ActivityStarter mActivityStarter;
     @Mock
     private ActivityTransitionAnimator.Controller mAnimationController;
+    @Mock
+    private RoleManager mRoleManager;
     @Captor
     private ArgumentCaptor<GetWalletCardsRequest> mRequestCaptor;
     @Captor
@@ -102,7 +108,8 @@
                 MoreExecutors.directExecutor(),
                 mSecureSettings,
                 mQuickAccessWalletClient,
-                mClock);
+                mClock,
+                mRoleManager);
     }
 
     @Test
@@ -113,6 +120,24 @@
     }
 
     @Test
+    public void walletRoleAvailable_isAvailable() {
+        when(mRoleManager.isRoleAvailable(eq(RoleManager.ROLE_WALLET))).thenReturn(true);
+        when(mRoleManager.getRoleHolders(eq(RoleManager.ROLE_WALLET)))
+                .thenReturn(List.of(WALLET_ROLE_HOLDER));
+
+        assertTrue(mController.isWalletRoleAvailable());
+    }
+
+    @Test
+    public void walletRoleAvailable_isNotAvailable() {
+        when(mRoleManager.isRoleAvailable(eq(RoleManager.ROLE_WALLET))).thenReturn(false);
+        when(mRoleManager.getRoleHolders(eq(RoleManager.ROLE_WALLET)))
+                .thenReturn(List.of(WALLET_ROLE_HOLDER));
+
+        assertFalse(mController.isWalletRoleAvailable());
+    }
+
+    @Test
     public void walletServiceUnavailable_walletNotEnabled() {
         when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(false);
 
diff --git a/packages/SystemUI/tests/utils/kosmos/src/com/android/systemui/kosmos/Kosmos.kt b/packages/SystemUI/tests/utils/kosmos/src/com/android/systemui/kosmos/Kosmos.kt
new file mode 100644
index 0000000..685bb0a
--- /dev/null
+++ b/packages/SystemUI/tests/utils/kosmos/src/com/android/systemui/kosmos/Kosmos.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.kosmos
+
+import kotlin.reflect.KProperty
+
+// (Historical note: The name Kosmos is meant to invoke "Kotlin", the "Object Mother" pattern
+//   (https://martinfowler.com/bliki/ObjectMother.html), and of course the Greek word "kosmos" for
+//   the "order of the world" (https://en.wiktionary.org/wiki/%CE%BA%CF%8C%CF%83%CE%BC%CE%BF%CF%82)
+
+/**
+ * Each Kosmos is its own self-contained set of fixtures, which may reference each other. Fixtures
+ * can be defined through extension properties in any file:
+ * ```
+ * // fixture that must be set:
+ * var Kosmos.context by Fixture<Context>()
+ *
+ * // fixture with overrideable default.
+ * var Kosmos.landscapeMode by Fixture { false }
+ *
+ * // fixture forbidding override (note `val`, and referencing context fixture from above)
+ * val Kosmos.lifecycleScope by Fixture { context.lifecycleScope }
+ * ```
+ *
+ * To use the fixtures, create an instance of Kosmos and retrieve the values you need:
+ * ```
+ * val k = Kosmos()
+ * k.context = mContext
+ * val underTest = YourInteractor(
+ *     context = k.context,
+ *     landscapeMode = k.landscapeMode,
+ * )
+ * ```
+ */
+interface Kosmos {
+    /**
+     * Lookup a fixture in the Kosmos by [name], using [creator] to instantiate and store one if
+     * there is none present.
+     */
+    fun <T> get(name: String, creator: (Kosmos.() -> T)?): T
+
+    /** Sets the [value] of a fixture with the given [name]. */
+    fun set(name: String, value: Any?)
+
+    /**
+     * A value in the kosmos that has a single value once it's read. It can be overridden before
+     * first use only; all objects that are dependent on this fixture will get the same value.
+     *
+     * Example classic uses would be a clock, filesystem, or singleton controller.
+     *
+     * If no [creator] parameter is provided, the fixture must be set before use.
+     */
+    class Fixture<T>(private val creator: (Kosmos.() -> T)? = null) {
+        operator fun getValue(thisRef: Kosmos, property: KProperty<*>): T =
+            thisRef.get(property.name, creator)
+
+        operator fun setValue(thisRef: Kosmos, property: KProperty<*>, value: T) {
+            thisRef.set(property.name, value)
+        }
+    }
+}
+
+/** Constructs a fresh Kosmos. */
+fun Kosmos(): Kosmos = KosmosRegistry()
+
+private class KosmosRegistry : Kosmos {
+    val map: MutableMap<String, Any?> = mutableMapOf()
+    val gotten: MutableSet<String> = mutableSetOf()
+
+    override fun <T> get(name: String, creator: (Kosmos.() -> T)?): T {
+        gotten.add(name)
+        if (name !in map) {
+            checkNotNull(creator) { "Fixture $name has no default, and is read before set." }
+            map[name] = creator()
+        }
+        @Suppress("UNCHECKED_CAST") return map[name] as T
+    }
+
+    override fun set(name: String, value: Any?) {
+        check(name !in gotten) { "Tried to set fixture '$name' after it's already been read." }
+        map[name] = value
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
index 3d84291..65dd411 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/TestMocksModule.kt
@@ -28,6 +28,7 @@
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardViewController
 import com.android.systemui.animation.DialogTransitionAnimator
+import com.android.systemui.biometrics.AuthController
 import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
 import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.demomode.DemoModeController
@@ -85,6 +86,7 @@
     @get:Provides val activityStarter: ActivityStarter = mock(),
     @get:Provides val activityManagerWrapper: ActivityManagerWrapper = mock(),
     @get:Provides val ambientState: AmbientState = mock(),
+    @get:Provides val authController: AuthController = mock(),
     @get:Provides val bubbles: Optional<Bubbles> = Optional.of(mock()),
     @get:Provides val darkIconDispatcher: DarkIconDispatcher = mock(),
     @get:Provides val demoModeController: DemoModeController = mock(),
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt
index 34a9c8a..d1709d6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/biometrics/domain/interactor/FingerprintPropertyInteractorKosmos.kt
@@ -30,5 +30,6 @@
         repository = fingerprintPropertyRepository,
         configurationInteractor = configurationInteractor,
         displayStateInteractor = displayStateInteractor,
+        udfpsOverlayInteractor = udfpsOverlayInteractor,
     )
 }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/BrightnessPolicyRepositoryKosmos.kt
similarity index 65%
copy from tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
copy to packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/BrightnessPolicyRepositoryKosmos.kt
index 4e64ab0..2e5ddc7 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/BrightnessPolicyRepositoryKosmos.kt
@@ -14,15 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.systemui.brightness.data.repository
 
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
+import com.android.systemui.kosmos.Kosmos
 
-import java.util.List;
+val Kosmos.fakeBrightnessPolicyRepository by Kosmos.Fixture { FakeBrightnessPolicyRepository() }
 
-public interface AslMarshallable {
-
-    /** Creates the on-device DOM element from the AslMarshallable Java Object. */
-    List<Element> toOdDomElements(Document doc);
-}
+var Kosmos.brightnessPolicyRepository: BrightnessPolicyRepository by
+    Kosmos.Fixture { fakeBrightnessPolicyRepository }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/FakeBrightnessPolicyRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/FakeBrightnessPolicyRepository.kt
new file mode 100644
index 0000000..d3ceb15
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/FakeBrightnessPolicyRepository.kt
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.data.repository
+
+import com.android.settingslib.RestrictedLockUtils
+import com.android.systemui.utils.PolicyRestriction
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+class FakeBrightnessPolicyRepository : BrightnessPolicyRepository {
+    private val _restrictionPolicy: MutableStateFlow<PolicyRestriction> =
+        MutableStateFlow(PolicyRestriction.NoRestriction)
+    override val restrictionPolicy = _restrictionPolicy.asStateFlow()
+
+    fun setCurrentUserUnrestricted() {
+        _restrictionPolicy.value = PolicyRestriction.NoRestriction
+    }
+
+    fun setCurrentUserRestricted() {
+        _restrictionPolicy.value =
+            PolicyRestriction.Restricted(
+                RestrictedLockUtils.EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(
+                    BrightnessPolicyRepository.RESTRICTION
+                )
+            )
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/FakeScreenBrightnessRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/FakeScreenBrightnessRepository.kt
new file mode 100644
index 0000000..a05b5e6
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/FakeScreenBrightnessRepository.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.brightness.data.repository
+
+import android.hardware.display.BrightnessInfo
+import android.hardware.display.BrightnessInfo.BRIGHTNESS_MAX_REASON_NONE
+import android.hardware.display.BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF
+import com.android.systemui.brightness.data.model.LinearBrightness
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.map
+
+class FakeScreenBrightnessRepository(
+    initialBrightnessInfo: BrightnessInfo =
+        BrightnessInfo(0f, 0f, 1f, HIGH_BRIGHTNESS_MODE_OFF, 1f, BRIGHTNESS_MAX_REASON_NONE)
+) : ScreenBrightnessRepository {
+
+    private val brightnessInfo = MutableStateFlow(initialBrightnessInfo)
+    private val _temporaryBrightness =
+        MutableStateFlow(LinearBrightness(initialBrightnessInfo.brightness))
+    val temporaryBrightness = _temporaryBrightness.asStateFlow()
+    override val linearBrightness = brightnessInfo.map { LinearBrightness(it.brightness) }
+    override val minLinearBrightness = brightnessInfo.map { LinearBrightness(it.brightnessMinimum) }
+    override val maxLinearBrightness = brightnessInfo.map { LinearBrightness(it.brightnessMaximum) }
+
+    override suspend fun getMinMaxLinearBrightness(): Pair<LinearBrightness, LinearBrightness> {
+        return minMaxLinearBrightness()
+    }
+
+    private fun minMaxLinearBrightness(): Pair<LinearBrightness, LinearBrightness> {
+        return with(brightnessInfo.value) {
+            LinearBrightness(brightnessMinimum) to LinearBrightness(brightnessMaximum)
+        }
+    }
+
+    override fun setTemporaryBrightness(value: LinearBrightness) {
+        val bounds = minMaxLinearBrightness()
+        val clampedValue = value.clamp(bounds.first, bounds.second)
+        _temporaryBrightness.value = clampedValue
+    }
+
+    override fun setBrightness(value: LinearBrightness) {
+        val bounds = minMaxLinearBrightness()
+        val clampedValue = value.clamp(bounds.first, bounds.second)
+        _temporaryBrightness.value = clampedValue
+        brightnessInfo.value =
+            with(brightnessInfo.value) {
+                BrightnessInfo(
+                    clampedValue.floatValue,
+                    brightnessMinimum,
+                    brightnessMaximum,
+                    highBrightnessMode,
+                    highBrightnessTransitionPoint,
+                    brightnessMaxReason,
+                )
+            }
+    }
+
+    fun setMinMaxBrightness(min: LinearBrightness, max: LinearBrightness) {
+        check(min.floatValue <= max.floatValue)
+        val clampedBrightness = LinearBrightness(brightnessInfo.value.brightness).clamp(min, max)
+        _temporaryBrightness.value = clampedBrightness
+        brightnessInfo.value =
+            with(brightnessInfo.value) {
+                BrightnessInfo(
+                    clampedBrightness.floatValue,
+                    min.floatValue,
+                    max.floatValue,
+                    highBrightnessMode,
+                    highBrightnessTransitionPoint,
+                    brightnessMaxReason
+                )
+            }
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/ScreenBrightnessRepositoryKosmos.kt
similarity index 63%
copy from tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
copy to packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/ScreenBrightnessRepositoryKosmos.kt
index 4e64ab0..c5b0eb2 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/data/repository/ScreenBrightnessRepositoryKosmos.kt
@@ -14,15 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.systemui.brightness.data.repository
 
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
+import com.android.systemui.kosmos.Kosmos
 
-import java.util.List;
+val Kosmos.fakeScreenBrightnessRepository: FakeScreenBrightnessRepository by
+    Kosmos.Fixture { FakeScreenBrightnessRepository() }
 
-public interface AslMarshallable {
-
-    /** Creates the on-device DOM element from the AslMarshallable Java Object. */
-    List<Element> toOdDomElements(Document doc);
-}
+var Kosmos.screenBrightnessRepository: ScreenBrightnessRepository by
+    Kosmos.Fixture { fakeScreenBrightnessRepository }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallableFactory.java b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/domain/interactor/BrightnessPolicyEnforcementInteractorKosmos.kt
similarity index 60%
copy from tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallableFactory.java
copy to packages/SystemUI/tests/utils/src/com/android/systemui/brightness/domain/interactor/BrightnessPolicyEnforcementInteractorKosmos.kt
index b8f9f0e..9d3c8d2 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallableFactory.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/domain/interactor/BrightnessPolicyEnforcementInteractorKosmos.kt
@@ -14,16 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.systemui.brightness.domain.interactor
 
-import com.android.asllib.util.MalformedXmlException;
+import com.android.systemui.brightness.data.repository.brightnessPolicyRepository
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.plugins.activityStarter
 
-import org.w3c.dom.Element;
-
-import java.util.List;
-
-public interface AslMarshallableFactory<T extends AslMarshallable> {
-
-    /** Creates an {@link AslMarshallableFactory} from human-readable DOM element */
-    T createFromHrElements(List<Element> elements) throws MalformedXmlException;
-}
+val Kosmos.brightnessPolicyEnforcementInteractor by
+    Kosmos.Fixture {
+        BrightnessPolicyEnforcementInteractor(brightnessPolicyRepository, activityStarter)
+    }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractorKosmos.kt
similarity index 66%
copy from tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
copy to packages/SystemUI/tests/utils/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractorKosmos.kt
index 4e64ab0..22784e4 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/brightness/domain/interactor/ScreenBrightnessInteractorKosmos.kt
@@ -14,15 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.systemui.brightness.domain.interactor
 
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
+import com.android.systemui.brightness.data.repository.screenBrightnessRepository
+import com.android.systemui.kosmos.Kosmos
 
-import java.util.List;
-
-public interface AslMarshallable {
-
-    /** Creates the on-device DOM element from the AslMarshallable Java Object. */
-    List<Element> toOdDomElements(Document doc);
-}
+val Kosmos.screenBrightnessInteractor by
+    Kosmos.Fixture { ScreenBrightnessInteractor(screenBrightnessRepository) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/BroadcastSenderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/BroadcastSenderKosmos.kt
new file mode 100644
index 0000000..42ad679
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/BroadcastSenderKosmos.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.broadcast
+
+import android.content.applicationContext
+import com.android.systemui.concurrency.fakeExecutor
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.wakelock.WakeLockFake
+
+val Kosmos.mockBroadcastSender by Kosmos.Fixture { mock<BroadcastSender>() }
+var Kosmos.broadcastSender by
+    Kosmos.Fixture {
+        BroadcastSender(applicationContext, WakeLockFake.Builder(applicationContext), fakeExecutor)
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt
index 77caeaa..045bd5d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/data/repository/FakeDeviceEntryRepository.kt
@@ -21,7 +21,6 @@
 import javax.inject.Inject
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asStateFlow
 
 /** Fake implementation of [DeviceEntryRepository] */
 @SysUISingleton
@@ -31,21 +30,10 @@
     private val _isBypassEnabled = MutableStateFlow(false)
     override val isBypassEnabled: StateFlow<Boolean> = _isBypassEnabled
 
-    private val _isUnlocked = MutableStateFlow(false)
-    override val isUnlocked: StateFlow<Boolean> = _isUnlocked.asStateFlow()
-
     override suspend fun isLockscreenEnabled(): Boolean {
         return isLockscreenEnabled
     }
 
-    override fun reportSuccessfulAuthentication() {
-        _isUnlocked.value = true
-    }
-
-    fun setUnlocked(isUnlocked: Boolean) {
-        _isUnlocked.value = isUnlocked
-    }
-
     fun setLockscreenEnabled(isLockscreenEnabled: Boolean) {
         this.isLockscreenEnabled = isLockscreenEnabled
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt
index e73e295..bff10a1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceEntryInteractorKosmos.kt
@@ -23,7 +23,6 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.scene.domain.interactor.sceneInteractor
-import com.android.systemui.scene.shared.flag.sceneContainerFlags
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 
 @ExperimentalCoroutinesApi
@@ -35,11 +34,10 @@
             authenticationInteractor = authenticationInteractor,
             sceneInteractor = sceneInteractor,
             faceAuthInteractor = deviceEntryFaceAuthInteractor,
-            trustInteractor = trustInteractor,
-            flags = sceneContainerFlags,
-            deviceUnlockedInteractor = deviceUnlockedInteractor,
             fingerprintAuthInteractor = deviceEntryFingerprintAuthInteractor,
             biometricSettingsInteractor = deviceEntryBiometricSettingsInteractor,
+            trustInteractor = trustInteractor,
+            deviceUnlockedInteractor = deviceUnlockedInteractor,
             systemPropertiesHelper = fakeSystemPropertiesHelper,
         )
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt
index df1cdc2..14210bc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/deviceentry/domain/interactor/DeviceUnlockedInteractorKosmos.kt
@@ -18,14 +18,20 @@
 
 import com.android.systemui.authentication.domain.interactor.authenticationInteractor
 import com.android.systemui.deviceentry.data.repository.deviceEntryRepository
+import com.android.systemui.keyguard.domain.interactor.trustInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.power.domain.interactor.powerInteractor
 
 val Kosmos.deviceUnlockedInteractor by Fixture {
     DeviceUnlockedInteractor(
         applicationScope = applicationCoroutineScope,
         authenticationInteractor = authenticationInteractor,
         deviceEntryRepository = deviceEntryRepository,
+        trustInteractor = trustInteractor,
+        faceAuthInteractor = deviceEntryFaceAuthInteractor,
+        fingerprintAuthInteractor = deviceEntryFingerprintAuthInteractor,
+        powerInteractor = powerInteractor,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt
index f65c74f..c1d2ad6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/EnableSceneContainer.kt
@@ -22,6 +22,8 @@
 import com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR
 import com.android.systemui.Flags.FLAG_MEDIA_IN_SCENE_CONTAINER
 import com.android.systemui.Flags.FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT
+import com.android.systemui.Flags.FLAG_NOTIFICATIONS_HEADS_UP_REFACTOR
+import com.android.systemui.Flags.FLAG_PREDICTIVE_BACK_SYSUI
 import com.android.systemui.Flags.FLAG_SCENE_CONTAINER
 
 /**
@@ -29,12 +31,14 @@
  * that feature. It is also picked up by [SceneContainerRule] to set non-aconfig prerequisites.
  */
 @EnableFlags(
-    FLAG_SCENE_CONTAINER,
-    FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR,
-    FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT,
     FLAG_COMPOSE_LOCKSCREEN,
-    FLAG_MEDIA_IN_SCENE_CONTAINER,
+    FLAG_KEYGUARD_BOTTOM_AREA_REFACTOR,
     FLAG_KEYGUARD_WM_STATE_REFACTOR,
+    FLAG_MEDIA_IN_SCENE_CONTAINER,
+    FLAG_MIGRATE_CLOCKS_TO_BLUEPRINT,
+    FLAG_NOTIFICATIONS_HEADS_UP_REFACTOR,
+    FLAG_PREDICTIVE_BACK_SYSUI,
+    FLAG_SCENE_CONTAINER,
 )
 @Retention(AnnotationRetention.RUNTIME)
 @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/SceneContainerRule.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/SceneContainerRule.kt
index 4e05de2..775ad14 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/SceneContainerRule.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/SceneContainerRule.kt
@@ -16,16 +16,14 @@
 
 package com.android.systemui.flags
 
-import android.util.Log
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import org.junit.Assert
-import org.junit.Assume
 import org.junit.rules.TestRule
 import org.junit.runner.Description
 import org.junit.runners.model.Statement
 
 /**
- * Should always be used with [SetFlagsRule] and should be ordered after it.
+ * Should always be used with `SetFlagsRule` and should be ordered after it.
  *
  * Used to ensure tests annotated with [EnableSceneContainer] can actually get `true` from
  * [SceneContainerFlag.isEnabled].
@@ -35,15 +33,10 @@
         return object : Statement() {
             @Throws(Throwable::class)
             override fun evaluate() {
-                val initialEnabledValue = Flags.SCENE_CONTAINER_ENABLED
                 val hasAnnotation =
                     description?.testClass?.getAnnotation(EnableSceneContainer::class.java) !=
                         null || description?.getAnnotation(EnableSceneContainer::class.java) != null
                 if (hasAnnotation) {
-                    Assume.assumeTrue(
-                        "Couldn't set Flags.SCENE_CONTAINER_ENABLED for @EnableSceneContainer test",
-                        trySetSceneContainerEnabled(true)
-                    )
                     Assert.assertTrue(
                         "SceneContainerFlag.isEnabled is false:" +
                             "\n * Did you forget to add a new aconfig flag dependency in" +
@@ -52,32 +45,7 @@
                         SceneContainerFlag.isEnabled
                     )
                 }
-                try {
-                    base?.evaluate()
-                } finally {
-                    if (hasAnnotation) {
-                        trySetSceneContainerEnabled(initialEnabledValue)
-                    }
-                }
-            }
-        }
-    }
-
-    companion object {
-        fun trySetSceneContainerEnabled(enabled: Boolean): Boolean {
-            if (Flags.SCENE_CONTAINER_ENABLED == enabled) {
-                return true
-            }
-            return try {
-                // TODO(b/283300105): remove this reflection setting once the hard-coded
-                //  Flags.SCENE_CONTAINER_ENABLED is no longer needed.
-                val field = Flags::class.java.getField("SCENE_CONTAINER_ENABLED")
-                field.isAccessible = true
-                field.set(null, enabled) // note: this does not work with multivalent tests
-                true
-            } catch (t: Throwable) {
-                Log.e("SceneContainerRule", "Unable to set SCENE_CONTAINER_ENABLED=$enabled", t)
-                false
+                base?.evaluate()
             }
         }
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt
index de6bfb2..a242368 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/data/repository/FakeKeyguardTransitionRepository.kt
@@ -32,7 +32,9 @@
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.channels.BufferOverflow
 import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.flow.asStateFlow
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.test.TestCoroutineScheduler
 import kotlinx.coroutines.test.TestScope
@@ -41,11 +43,21 @@
 /** Fake implementation of [KeyguardTransitionRepository] */
 @SysUISingleton
 class FakeKeyguardTransitionRepository @Inject constructor() : KeyguardTransitionRepository {
-
     private val _transitions =
         MutableSharedFlow<TransitionStep>(replay = 3, onBufferOverflow = BufferOverflow.DROP_OLDEST)
     override val transitions: SharedFlow<TransitionStep> = _transitions
 
+    private val _currentTransitionInfo: MutableStateFlow<TransitionInfo> =
+        MutableStateFlow(
+            TransitionInfo(
+                ownerName = "",
+                from = KeyguardState.OFF,
+                to = KeyguardState.LOCKSCREEN,
+                animator = null
+            )
+        )
+    override var currentTransitionInfoInternal = _currentTransitionInfo.asStateFlow()
+
     init {
         // Seed the fake repository with the same initial steps the actual repository uses.
         KeyguardTransitionRepositoryImpl.initialTransitionSteps.forEach { _transitions.tryEmit(it) }
@@ -159,6 +171,11 @@
             ),
         validateStep: Boolean = true
     ) {
+        if (step.transitionState == TransitionState.STARTED) {
+            _currentTransitionInfo.value =
+                TransitionInfo(from = step.from, to = step.to, animator = null, ownerName = "")
+        }
+
         _transitions.replayCache.last().let { lastStep ->
             if (
                 validateStep &&
@@ -201,7 +218,8 @@
         }
     }
 
-    override fun startTransition(info: TransitionInfo): UUID? {
+    override suspend fun startTransition(info: TransitionInfo): UUID? {
+        _currentTransitionInfo.value = info
         return if (info.animator == null) UUID.randomUUID() else null
     }
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorKosmos.kt
index d791e94..12165cd 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractorKosmos.kt
@@ -20,4 +20,4 @@
 import com.android.systemui.kosmos.Kosmos
 
 val Kosmos.keyguardClockInteractor by
-    Kosmos.Fixture { KeyguardClockInteractor(keyguardClockRepository = keyguardClockRepository) }
+    Kosmos.Fixture { KeyguardClockInteractor(keyguardClockRepository) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt
index e6651a4..f86e9b7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt
@@ -20,6 +20,8 @@
 
 import com.android.systemui.common.ui.domain.interactor.configurationInteractor
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
+import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
@@ -30,5 +32,7 @@
         deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
         configurationInteractor = configurationInteractor,
         animationFlow = keyguardTransitionAnimationFlow,
+        keyguardInteractor = keyguardInteractor,
+        keyguardTransitionInteractor = keyguardTransitionInteractor,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/Kosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/Kosmos.kt
deleted file mode 100644
index c74cdd4..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/Kosmos.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-package com.android.systemui.kosmos
-
-import kotlin.reflect.KProperty
-
-// (Historical note: The name Kosmos is meant to invoke "Kotlin", the "Object Mother" pattern
-//   (https://martinfowler.com/bliki/ObjectMother.html), and of course the Greek word "kosmos" for
-//   the "order of the world" (https://en.wiktionary.org/wiki/%CE%BA%CF%8C%CF%83%CE%BC%CE%BF%CF%82)
-/**
- * Each Kosmos is its own self-contained set of fixtures, which may reference each other. Fixtures
- * can be defined through extension properties in any file:
- * ```
- * // fixture that must be set:
- * var Kosmos.context by Fixture<Context>()
- *
- * // fixture with overrideable default.
- * var Kosmos.landscapeMode by Fixture { false }
- *
- * // fixture forbidding override (note `val`, and referencing context fixture from above)
- * val Kosmos.lifecycleScope by Fixture { context.lifecycleScope }
- * ```
- *
- * To use the fixtures, create an instance of Kosmos and retrieve the values you need:
- * ```
- * val k = Kosmos()
- * k.context = mContext
- * val underTest = YourInteractor(
- *     context = k.context,
- *     landscapeMode = k.landscapeMode,
- * )
- * ```
- */
-class Kosmos {
-    private val map: MutableMap<String, Any?> = mutableMapOf()
-    private val gotten: MutableSet<String> = mutableSetOf()
-
-    /**
-     * A value in the kosmos that has a single value once it's read. It can be overridden before
-     * first use only; all objects that are dependent on this fixture will get the same value.
-     *
-     * Example classic uses would be a clock, filesystem, or singleton controller.
-     *
-     * If no [creator] parameter is provided, the fixture must be set before use.
-     */
-    class Fixture<T>(private val creator: (Kosmos.() -> T)? = null) {
-        operator fun getValue(thisRef: Kosmos, property: KProperty<*>): T {
-            thisRef.gotten.add(property.name)
-            @Suppress("UNCHECKED_CAST")
-            if (!thisRef.map.contains(property.name)) {
-                if (creator == null) {
-                    throw IllegalStateException(
-                        "Fixture ${property.name} has no default, and is read before set."
-                    )
-                } else {
-                    val nonNullCreator = creator
-                    // The Kotlin compiler seems to need this odd workaround
-                    thisRef.map[property.name] = thisRef.nonNullCreator()
-                }
-            }
-            return thisRef.map[property.name] as T
-        }
-
-        operator fun setValue(thisRef: Kosmos, property: KProperty<*>, value: T) {
-            check(!thisRef.gotten.contains(property.name)) {
-                "Tried to set fixture '${property.name}' after it's already been read."
-            }
-            thisRef.map[property.name] = value
-        }
-    }
-}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractorKosmos.kt
new file mode 100644
index 0000000..29c5bd5
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaControlInteractorKosmos.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.domain.pipeline.interactor
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+import com.android.systemui.media.controls.domain.pipeline.mediaDataProcessor
+import com.android.systemui.media.controls.util.mediaInstanceId
+
+val Kosmos.mediaControlInteractor by
+    Kosmos.Fixture {
+        MediaControlInteractor(
+            instanceId = mediaInstanceId,
+            repository = mediaFilterRepository,
+            mediaDataProcessor = mediaDataProcessor,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractorKosmos.kt
new file mode 100644
index 0000000..1edd405
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/domain/pipeline/interactor/MediaRecommendationsInteractorKosmos.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.domain.pipeline.interactor
+
+import android.content.applicationContext
+import com.android.systemui.broadcast.broadcastSender
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.media.controls.data.repository.mediaFilterRepository
+import com.android.systemui.media.controls.domain.pipeline.mediaDataProcessor
+import com.android.systemui.plugins.activityStarter
+
+val Kosmos.mediaRecommendationsInteractor by
+    Kosmos.Fixture {
+        MediaRecommendationsInteractor(
+            applicationScope = applicationCoroutineScope,
+            applicationContext = applicationContext,
+            repository = mediaFilterRepository,
+            mediaDataProcessor = mediaDataProcessor,
+            broadcastSender = broadcastSender,
+            activityStarter = activityStarter,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModelKosmos.kt
new file mode 100644
index 0000000..34a5277
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModelKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.media.controls.ui.viewmodel
+
+import android.content.applicationContext
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.media.controls.domain.pipeline.interactor.mediaRecommendationsInteractor
+import com.android.systemui.media.controls.util.mediaUiEventLogger
+
+val Kosmos.mediaRecommendationsViewModel by
+    Kosmos.Fixture {
+        MediaRecommendationsViewModel(
+            applicationContext = applicationContext,
+            backgroundDispatcher = testDispatcher,
+            interactor = mediaRecommendationsInteractor,
+            logger = mediaUiEventLogger,
+        )
+    }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/MediaInstanceIdKosmos.kt
similarity index 72%
copy from packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/MediaInstanceIdKosmos.kt
index 0c92b50..923eaa1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/media/controls/util/MediaInstanceIdKosmos.kt
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.notification.stack.shared.model
+package com.android.systemui.media.controls.util
 
-/** Models the clipping rounded rectangle of the notification stack */
-data class StackClipping(val bounds: StackBounds, val rounding: StackRounding)
+import com.android.internal.logging.InstanceId
+import com.android.systemui.kosmos.Kosmos
+
+val Kosmos.mediaInstanceId: InstanceId by Kosmos.Fixture { InstanceId.fakeInstanceId(123) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SceneContainerPluginKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SceneContainerPluginKosmos.kt
index b1027b9..d19dfe8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SceneContainerPluginKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SceneContainerPluginKosmos.kt
@@ -18,6 +18,12 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.scene.domain.interactor.sceneContainerOcclusionInteractor
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 
-val Kosmos.sceneContainerPlugin by Fixture { SceneContainerPlugin { sceneInteractor } }
+val Kosmos.sceneContainerPlugin by Fixture {
+    SceneContainerPlugin(
+        sceneInteractor = { sceneInteractor },
+        occlusionInteractor = { sceneContainerOcclusionInteractor },
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt
similarity index 71%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepositoryKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt
index 4073902..8faeb39 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,11 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.notification.stack.data.repository
+package com.android.systemui.model
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.settings.displayTracker
 
-val Kosmos.notificationStackAppearanceRepository by Fixture {
-    NotificationStackAppearanceRepository()
+val Kosmos.sysUiState by Fixture {
+    SysUiState(
+        displayTracker,
+        sceneContainerPlugin,
+    )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
index 394c873..695e594 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/plugins/statusbar/StatusBarStateControllerKosmos.kt
@@ -24,9 +24,10 @@
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.statusbar.StatusBarStateControllerImpl
+import com.android.systemui.statusbar.SysuiStatusBarStateController
 import com.android.systemui.util.mockito.mock
 
-var Kosmos.statusBarStateController by
+var Kosmos.statusBarStateController: SysuiStatusBarStateController by
     Kosmos.Fixture {
         StatusBarStateControllerImpl(
             uiEventLogger,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt
index 1ce2610..0de76c8 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/QuickSettingsKosmos.kt
@@ -35,7 +35,6 @@
 import com.android.systemui.qs.footer.domain.interactor.FooterActionsInteractorImpl
 import com.android.systemui.qs.footer.foregroundServicesRepository
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
-import com.android.systemui.qs.tiles.di.NewQSTileFactory
 import com.android.systemui.security.data.repository.securityRepository
 import com.android.systemui.settings.userTracker
 import com.android.systemui.statusbar.policy.deviceProvisionedController
@@ -49,7 +48,6 @@
     QsEventLoggerFake(uiEventLoggerFake, instanceIdSequenceFake)
 }
 
-var Kosmos.newQSTileFactory by Fixture<NewQSTileFactory>()
 var Kosmos.qsTileFactory by Fixture<QSFactory>()
 
 val Kosmos.fgsManagerController by Fixture { FakeFgsManagerController() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorKosmos.kt
index 9ef44c4..b870039 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorKosmos.kt
@@ -21,7 +21,6 @@
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.qs.external.customTileStatePersister
 import com.android.systemui.qs.external.tileLifecycleManagerFactory
-import com.android.systemui.qs.newQSTileFactory
 import com.android.systemui.qs.pipeline.data.repository.customTileAddedRepository
 import com.android.systemui.qs.pipeline.data.repository.installedTilesRepository
 import com.android.systemui.qs.pipeline.data.repository.minimumTilesRepository
@@ -29,6 +28,7 @@
 import com.android.systemui.qs.pipeline.shared.logging.qsLogger
 import com.android.systemui.qs.pipeline.shared.pipelineFlagsRepository
 import com.android.systemui.qs.qsTileFactory
+import com.android.systemui.qs.tiles.di.newQSTileFactory
 import com.android.systemui.settings.userTracker
 import com.android.systemui.user.data.repository.userRepository
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeDisabledByPolicyInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeDisabledByPolicyInteractor.kt
index 62765d1..fb6ba20 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeDisabledByPolicyInteractor.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeDisabledByPolicyInteractor.kt
@@ -17,16 +17,21 @@
 package com.android.systemui.qs.tiles.base.interactor
 
 import android.os.UserHandle
+import com.android.settingslib.RestrictedLockUtils
 
 class FakeDisabledByPolicyInteractor : DisabledByPolicyInteractor {
 
-    var policyResult: DisabledByPolicyInteractor.PolicyResult =
-        DisabledByPolicyInteractor.PolicyResult.TileEnabled
-
     override suspend fun isDisabled(
         user: UserHandle,
         userRestriction: String?
-    ): DisabledByPolicyInteractor.PolicyResult = policyResult
+    ): DisabledByPolicyInteractor.PolicyResult =
+        if (userRestriction == DISABLED_RESTRICTION || userRestriction == DISABLED_RESTRICTION_2) {
+            DisabledByPolicyInteractor.PolicyResult.TileDisabled(
+                RestrictedLockUtils.EnforcedAdmin()
+            )
+        } else {
+            DisabledByPolicyInteractor.PolicyResult.TileEnabled
+        }
 
     override fun handlePolicyResult(
         policyResult: DisabledByPolicyInteractor.PolicyResult
@@ -35,4 +40,10 @@
             is DisabledByPolicyInteractor.PolicyResult.TileEnabled -> false
             is DisabledByPolicyInteractor.PolicyResult.TileDisabled -> true
         }
+
+    companion object {
+        const val DISABLED_RESTRICTION = "disabled_restriction"
+        const val DISABLED_RESTRICTION_2 = "disabled_restriction_2"
+        const val ENABLED_RESTRICTION = "test_restriction"
+    }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
new file mode 100644
index 0000000..5c4b390
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
@@ -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.systemui.qs.tiles.di
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.viewmodel.qSTileConfigProvider
+import com.android.systemui.qs.tiles.viewmodel.qsTileViewModelAdaperFactory
+import com.android.systemui.util.mockito.mock
+import javax.inject.Provider
+import org.mockito.Mockito
+
+var Kosmos.newFactoryTileMap by Kosmos.Fixture { emptyMap<String, Provider<QSTileViewModel>>() }
+
+val Kosmos.newQSTileFactory by
+    Kosmos.Fixture {
+        NewQSTileFactory(
+            qSTileConfigProvider,
+            qsTileViewModelAdaperFactory,
+            newFactoryTileMap,
+            mock(Mockito.withSettings().defaultAnswer(Mockito.RETURNS_MOCKS)),
+            mock(Mockito.withSettings().defaultAnswer(Mockito.RETURNS_MOCKS)),
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/sensorprivacy/SensorPrivacyTileKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/sensorprivacy/SensorPrivacyTileKosmos.kt
new file mode 100644
index 0000000..b7e31db
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/sensorprivacy/SensorPrivacyTileKosmos.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.impl.sensorprivacy
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.qsEventLogger
+import com.android.systemui.statusbar.policy.PolicyModule
+
+val Kosmos.qsCameraSensorPrivacyToggleTileConfig by
+    Kosmos.Fixture { PolicyModule.provideCameraToggleTileConfig(qsEventLogger) }
+
+val Kosmos.qsMicrophoneSensorPrivacyToggleTileConfig by
+    Kosmos.Fixture { PolicyModule.provideMicrophoneToggleTileConfig(qsEventLogger) }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderKosmos.kt
similarity index 68%
copy from tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
copy to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderKosmos.kt
index 4e64ab0..1d57979 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderKosmos.kt
@@ -14,15 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.systemui.qs.tiles.viewmodel
 
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
+import com.android.systemui.kosmos.Kosmos
 
-import java.util.List;
-
-public interface AslMarshallable {
-
-    /** Creates the on-device DOM element from the AslMarshallable Java Object. */
-    List<Element> toOdDomElements(Document doc);
-}
+val Kosmos.fakeQSTileConfigProvider by Kosmos.Fixture { FakeQSTileConfigProvider() }
+var Kosmos.qSTileConfigProvider: QSTileConfigProvider by Kosmos.Fixture { fakeQSTileConfigProvider }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt
new file mode 100644
index 0000000..a908765
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs.tiles.viewmodel
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.util.mockito.mock
+
+val Kosmos.qsTileViewModelAdaperFactory by
+    Kosmos.Fixture {
+        object : QSTileViewModelAdapter.Factory {
+            override fun create(qsTileViewModel: QSTileViewModel): QSTileViewModelAdapter {
+                return QSTileViewModelAdapter(
+                    applicationCoroutineScope,
+                    mock(),
+                    qsTileViewModel,
+                )
+            }
+        }
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt
index 4d902fa..df08e4a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/ui/adapter/FakeQSSceneAdapter.kt
@@ -60,4 +60,8 @@
     override suspend fun applyBottomNavBarPadding(padding: Int) {
         _navBarPadding.value = padding
     }
+
+    override fun requestCloseCustomizer() {
+        _customizing.value = false
+    }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractorKosmos.kt
index b32960a..9bd5581 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/scene/domain/interactor/SceneContainerOcclusionInteractorKosmos.kt
@@ -19,10 +19,12 @@
 import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.statusbar.domain.interactor.keyguardOcclusionInteractor
 
 val Kosmos.sceneContainerOcclusionInteractor by Fixture {
     SceneContainerOcclusionInteractor(
+        applicationScope = applicationCoroutineScope,
         keyguardOcclusionInteractor = keyguardOcclusionInteractor,
         sceneInteractor = sceneInteractor,
         keyguardTransitionInteractor = keyguardTransitionInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/settings/DisplayTrackerKosmos.kt
similarity index 72%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepositoryKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/settings/DisplayTrackerKosmos.kt
index 4073902..7ac9680 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/settings/DisplayTrackerKosmos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -14,11 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.notification.stack.data.repository
+package com.android.systemui.settings
 
+import android.content.applicationContext
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 
-val Kosmos.notificationStackAppearanceRepository by Fixture {
-    NotificationStackAppearanceRepository()
+val Kosmos.displayTracker by Fixture {
+    FakeDisplayTracker(
+        context = applicationContext,
+    )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt
index 4a2eaf0..d08855f 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ShadeControllerKosmos.kt
@@ -21,6 +21,7 @@
 import com.android.systemui.assist.AssistManager
 import com.android.systemui.concurrency.fakeExecutor
 import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
+import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.kosmos.testDispatcher
@@ -58,6 +59,7 @@
             statusBarKeyguardViewManager = mock<StatusBarKeyguardViewManager>(),
             notificationShadeWindowController = mock<NotificationShadeWindowController>(),
             assistManagerLazy = { mock<AssistManager>() },
+            deviceUnlockedInteractor = deviceUnlockedInteractor,
         )
     }
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationPlaceholderRepositoryKosmos.kt
similarity index 81%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepositoryKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationPlaceholderRepositoryKosmos.kt
index 4073902..3e54e3d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationPlaceholderRepositoryKosmos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -19,6 +19,4 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 
-val Kosmos.notificationStackAppearanceRepository by Fixture {
-    NotificationStackAppearanceRepository()
-}
+val Kosmos.notificationPlaceholderRepository by Fixture { NotificationPlaceholderRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationViewHeightRepositoryKosmos.kt
similarity index 81%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepositoryKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationViewHeightRepositoryKosmos.kt
index 4073902..6c16c2c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationStackAppearanceRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationViewHeightRepositoryKosmos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * 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.
@@ -19,6 +19,4 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 
-val Kosmos.notificationStackAppearanceRepository by Fixture {
-    NotificationStackAppearanceRepository()
-}
+val Kosmos.notificationViewHeightRepository by Fixture { NotificationViewHeightRepository() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorKosmos.kt
index 5605d10..dbfd9de 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationStackAppearanceInteractorKosmos.kt
@@ -19,11 +19,13 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.shade.domain.interactor.shadeInteractor
-import com.android.systemui.statusbar.notification.stack.data.repository.notificationStackAppearanceRepository
+import com.android.systemui.statusbar.notification.stack.data.repository.notificationPlaceholderRepository
+import com.android.systemui.statusbar.notification.stack.data.repository.notificationViewHeightRepository
 
 val Kosmos.notificationStackAppearanceInteractor by Fixture {
     NotificationStackAppearanceInteractor(
-        repository = notificationStackAppearanceRepository,
+        viewHeightRepository = notificationViewHeightRepository,
+        placeholderRepository = notificationPlaceholderRepository,
         shadeInteractor = shadeInteractor,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationStackAppearanceViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModelKosmos.kt
similarity index 85%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationStackAppearanceViewModelKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModelKosmos.kt
index 7e63eaa..10cc136 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationStackAppearanceViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModelKosmos.kt
@@ -19,14 +19,12 @@
 import com.android.systemui.dump.dumpManager
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.scene.domain.interactor.sceneInteractor
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
 
-val Kosmos.notificationStackAppearanceViewModel by Fixture {
-    NotificationStackAppearanceViewModel(
-        applicationScope = applicationCoroutineScope,
+val Kosmos.notificationScrollViewModel by Fixture {
+    NotificationScrollViewModel(
         dumpManager = dumpManager,
         stackAppearanceInteractor = notificationStackAppearanceInteractor,
         shadeInteractor = shadeInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
index 29faa58..b249211 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationsPlaceholderViewModelKosmos.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification.stack.ui.viewmodel
 
+import com.android.systemui.dump.dumpManager
 import com.android.systemui.flags.featureFlagsClassic
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.kosmos.Kosmos
@@ -26,6 +27,7 @@
 
 val Kosmos.notificationsPlaceholderViewModel by Fixture {
     NotificationsPlaceholderViewModel(
+        dumpManager = dumpManager,
         interactor = notificationStackAppearanceInteractor,
         shadeInteractor = shadeInteractor,
         flags = sceneContainerFlags,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
index de0cc65..d2de835 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelKosmos.kt
@@ -43,6 +43,7 @@
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.shade.domain.interactor.shadeInteractor
+import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 
@@ -55,6 +56,7 @@
         keyguardInteractor = keyguardInteractor,
         keyguardTransitionInteractor = keyguardTransitionInteractor,
         shadeInteractor = shadeInteractor,
+        notificationStackAppearanceInteractor = notificationStackAppearanceInteractor,
         alternateBouncerToGoneTransitionViewModel = alternateBouncerToGoneTransitionViewModel,
         aodToLockscreenTransitionViewModel = aodToLockscreenTransitionViewModel,
         aodToOccludedTransitionViewModel = aodToOccludedTransitionViewModel,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/unfold/FullscreenLightRevealAnimationKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/unfold/FullscreenLightRevealAnimationKosmos.kt
new file mode 100644
index 0000000..43d6c48
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/unfold/FullscreenLightRevealAnimationKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.unfold
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.Kosmos.Fixture
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+
+var Kosmos.fullscreenLightRevealAnimationController by Fixture {
+    mock<FullscreenLightRevealAnimationController>()
+}
+var Kosmos.fullscreenLightRevealAnimationControllerFactory by Fixture {
+    var mockControllerFactory = mock<FullscreenLightRevealAnimationController.Factory>()
+    whenever(mockControllerFactory.create(any(), any(), any()))
+        .thenReturn(fullscreenLightRevealAnimationController)
+    mockControllerFactory
+}
diff --git a/packages/VpnDialogs/res/values-af/strings.xml b/packages/VpnDialogs/res/values-af/strings.xml
index db3c355..83c9717 100644
--- a/packages/VpnDialogs/res/values-af/strings.xml
+++ b/packages/VpnDialogs/res/values-af/strings.xml
@@ -32,7 +32,7 @@
     <string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Verander VPN-instellings"</string>
     <string name="configure" msgid="4905518375574791375">"Stel op"</string>
     <string name="disconnect" msgid="971412338304200056">"Ontkoppel"</string>
-    <string name="open_app" msgid="3717639178595958667">"Maak program oop"</string>
+    <string name="open_app" msgid="3717639178595958667">"Maak app oop"</string>
     <string name="dismiss" msgid="6192859333764711227">"Maak toe"</string>
     <string name="sanitized_vpn_label_with_ellipsis" msgid="7014327474633422235">"<xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_0">%1$s</xliff:g> … ( <xliff:g id="SANITIZED_VPN_LABEL_WITH_ELLIPSIS_1">%2$s</xliff:g>)"</string>
     <string name="sanitized_vpn_label" msgid="1877415015009794766">"<xliff:g id="SANITIZED_VPN_LABEL_0">%1$s</xliff:g> ( <xliff:g id="SANITIZED_VPN_LABEL_1">%2$s</xliff:g>)"</string>
diff --git a/packages/VpnDialogs/res/values-de/strings.xml b/packages/VpnDialogs/res/values-de/strings.xml
index 7397ddb..062f61c 100644
--- a/packages/VpnDialogs/res/values-de/strings.xml
+++ b/packages/VpnDialogs/res/values-de/strings.xml
@@ -17,7 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="prompt" msgid="3183836924226407828">"Verbindungsanfrage"</string>
-    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> möchte eine VPN-Verbindung herstellen, über die der Netzwerkverkehr überwacht werden kann. Lass die Verbindung nur zu, wenn die App vertrauenswürdig ist. &lt;br /&gt; &lt;br /&gt; Wenn das VPN aktiv ist, wird oben im Display &lt;img src=vpn_icon /&gt; angezeigt."</string>
+    <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> möchte eine VPN-Verbindung herstellen, über die der Netzwerkverkehr überwacht werden kann. Lass die Verbindung nur zu, wenn die App vertrauenswürdig ist. &lt;br /&gt; &lt;br /&gt; Wenn das VPN aktiv ist, wird oben auf dem Display das Symbol „&lt;img src=vpn_icon /&gt;“ angezeigt."</string>
     <string name="warning" product="tv" msgid="5188957997628124947">"<xliff:g id="APP">%s</xliff:g> möchte eine VPN-Verbindung herstellen, über die der Netzwerkverkehr überwacht werden kann. Lass die Verbindung nur zu, wenn die App vertrauenswürdig ist. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; wird auf dem Display angezeigt, wenn VPN aktiv ist."</string>
     <string name="legacy_title" msgid="192936250066580964">"VPN ist verbunden"</string>
     <string name="session" msgid="6470628549473641030">"Sitzung:"</string>
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index f4337d4..8905ad3 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -151,7 +151,7 @@
 
 filegroup {
     name: "ravenwood-services-jarjar-rules",
-    srcs: ["ravenwood-services-jarjar-rules.txt"],
+    srcs: ["texts/ravenwood-services-jarjar-rules.txt"],
     visibility: ["//frameworks/base"],
 }
 
@@ -159,7 +159,7 @@
 // The "test" just shows the available stats filenames.
 sh_test_host {
     name: "ravenwood-stats-checker",
-    src: "ravenwood-stats-checker.sh",
+    src: "scripts/ravenwood-stats-checker.sh",
     test_suites: ["general-tests"],
     data: [
         ":framework-minus-apex.ravenwood.stats",
diff --git a/ravenwood/ravenwood-stats-checker.sh b/ravenwood/ravenwood-stats-checker.sh
deleted file mode 100755
index fb58e72..0000000
--- a/ravenwood/ravenwood-stats-checker.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-# Just print the available *.csv filenames.
-echo '#Stats files:'
-ls *.csv
\ No newline at end of file
diff --git a/ravenwood/bulk_enable.py b/ravenwood/scripts/bulk_enable.py
similarity index 100%
rename from ravenwood/bulk_enable.py
rename to ravenwood/scripts/bulk_enable.py
diff --git a/ravenwood/fix_test_runner.py b/ravenwood/scripts/fix_test_runner.py
similarity index 100%
rename from ravenwood/fix_test_runner.py
rename to ravenwood/scripts/fix_test_runner.py
diff --git a/ravenwood/list-ravenwood-tests.sh b/ravenwood/scripts/list-ravenwood-tests.sh
similarity index 100%
rename from ravenwood/list-ravenwood-tests.sh
rename to ravenwood/scripts/list-ravenwood-tests.sh
diff --git a/Android.mk b/ravenwood/scripts/ravenwood-stats-checker.sh
old mode 100644
new mode 100755
similarity index 65%
rename from Android.mk
rename to ravenwood/scripts/ravenwood-stats-checker.sh
index a126c52..93f4a3f
--- a/Android.mk
+++ b/ravenwood/scripts/ravenwood-stats-checker.sh
@@ -1,5 +1,5 @@
-#
-# Copyright (C) 2008 The Android Open Source Project
+#!/bin/bash
+# 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.
@@ -12,9 +12,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
 
-# TODO: Empty this file after all subdirectories' Android.mk have been
-#       converted to Android.bp to avoid using any newly added Android.mk.
-include $(call first-makefiles-under,$(LOCAL_PATH))
+# Just print the available *.csv filenames.
+echo '#Stats files:'
+ls *.csv
\ No newline at end of file
diff --git a/ravenwood/scripts/ravenwood-stats-collector.sh b/ravenwood/scripts/ravenwood-stats-collector.sh
new file mode 100755
index 0000000..4dcaa2b
--- /dev/null
+++ b/ravenwood/scripts/ravenwood-stats-collector.sh
@@ -0,0 +1,52 @@
+#!/bin/bash
+# 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.
+
+# Script to collect the ravenwood "stats" CVS files and create a single file.
+
+set -e
+
+# Output file
+out=/tmp/ravenwood-stats-all.csv
+
+# Where the input files are.
+path=$ANDROID_BUILD_TOP/out/host/linux-x86/testcases/ravenwood-stats-checker/x86_64/
+
+m() {
+    ${ANDROID_BUILD_TOP}/build/soong/soong_ui.bash --make-mode "$@"
+}
+
+# Building this will generate the files we need.
+m ravenwood-stats-checker
+
+# Start...
+
+cd $path
+
+dump() {
+    local jar=$1
+    local file=$2
+
+    sed -e '1d' -e "s/^/$jar,/"  $file
+}
+
+collect() {
+    echo 'Jar,PackageName,ClassName,SupportedMethods,TotalMethods'
+    dump "framework-minus-apex"  hoststubgen_framework-minus-apex_stats.csv
+    dump "service.core"  hoststubgen_services.core_stats.csv
+}
+
+collect >$out
+
+echo "Full dump CVS created at $out"
diff --git a/ravenwood/run-ravenwood-tests.sh b/ravenwood/scripts/run-ravenwood-tests.sh
similarity index 95%
rename from ravenwood/run-ravenwood-tests.sh
rename to ravenwood/scripts/run-ravenwood-tests.sh
index a303626..926c08f 100755
--- a/ravenwood/run-ravenwood-tests.sh
+++ b/ravenwood/scripts/run-ravenwood-tests.sh
@@ -15,7 +15,7 @@
 
 # Run all the ravenwood tests + hoststubgen unit tests.
 
-all_tests="hoststubgentest tiny-framework-dump-test hoststubgen-invoke-test"
+all_tests="hoststubgentest tiny-framework-dump-test hoststubgen-invoke-test ravenwood-stats-checker"
 
 # "echo" is to remove the newlines
 all_tests="$all_tests $(echo $(${0%/*}/list-ravenwood-tests.sh) )"
diff --git a/ravenwood/framework-minus-apex-ravenwood-policies.txt b/ravenwood/texts/framework-minus-apex-ravenwood-policies.txt
similarity index 100%
rename from ravenwood/framework-minus-apex-ravenwood-policies.txt
rename to ravenwood/texts/framework-minus-apex-ravenwood-policies.txt
diff --git a/ravenwood/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
similarity index 100%
rename from ravenwood/ravenwood-annotation-allowed-classes.txt
rename to ravenwood/texts/ravenwood-annotation-allowed-classes.txt
diff --git a/ravenwood/ravenwood-services-jarjar-rules.txt b/ravenwood/texts/ravenwood-services-jarjar-rules.txt
similarity index 100%
rename from ravenwood/ravenwood-services-jarjar-rules.txt
rename to ravenwood/texts/ravenwood-services-jarjar-rules.txt
diff --git a/ravenwood/ravenwood-standard-options.txt b/ravenwood/texts/ravenwood-standard-options.txt
similarity index 100%
rename from ravenwood/ravenwood-standard-options.txt
rename to ravenwood/texts/ravenwood-standard-options.txt
diff --git a/ravenwood/services.core-ravenwood-policies.txt b/ravenwood/texts/services.core-ravenwood-policies.txt
similarity index 100%
rename from ravenwood/services.core-ravenwood-policies.txt
rename to ravenwood/texts/services.core-ravenwood-policies.txt
diff --git a/services/Android.bp b/services/Android.bp
index 7bbb42e..881d6e1 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -254,6 +254,7 @@
     required: [
         "libukey2_jni_shared",
         "protolog.conf.json.gz",
+        "core.protolog.pb",
     ],
     lint: {
         baseline_filename: "lint-baseline.xml",
@@ -285,6 +286,11 @@
 // API stub
 // =============================================================
 
+soong_config_module_type_import {
+    from: "frameworks/base/api/Android.bp",
+    module_types: ["non_updatable_exportable_droidstubs"],
+}
+
 stubs_defaults {
     name: "services-stubs-default",
     installable: false,
@@ -300,10 +306,12 @@
     filter_packages: ["com.android."],
 }
 
-droidstubs {
+non_updatable_exportable_droidstubs {
     name: "services-non-updatable-stubs",
     srcs: [":services-non-updatable-sources"],
-    defaults: ["services-stubs-default"],
+    defaults: [
+        "services-stubs-default",
+    ],
     check_api: {
         current: {
             api_file: "api/current.txt",
@@ -320,14 +328,34 @@
             targets: ["sdk"],
             dir: "apistubs/android/system-server/api",
             dest: "android-non-updatable.txt",
-            tag: ".api.txt",
         },
         {
             targets: ["sdk"],
             dir: "apistubs/android/system-server/api",
             dest: "android-non-updatable-removed.txt",
-            tag: ".removed-api.txt",
         },
     ],
+    soong_config_variables: {
+        release_hidden_api_exportable_stubs: {
+            dists: [
+                {
+                    tag: ".exportable.api.txt",
+                },
+                {
+                    tag: ".exportable.removed-api.txt",
+                },
+            ],
+            conditions_default: {
+                dists: [
+                    {
+                        tag: ".api.txt",
+                    },
+                    {
+                        tag: ".removed-api.txt",
+                    },
+                ],
+            },
+        },
+    },
     api_surface: "system-server",
 }
diff --git a/services/accessibility/Android.bp b/services/accessibility/Android.bp
index 69cc68a..7a99b60 100644
--- a/services/accessibility/Android.bp
+++ b/services/accessibility/Android.bp
@@ -34,6 +34,8 @@
     ],
     static_libs: [
         "com_android_server_accessibility_flags_lib",
+        "//frameworks/base/packages/SystemUI/aconfig:com_android_systemui_flags_lib",
+
     ],
 }
 
@@ -56,6 +58,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 04b19ff..1d6399e 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/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 9403796..0811c87 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -31,16 +31,14 @@
 import static android.companion.virtual.VirtualDeviceManager.EXTRA_VIRTUAL_DEVICE_ID;
 import static android.content.Context.DEVICE_ID_DEFAULT;
 import static android.provider.Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
 import static android.view.accessibility.AccessibilityManager.FlashNotificationReason;
-import static android.view.accessibility.AccessibilityManager.ShortcutType;
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
 import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
 import static com.android.internal.accessibility.common.ShortcutConstants.USER_SHORTCUT_TYPES;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 import static com.android.internal.accessibility.util.AccessibilityStatsLogUtils.logAccessibilityShortcutActivated;
 import static com.android.internal.util.FunctionalUtils.ignoreRemoteException;
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
@@ -149,7 +147,6 @@
 import com.android.internal.accessibility.AccessibilityShortcutController.LaunchableFrameworkFeatureInfo;
 import com.android.internal.accessibility.common.ShortcutConstants;
 import com.android.internal.accessibility.common.ShortcutConstants.FloatingMenuSize;
-import com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity;
 import com.android.internal.accessibility.dialog.AccessibilityShortcutChooserActivity;
 import com.android.internal.accessibility.util.AccessibilityUtils;
@@ -243,6 +240,13 @@
     private static final String SET_PIP_ACTION_REPLACEMENT =
             "setPictureInPictureActionReplacingConnection";
 
+    /**
+     * An intent action to launch Hearing devices dialog.
+     */
+    @VisibleForTesting
+    static final String ACTION_LAUNCH_HEARING_DEVICES_DIALOG =
+            "com.android.systemui.action.LAUNCH_HEARING_DEVICES_DIALOG";
+
     private static final char COMPONENT_NAME_SEPARATOR = ':';
 
     private static final int OWN_PROCESS_ID = android.os.Process.myPid();
@@ -1679,7 +1683,7 @@
         }
         mMainHandler.sendMessage(obtainMessage(
                 AccessibilityManagerService::performAccessibilityShortcutInternal, this,
-                displayId, ACCESSIBILITY_BUTTON, targetName));
+                displayId, UserShortcutType.SOFTWARE, targetName));
     }
 
     /**
@@ -2276,9 +2280,9 @@
     }
 
     private void showAccessibilityTargetsSelection(int displayId,
-            @ShortcutType int shortcutType) {
+            @UserShortcutType int shortcutType) {
         final Intent intent = new Intent(AccessibilityManager.ACTION_CHOOSE_ACCESSIBILITY_BUTTON);
-        final String chooserClassName = (shortcutType == ACCESSIBILITY_SHORTCUT_KEY)
+        final String chooserClassName = (shortcutType == UserShortcutType.HARDWARE)
                 ? AccessibilityShortcutChooserActivity.class.getName()
                 : AccessibilityButtonChooserActivity.class.getName();
         intent.setClassName(CHOOSER_PACKAGE_NAME, chooserClassName);
@@ -2311,6 +2315,14 @@
         }
     }
 
+    private void launchHearingDevicesDialog() {
+        final Intent intent = new Intent(ACTION_LAUNCH_HEARING_DEVICES_DIALOG);
+        intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        intent.setPackage(
+                mContext.getString(com.android.internal.R.string.config_systemUi));
+        mContext.sendBroadcastAsUser(intent, UserHandle.SYSTEM);
+    }
+
     private void notifyAccessibilityButtonVisibilityChangedLocked(boolean available) {
         final AccessibilityUserState state = getCurrentUserStateLocked();
         mIsAccessibilityButtonShown = available;
@@ -3363,7 +3375,7 @@
         }
 
         final Set<String> currentTargets =
-                userState.getShortcutTargetsLocked(ACCESSIBILITY_SHORTCUT_KEY);
+                userState.getShortcutTargetsLocked(UserShortcutType.HARDWARE);
         if (targetsFromSetting.equals(currentTargets)) {
             return false;
         }
@@ -3394,7 +3406,7 @@
                 userState.mUserId, str -> str, targetsFromSetting);
 
         final Set<String> currentTargets =
-                userState.getShortcutTargetsLocked(ACCESSIBILITY_BUTTON);
+                userState.getShortcutTargetsLocked(UserShortcutType.SOFTWARE);
         if (targetsFromSetting.equals(currentTargets)) {
             return false;
         }
@@ -3449,7 +3461,7 @@
      */
     private void updateAccessibilityShortcutKeyTargetsLocked(AccessibilityUserState userState) {
         final Set<String> currentTargets =
-                userState.getShortcutTargetsLocked(ACCESSIBILITY_SHORTCUT_KEY);
+                userState.getShortcutTargetsLocked(UserShortcutType.HARDWARE);
         final int lastSize = currentTargets.size();
         if (lastSize == 0) {
             return;
@@ -3641,7 +3653,7 @@
         }
 
         final Set<String> currentTargets =
-                userState.getShortcutTargetsLocked(ACCESSIBILITY_BUTTON);
+                userState.getShortcutTargetsLocked(UserShortcutType.SOFTWARE);
         final int lastSize = currentTargets.size();
         if (lastSize == 0) {
             return;
@@ -3681,7 +3693,7 @@
             return;
         }
         final Set<String> buttonTargets =
-                userState.getShortcutTargetsLocked(ACCESSIBILITY_BUTTON);
+                userState.getShortcutTargetsLocked(UserShortcutType.SOFTWARE);
         int lastSize = buttonTargets.size();
         buttonTargets.removeIf(name -> {
             if (packageName != null && name != null && !name.contains(packageName)) {
@@ -3718,7 +3730,7 @@
         lastSize = buttonTargets.size();
 
         final Set<String> shortcutKeyTargets =
-                userState.getShortcutTargetsLocked(ACCESSIBILITY_SHORTCUT_KEY);
+                userState.getShortcutTargetsLocked(UserShortcutType.HARDWARE);
         final Set<String> qsShortcutTargets =
                 userState.getShortcutTargetsLocked(UserShortcutType.QUICK_SETTINGS);
         userState.mEnabledServices.forEach(componentName -> {
@@ -3824,10 +3836,10 @@
 
         final List<Pair<Integer, String>> shortcutTypeAndShortcutSetting = new ArrayList<>(3);
         shortcutTypeAndShortcutSetting.add(
-                new Pair<>(ACCESSIBILITY_SHORTCUT_KEY,
+                new Pair<>(UserShortcutType.HARDWARE,
                         Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE));
         shortcutTypeAndShortcutSetting.add(
-                new Pair<>(ACCESSIBILITY_BUTTON,
+                new Pair<>(UserShortcutType.SOFTWARE,
                         Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS));
         if (android.view.accessibility.Flags.a11yQsShortcut()) {
             shortcutTypeAndShortcutSetting.add(
@@ -3934,7 +3946,7 @@
         }
         mMainHandler.sendMessage(obtainMessage(
                 AccessibilityManagerService::performAccessibilityShortcutInternal, this,
-                Display.DEFAULT_DISPLAY, ACCESSIBILITY_SHORTCUT_KEY, targetName));
+                Display.DEFAULT_DISPLAY, UserShortcutType.HARDWARE, targetName));
     }
 
     /**
@@ -3947,7 +3959,7 @@
      *        specified target.
      */
     private void performAccessibilityShortcutInternal(int displayId,
-            @ShortcutType int shortcutType, @Nullable String targetName) {
+            @UserShortcutType int shortcutType, @Nullable String targetName) {
         final List<String> shortcutTargets = getAccessibilityShortcutTargetsInternal(shortcutType);
         if (shortcutTargets.isEmpty()) {
             Slog.d(LOG_TAG, "No target to perform shortcut, shortcutType=" + shortcutType);
@@ -3998,7 +4010,7 @@
     }
 
     private boolean performAccessibilityFrameworkFeature(int displayId,
-            ComponentName assignedTarget, @ShortcutType int shortcutType) {
+            ComponentName assignedTarget, @UserShortcutType int shortcutType) {
         final Map<ComponentName, FrameworkFeatureInfo> frameworkFeatureMap =
                 AccessibilityShortcutController.getFrameworkShortcutFeaturesMap();
         if (!frameworkFeatureMap.containsKey(assignedTarget)) {
@@ -4047,12 +4059,12 @@
     /**
      * Perform accessibility service shortcut action.
      *
-     * 1) For {@link AccessibilityManager#ACCESSIBILITY_BUTTON} type and services targeting sdk
+     * 1) For {@link UserShortcutType#SOFTWARE} type and services targeting sdk
      *    version <= Q: callbacks to accessibility service if service is bounded and requests
      *    accessibility button.
-     * 2) For {@link AccessibilityManager#ACCESSIBILITY_SHORTCUT_KEY} type and service targeting sdk
+     * 2) For {@link UserShortcutType#HARDWARE} type and service targeting sdk
      *    version <= Q: turns on / off the accessibility service.
-     * 3) For {@link AccessibilityManager#ACCESSIBILITY_SHORTCUT_KEY} type and service targeting sdk
+     * 3) For {@link UserShortcutType#HARDWARE} type and service targeting sdk
      *    version > Q and request accessibility button: turn on the accessibility service if it's
      *    not in the enabled state.
      *    (It'll happen when a service is disabled and assigned to shortcut then upgraded.)
@@ -4063,7 +4075,7 @@
      *       button.
      */
     private boolean performAccessibilityShortcutTargetService(int displayId,
-            @ShortcutType int shortcutType, ComponentName assignedTarget) {
+            @UserShortcutType int shortcutType, ComponentName assignedTarget) {
         synchronized (mLock) {
             final AccessibilityUserState userState = getCurrentUserStateLocked();
             final AccessibilityServiceInfo installedServiceInfo =
@@ -4081,7 +4093,7 @@
             final boolean requestA11yButton = (installedServiceInfo.flags
                     & FLAG_REQUEST_ACCESSIBILITY_BUTTON) != 0;
             // Turns on / off the accessibility service
-            if ((targetSdk <= Build.VERSION_CODES.Q && shortcutType == ACCESSIBILITY_SHORTCUT_KEY)
+            if ((targetSdk <= Build.VERSION_CODES.Q && shortcutType == UserShortcutType.HARDWARE)
                     || (targetSdk > Build.VERSION_CODES.Q && !requestA11yButton)) {
                 if (serviceConnection == null) {
                     logAccessibilityShortcutActivated(mContext, assignedTarget, shortcutType,
@@ -4095,7 +4107,7 @@
                 }
                 return true;
             }
-            if (shortcutType == ACCESSIBILITY_SHORTCUT_KEY && targetSdk > Build.VERSION_CODES.Q
+            if (shortcutType == UserShortcutType.HARDWARE && targetSdk > Build.VERSION_CODES.Q
                     && requestA11yButton) {
                 if (!userState.getEnabledServicesLocked().contains(assignedTarget)) {
                     enableAccessibilityServiceLocked(assignedTarget, mCurrentUserId);
@@ -4120,7 +4132,13 @@
 
     private void launchAccessibilityFrameworkFeature(int displayId, ComponentName assignedTarget) {
         if (assignedTarget.equals(ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME)) {
-            launchAccessibilitySubSettings(displayId, ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME);
+            //import com.android.systemui.Flags;
+            if (com.android.systemui.Flags.hearingAidsQsTileDialog()) {
+                launchHearingDevicesDialog();
+            } else {
+                launchAccessibilitySubSettings(displayId,
+                        ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME);
+            }
         }
     }
 
@@ -4383,7 +4401,7 @@
     }
 
     @Override
-    public List<String> getAccessibilityShortcutTargets(@ShortcutType int shortcutType) {
+    public List<String> getAccessibilityShortcutTargets(@UserShortcutType int shortcutType) {
         if (mTraceManager.isA11yTracingEnabledForTypes(FLAGS_ACCESSIBILITY_MANAGER)) {
             mTraceManager.logTrace(LOG_TAG + ".getAccessibilityShortcutTargets",
                     FLAGS_ACCESSIBILITY_MANAGER, "shortcutType=" + shortcutType);
@@ -4397,12 +4415,13 @@
         return getAccessibilityShortcutTargetsInternal(shortcutType);
     }
 
-    private List<String> getAccessibilityShortcutTargetsInternal(@ShortcutType int shortcutType) {
+    private List<String> getAccessibilityShortcutTargetsInternal(
+            @UserShortcutType int shortcutType) {
         synchronized (mLock) {
             final AccessibilityUserState userState = getCurrentUserStateLocked();
             final ArrayList<String> shortcutTargets = new ArrayList<>(
                     userState.getShortcutTargetsLocked(shortcutType));
-            if (shortcutType != ACCESSIBILITY_BUTTON) {
+            if (shortcutType != UserShortcutType.SOFTWARE) {
                 return shortcutTargets;
             }
             // Adds legacy a11y services requesting a11y button into the list.
@@ -4895,7 +4914,7 @@
             }
         }
         // Warning is not required if the service is already assigned to a shortcut.
-        for (int shortcutType : AccessibilityManager.SHORTCUT_TYPES) {
+        for (int shortcutType : ShortcutConstants.USER_SHORTCUT_TYPES) {
             if (getAccessibilityShortcutTargets(shortcutType).contains(
                     componentName.flattenToString())) {
                 return false;
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
index 7008e8e..a37a184 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityUserState.java
@@ -24,11 +24,9 @@
 import static android.accessibilityservice.AccessibilityService.SHOW_MODE_MASK;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
 import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_NONE;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
-import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
-import static android.view.accessibility.AccessibilityManager.ShortcutType;
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
+import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType;
 
 import android.accessibilityservice.AccessibilityService.SoftKeyboardShowMode;
 import android.accessibilityservice.AccessibilityServiceInfo;
@@ -53,7 +51,6 @@
 
 import com.android.internal.R;
 import com.android.internal.accessibility.AccessibilityShortcutController;
-import com.android.internal.accessibility.common.ShortcutConstants;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -779,15 +776,22 @@
      * @param shortcutType The shortcut type.
      * @return The array set of the strings
      */
-    public ArraySet<String> getShortcutTargetsLocked(@ShortcutType int shortcutType) {
-        if (shortcutType == ACCESSIBILITY_SHORTCUT_KEY) {
+    public ArraySet<String> getShortcutTargetsLocked(@UserShortcutType int shortcutType) {
+        if (shortcutType == UserShortcutType.HARDWARE) {
             return mAccessibilityShortcutKeyTargets;
-        } else if (shortcutType == ACCESSIBILITY_BUTTON) {
+        } else if (shortcutType == UserShortcutType.SOFTWARE) {
             return mAccessibilityButtonTargets;
-        } else if (shortcutType == ShortcutConstants.UserShortcutType.QUICK_SETTINGS) {
+        } else if (shortcutType == UserShortcutType.QUICK_SETTINGS) {
             return getA11yQsTargets();
+        } else if ((shortcutType == UserShortcutType.TRIPLETAP
+                && isMagnificationSingleFingerTripleTapEnabledLocked()) || (
+                shortcutType == UserShortcutType.TWOFINGER_DOUBLETAP
+                        && isMagnificationTwoFingerTripleTapEnabledLocked())) {
+            ArraySet<String> targets = new ArraySet<>();
+            targets.add(MAGNIFICATION_CONTROLLER_NAME);
+            return targets;
         }
-        return null;
+        return new ArraySet<>();
     }
 
     /**
@@ -830,8 +834,16 @@
      * @param target The component name of the shortcut target.
      * @return true if the shortcut target is removed.
      */
-    public boolean removeShortcutTargetLocked(@ShortcutType int shortcutType,
-            ComponentName target) {
+    public boolean removeShortcutTargetLocked(
+            @UserShortcutType int shortcutType, ComponentName target) {
+        if (shortcutType == UserShortcutType.TRIPLETAP
+                || shortcutType == UserShortcutType.TWOFINGER_DOUBLETAP) {
+            throw new UnsupportedOperationException(
+                    "removeShortcutTargetLocked only support shortcut type: "
+                            + "software and hardware and quick settings for now"
+            );
+        }
+
         Set<String> targets = getShortcutTargetsLocked(shortcutType);
         boolean result = targets.removeIf(name -> {
             ComponentName componentName;
@@ -841,7 +853,7 @@
             }
             return componentName.equals(target);
         });
-        if (shortcutType == ShortcutConstants.UserShortcutType.QUICK_SETTINGS) {
+        if (shortcutType == UserShortcutType.QUICK_SETTINGS) {
             updateA11yQsTargetLocked(targets);
         }
 
diff --git a/services/autofill/bugfixes.aconfig b/services/autofill/bugfixes.aconfig
index ced10fb..0a3906a 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 c130cee..1dc3b73 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/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index fef3216..9701292 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -79,6 +79,7 @@
 import android.view.autofill.IAutoFillManager;
 import android.view.autofill.IAutoFillManagerClient;
 
+import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.infra.AbstractRemoteService;
@@ -159,6 +160,7 @@
     final FrameworkResourcesServiceNameResolver mFieldClassificationResolver;
 
     private final AutoFillUI mUi;
+    final ComponentName mCredentialAutofillService;
 
     private final LocalLog mRequestsHistory = new LocalLog(20);
     private final LocalLog mUiLatencyHistory = new LocalLog(20);
@@ -288,6 +290,16 @@
                         mAugmentedAutofillResolver.isTemporary(userId));
             }
         }
+        String credentialManagerAutofillCompName = context.getResources().getString(
+                R.string.config_defaultCredentialManagerAutofillService);
+        if (credentialManagerAutofillCompName != null
+                && !credentialManagerAutofillCompName.isEmpty()) {
+            mCredentialAutofillService = ComponentName.unflattenFromString(
+                    credentialManagerAutofillCompName);
+        } else {
+            mCredentialAutofillService = null;
+            Slog.w(TAG, "Invalid CredentialAutofillService");
+        }
     }
 
     @Override // from AbstractMasterSystemService
@@ -417,7 +429,6 @@
         } finally {
             Binder.restoreCallingIdentity(token);
         }
-
         return managerService;
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 272d63d..6822229 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -1291,7 +1291,8 @@
         RemoteFillService remoteService =
                 new RemoteFillService(
                         getContext(), mInfo.getServiceInfo().getComponentName(), mUserId,
-                        /* callbacks= */ null, mMaster.isInstantServiceAllowed());
+                        /* callbacks= */ null, mMaster.isInstantServiceAllowed(),
+                        mMaster.mCredentialAutofillService);
         remoteService.onSavedPasswordCountRequest(receiver);
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index f914ed5..c96688c 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -62,10 +62,6 @@
     private static final long TIMEOUT_IDLE_BIND_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
     private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
 
-    private static final ComponentName CREDMAN_SERVICE_COMPONENT_NAME =
-            new ComponentName("com.android.credentialmanager",
-                    "com.android.credentialmanager.autofill.CredentialAutofillService");
-
     private final FillServiceCallbacks mCallbacks;
     private final Object mLock = new Object();
     private CompletableFuture<FillResponse> mPendingFillRequest;
@@ -102,14 +98,15 @@
     }
 
     RemoteFillService(Context context, ComponentName componentName, int userId,
-            FillServiceCallbacks callbacks, boolean bindInstantServiceAllowed) {
+            FillServiceCallbacks callbacks, boolean bindInstantServiceAllowed,
+            @Nullable ComponentName credentialAutofillService) {
         super(context, new Intent(AutofillService.SERVICE_INTERFACE).setComponent(componentName),
                 Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS
                         | (bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0),
                 userId, IAutoFillService.Stub::asInterface);
         mCallbacks = callbacks;
         mComponentName = componentName;
-        mIsCredentialAutofillService = mComponentName.equals(CREDMAN_SERVICE_COMPONENT_NAME);
+        mIsCredentialAutofillService = mComponentName.equals(credentialAutofillService);
     }
 
     @Override // from ServiceConnector.Impl
diff --git a/services/autofill/java/com/android/server/autofill/SecondaryProviderHandler.java b/services/autofill/java/com/android/server/autofill/SecondaryProviderHandler.java
index 0af703e..4506779 100644
--- a/services/autofill/java/com/android/server/autofill/SecondaryProviderHandler.java
+++ b/services/autofill/java/com/android/server/autofill/SecondaryProviderHandler.java
@@ -59,9 +59,10 @@
 
     SecondaryProviderHandler(
             @NonNull Context context, int userId, boolean bindInstantServiceAllowed,
-            SecondaryProviderCallback callback, ComponentName componentName) {
+            SecondaryProviderCallback callback, ComponentName componentName,
+            @Nullable ComponentName credentialAutofillService) {
         mRemoteFillService = new RemoteFillService(context, componentName, userId, this,
-                bindInstantServiceAllowed);
+                bindInstantServiceAllowed, credentialAutofillService);
         mCallback = callback;
         Slog.v(TAG, "Creating a secondary provider handler with component name, " + componentName);
     }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 558e07f..0b68f5f 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -244,10 +244,6 @@
     private static final int DEFAULT__FILL_REQUEST_ID_SNAPSHOT = -2;
     private static final int DEFAULT__FIELD_CLASSIFICATION_REQUEST_ID_SNAPSHOT = -2;
 
-    private static final ComponentName CREDMAN_SERVICE_COMPONENT_NAME =
-            new ComponentName("com.android.credentialmanager",
-                    "com.android.credentialmanager.autofill.CredentialAutofillService");
-
     static final String SESSION_ID_KEY = "autofill_session_id";
     static final String REQUEST_ID_KEY = "autofill_request_id";
 
@@ -524,6 +520,9 @@
 
     private final ClassificationState mClassificationState = new ClassificationState();
 
+    @Nullable
+    private final ComponentName mCredentialAutofillService;
+
     // TODO(b/216576510): Share one BroadcastReceiver between all Sessions instead of creating a
     // new one per Session.
     private final BroadcastReceiver mDelayedFillBroadcastReceiver =
@@ -1481,23 +1480,26 @@
         mUi = ui;
         mHandler = handler;
 
+        mCredentialAutofillService = getCredentialAutofillService(context);
+
         ComponentName primaryServiceComponentName, secondaryServiceComponentName;
         if (isPrimaryCredential) {
-            primaryServiceComponentName = CREDMAN_SERVICE_COMPONENT_NAME;
+            primaryServiceComponentName = mCredentialAutofillService;
             secondaryServiceComponentName = serviceComponentName;
         } else {
             primaryServiceComponentName = serviceComponentName;
-            secondaryServiceComponentName = CREDMAN_SERVICE_COMPONENT_NAME;
+            secondaryServiceComponentName = mCredentialAutofillService;
         }
         Slog.v(TAG, "Primary service component name: " + primaryServiceComponentName
                 + ", secondary service component name: " + secondaryServiceComponentName);
 
         mRemoteFillService = primaryServiceComponentName == null ? null
                 : new RemoteFillService(context, primaryServiceComponentName, userId, this,
-                        bindInstantServiceAllowed);
+                        bindInstantServiceAllowed, mCredentialAutofillService);
         mSecondaryProviderHandler = secondaryServiceComponentName == null ? null
                 : new SecondaryProviderHandler(context, userId, bindInstantServiceAllowed,
-                this::onSecondaryFillResponse, secondaryServiceComponentName);
+                this::onSecondaryFillResponse, secondaryServiceComponentName,
+                        mCredentialAutofillService);
         mActivityToken = activityToken;
         mHasCallback = hasCallback;
         mUiLatencyHistory = uiLatencyHistory;
@@ -1556,6 +1558,21 @@
         mLogViewEntered = false;
     }
 
+    private ComponentName getCredentialAutofillService(Context context) {
+        ComponentName componentName = null;
+        String credentialManagerAutofillCompName = context.getResources().getString(
+                R.string.config_defaultCredentialManagerAutofillService);
+        if (credentialManagerAutofillCompName != null
+                && !credentialManagerAutofillCompName.isEmpty()) {
+            componentName = ComponentName.unflattenFromString(
+                    credentialManagerAutofillCompName);
+        }
+        if (componentName == null) {
+            Slog.w(TAG, "Invalid CredentialAutofillService");
+        }
+        return componentName;
+    }
+
     /**
      * Gets the currently registered activity token
      *
@@ -5141,7 +5158,8 @@
             return;
         }
         for (Dataset dataset: response.getDatasets()) {
-            if (isPinnedDataset(dataset)) {
+            if (dataset.getId() != null
+                    && dataset.getId().equals(AutofillManager.PINNED_DATASET_ID)) {
                 Slog.d(TAG, "Adding Credential Manager callback to a pinned entry");
                 addCredentialManagerCallbackForDataset(dataset, response.getRequestId());
             }
diff --git a/services/backup/Android.bp b/services/backup/Android.bp
index 2a85eb6..e13746e 100644
--- a/services/backup/Android.bp
+++ b/services/backup/Android.bp
@@ -30,5 +30,6 @@
 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 e9f959f..d53f949 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"
@@ -50,4 +51,12 @@
             "logger."
     bug: "296844513"
     is_fixed_read_only: true
-}
\ No newline at end of file
+}
+
+flag {
+    name: "enable_increased_bmm_logging_for_restore_at_install"
+    namespace: "onboarding"
+    description: "Increase BMM logging coverage in restore at install flow."
+    bug: "331749778"
+    is_fixed_read_only: true
+}
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 976504a..dc1cfb9 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -3903,11 +3903,33 @@
             skip = true;
         }
 
+        BackupManagerMonitorEventSender  mBMMEventSender =
+                getBMMEventSender(/*monitor=*/ null);
+        PackageInfo packageInfo = getPackageInfoForBMMLogging(packageName);
         TransportConnection transportConnection =
                 mTransportManager.getCurrentTransportClient("BMS.restoreAtInstall()");
         if (transportConnection == null) {
             if (DEBUG) Slog.w(TAG, addUserIdToLogMessage(mUserId, "No transport client"));
             skip = true;
+        } else if (Flags.enableIncreasedBmmLoggingForRestoreAtInstall()) {
+            try {
+                BackupTransportClient transportClient = transportConnection.connectOrThrow(
+                        "BMS.restoreAtInstall");
+                mBMMEventSender.setMonitor(transportClient.getBackupManagerMonitor());
+            } catch (TransportNotAvailableException | RemoteException e) {
+                mBMMEventSender.monitorEvent(
+                        BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_IS_NULL, packageInfo,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT, null);
+            }
+        }
+
+        if (Flags.enableIncreasedBmmLoggingForRestoreAtInstall()) {
+            mBMMEventSender.monitorEvent(
+                    BackupManagerMonitor.LOG_EVENT_ID_RESTORE_AT_INSTALL_INVOKED, packageInfo,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    mBMMEventSender.putMonitoringExtra(/*extras=*/null,
+                            BackupManagerMonitor.EXTRA_LOG_OPERATION_TYPE,
+                            BackupAnnotations.OperationType.RESTORE));
         }
 
         if (!mAutoRestore) {
@@ -3943,7 +3965,7 @@
                         RestoreParams.createForRestoreAtInstall(
                                 transportConnection,
                                 /* observer */ null,
-                                /* monitor */ null,
+                                mBMMEventSender.getMonitor(),
                                 restoreSet,
                                 packageName,
                                 token,
@@ -3963,6 +3985,15 @@
         if (skip) {
             // Auto-restore disabled or no way to attempt a restore
 
+            if (Flags.enableIncreasedBmmLoggingForRestoreAtInstall()) {
+                mBMMEventSender.monitorEvent(
+                        BackupManagerMonitor.LOG_EVENT_ID_SKIP_RESTORE_AT_INSTALL, packageInfo,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        mBMMEventSender.putMonitoringExtra(/*extras=*/null,
+                                BackupManagerMonitor.EXTRA_LOG_OPERATION_TYPE,
+                                BackupAnnotations.OperationType.RESTORE));
+            }
+
             if (transportConnection != null) {
                 mTransportManager.disposeOfTransportClient(
                         transportConnection, "BMS.restoreAtInstall()");
@@ -3976,6 +4007,23 @@
         }
     }
 
+    private PackageInfo getPackageInfoForBMMLogging(String packageName) {
+        try {
+            return mPackageManager.getPackageInfoAsUser(packageName, 0, mUserId);
+        } catch (NameNotFoundException e) {
+            Slog.w(
+                    TAG,
+                    addUserIdToLogMessage(
+                            mUserId, "Asked to get PackageInfo for BMM logging of nonexistent pkg "
+                                    + packageName));
+
+            PackageInfo packageInfo = new PackageInfo();
+            packageInfo.packageName = packageName;
+
+            return packageInfo;
+        }
+    }
+
     /** Hand off a restore session. */
     public IRestoreSession beginRestoreSession(String packageName, String transport) {
         if (DEBUG) {
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index 2c9eb51..b414b25 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -29,6 +29,7 @@
 import android.app.IBackupAgent;
 import android.app.backup.BackupAgent;
 import android.app.backup.BackupAnnotations;
+import android.app.backup.BackupManagerMonitor;
 import android.app.backup.FullBackup;
 import android.app.backup.IBackupManagerMonitor;
 import android.app.backup.IFullBackupRestoreObserver;
@@ -57,6 +58,7 @@
 import com.android.server.backup.UserBackupManagerService;
 import com.android.server.backup.fullbackup.FullBackupObbConnection;
 import com.android.server.backup.utils.BackupEligibilityRules;
+import com.android.server.backup.utils.BackupManagerMonitorEventSender;
 import com.android.server.backup.utils.BytesReadListener;
 import com.android.server.backup.utils.FullBackupRestoreObserverUtils;
 import com.android.server.backup.utils.RestoreUtils;
@@ -143,6 +145,8 @@
 
     private FileMetadata mReadOnlyParent = null;
 
+    private BackupManagerMonitorEventSender mBackupManagerMonitorEventSender;
+
     public FullRestoreEngine(
             UserBackupManagerService backupManagerService, OperationStorage operationStorage,
             BackupRestoreTask monitorTask, IFullBackupRestoreObserver observer,
@@ -155,6 +159,7 @@
         mMonitorTask = monitorTask;
         mObserver = observer;
         mMonitor = monitor;
+        mBackupManagerMonitorEventSender = new BackupManagerMonitorEventSender(monitor);
         mOnlyPackage = onlyPackage;
         mAllowApks = allowApks;
         mAgentTimeoutParameters = Objects.requireNonNull(
@@ -225,6 +230,9 @@
                     // one app's data but see a different app's on the wire
                     if (onlyPackage != null) {
                         if (!pkg.equals(onlyPackage.packageName)) {
+                            logBMMEvent(
+                                    BackupManagerMonitor.LOG_EVENT_ID_RESTORE_DATA_DOES_NOT_BELONG_TO_PACKAGE,
+                                    onlyPackage);
                             Slog.w(TAG, "Expected data for " + onlyPackage + " but saw " + pkg);
                             setResult(RestoreEngine.TRANSPORT_FAILURE);
                             setRunning(false);
@@ -412,6 +420,9 @@
                         }
 
                         if (mAgent == null) {
+                            logBMMEvent(
+                                    BackupManagerMonitor.LOG_EVENT_ID_UNABLE_TO_CREATE_AGENT_FOR_RESTORE,
+                                    onlyPackage);
                             Slog.e(TAG, "Unable to create agent for " + pkg);
                             okay = false;
                             tearDownPipes();
@@ -501,6 +512,9 @@
                         } catch (RemoteException e) {
                             // whoops, remote entity went away.  We'll eat the content
                             // ourselves, then, and not copy it over.
+                            logBMMEvent(
+                                    BackupManagerMonitor.LOG_EVENT_ID_AGENT_CRASHED_BEFORE_RESTORE_DATA_IS_SENT,
+                                    onlyPackage);
                             Slog.e(TAG, "Agent crashed during full restore");
                             agentSuccess = false;
                             okay = false;
@@ -531,6 +545,9 @@
                                     } catch (IOException e) {
                                         Slog.e(TAG, "Failed to write to restore pipe: "
                                                 + e.getMessage());
+                                        logBMMEvent(
+                                                BackupManagerMonitor.LOG_EVENT_ID_FAILED_TO_SEND_DATA_TO_AGENT_DURING_RESTORE,
+                                                onlyPackage);
                                         pipeOkay = false;
                                     }
                                 }
@@ -548,6 +565,8 @@
                         // okay, if the remote end failed at any point, deal with
                         // it by ignoring the rest of the restore on it
                         if (!agentSuccess) {
+                            logBMMEvent(BackupManagerMonitor.LOG_EVENT_ID_AGENT_FAILURE_DURING_RESTORE,
+                                    onlyPackage);
                             Slog.w(TAG, "Agent failure restoring " + pkg + "; ending restore");
                             mBackupManagerService.getBackupHandler().removeMessages(
                                     MSG_RESTORE_OPERATION_TIMEOUT);
@@ -590,6 +609,8 @@
             if (DEBUG) {
                 Slog.w(TAG, "io exception on restore socket read: " + e.getMessage());
             }
+            logBMMEvent(BackupManagerMonitor.LOG_EVENT_ID_FAILED_TO_READ_DATA_FROM_TRANSPORT,
+                    onlyPackage);
             setResult(RestoreEngine.TRANSPORT_FAILURE);
             info = null;
         }
@@ -631,6 +652,16 @@
         return false;
     }
 
+    private void logBMMEvent(int eventId, PackageInfo pkgInfo) {
+        if (Flags.enableIncreasedBmmLoggingForRestoreAtInstall()) {
+            mBackupManagerMonitorEventSender.monitorEvent(eventId, pkgInfo,
+                    BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                    mBackupManagerMonitorEventSender.putMonitoringExtra(/*extras=*/
+                            null, BackupManagerMonitor.EXTRA_LOG_OPERATION_TYPE,
+                            BackupAnnotations.OperationType.RESTORE));
+        }
+    }
+
     private static boolean isValidParent(FileMetadata parentDir, @NonNull FileMetadata childDir) {
         return parentDir != null
                 && childDir.packageName.equals(parentDir.packageName)
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index 8fece82..e536876 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -418,25 +418,6 @@
     private void startRestore() {
         sendStartRestore(mAcceptSet.size());
 
-        // If we're starting a full-system restore, set up to begin widget ID remapping
-        if (mIsSystemRestore) {
-            AppWidgetBackupBridge.systemRestoreStarting(mUserId);
-            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
-            mBackupManagerMonitorEventSender.monitorEvent(
-                    BackupManagerMonitor.LOG_EVENT_ID_START_SYSTEM_RESTORE,
-                    null,
-                    BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
-                    monitoringExtras);
-        } else {
-            // We are either performing RestoreAtInstall or Bmgr.
-            Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
-            mBackupManagerMonitorEventSender.monitorEvent(
-                    BackupManagerMonitor.LOG_EVENT_ID_START_RESTORE_AT_INSTALL,
-                    null,
-                    BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
-                    monitoringExtras);
-        }
-
         try {
             String transportDirName =
                     mTransportManager.getTransportDirName(
@@ -459,6 +440,34 @@
                 mBackupManagerMonitorEventSender.setMonitor(transport.getBackupManagerMonitor());
             }
 
+            if (Flags.enableIncreasedBmmLoggingForRestoreAtInstall()) {
+                for (PackageInfo info : mAcceptSet) {
+                    mBackupManagerMonitorEventSender.monitorEvent(
+                            BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_ACCEPTED_FOR_RESTORE, info,
+                            BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                            addRestoreOperationTypeToEvent(/* extras= */ null));
+                }
+            }
+
+            // If we're starting a full-system restore, set up to begin widget ID remapping
+            if (mIsSystemRestore) {
+                AppWidgetBackupBridge.systemRestoreStarting(mUserId);
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
+                mBackupManagerMonitorEventSender.monitorEvent(
+                        BackupManagerMonitor.LOG_EVENT_ID_START_SYSTEM_RESTORE,
+                        null,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        monitoringExtras);
+            } else {
+                // We are either performing RestoreAtInstall or Bmgr.
+                Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
+                mBackupManagerMonitorEventSender.monitorEvent(
+                        BackupManagerMonitor.LOG_EVENT_ID_START_RESTORE_AT_INSTALL,
+                        null,
+                        BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+                        monitoringExtras);
+            }
+
             mStatus = transport.startRestore(mToken, packages);
             if (mStatus != BackupTransport.TRANSPORT_OK) {
                 Slog.e(TAG, "Transport error " + mStatus + "; no restore possible");
@@ -638,7 +647,7 @@
                 Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
                 mBackupManagerMonitorEventSender.monitorEvent(
                         BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_NOT_PRESENT,
-                        mCurrentPackage,
+                        createPackageInfoForBMMLogging(pkgName),
                         BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                         monitoringExtras);
                 EventLog.writeEvent(
@@ -739,7 +748,7 @@
             Bundle monitoringExtras = addRestoreOperationTypeToEvent(/* extras= */ null);
             mBackupManagerMonitorEventSender.monitorEvent(
                     BackupManagerMonitor.LOG_EVENT_ID_NO_NEXT_RESTORE_TARGET,
-                    mCurrentPackage,
+                    null,
                     BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
                     monitoringExtras);
             EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
@@ -1804,4 +1813,10 @@
                 monitoringExtrasDenylist);
     }
 
+    private PackageInfo createPackageInfoForBMMLogging(String packageName) {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.packageName = packageName;
+
+        return packageInfo;
+    }
 }
diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
index 6d315ba..fad59d2 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorDumpsysUtils.java
@@ -371,6 +371,24 @@
                     "V to U restore pkg not eligible";
             case BackupManagerMonitor.LOG_EVENT_ID_V_TO_U_RESTORE_SET_LIST ->
                     "V to U restore lists";
+            case BackupManagerMonitor.LOG_EVENT_ID_RESTORE_AT_INSTALL_INVOKED ->
+                    "Invoked restore at install";
+            case BackupManagerMonitor.LOG_EVENT_ID_SKIP_RESTORE_AT_INSTALL ->
+                    "Skip restore at install";
+            case BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_ACCEPTED_FOR_RESTORE ->
+                    "Pkg accepted for restore";
+            case BackupManagerMonitor.LOG_EVENT_ID_RESTORE_DATA_DOES_NOT_BELONG_TO_PACKAGE ->
+                    "Restore data does not belong to package";
+            case BackupManagerMonitor.LOG_EVENT_ID_UNABLE_TO_CREATE_AGENT_FOR_RESTORE ->
+                    "Unable to create Agent";
+            case BackupManagerMonitor.LOG_EVENT_ID_AGENT_CRASHED_BEFORE_RESTORE_DATA_IS_SENT ->
+                    "Agent crashed before restore data is streamed";
+            case BackupManagerMonitor.LOG_EVENT_ID_FAILED_TO_SEND_DATA_TO_AGENT_DURING_RESTORE ->
+                    "Failed to send data to agent";
+            case BackupManagerMonitor.LOG_EVENT_ID_AGENT_FAILURE_DURING_RESTORE ->
+                    "Agent failure during restore";
+            case BackupManagerMonitor.LOG_EVENT_ID_FAILED_TO_READ_DATA_FROM_TRANSPORT ->
+                    "Failed to read data from Transport";
             default -> "Unknown log event ID: " + code;
         };
         return id;
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 8ac1eb9..30e4a3e 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -52,6 +52,7 @@
 import android.app.AppOpsManager;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.app.ecm.EnhancedConfirmationManager;
 import android.companion.AssociationInfo;
 import android.companion.AssociationRequest;
 import android.companion.IAssociationRequestCallback;
@@ -64,6 +65,7 @@
 import android.companion.datatransfer.PermissionSyncRequest;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -80,6 +82,7 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.permission.flags.Flags;
 import android.util.ArraySet;
 import android.util.ExceptionUtils;
 import android.util.Slog;
@@ -103,10 +106,10 @@
 import com.android.server.companion.datatransfer.contextsync.CrossDeviceCall;
 import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncController;
 import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncControllerCallback;
-import com.android.server.companion.presence.CompanionAppBinder;
-import com.android.server.companion.presence.DevicePresenceProcessor;
-import com.android.server.companion.presence.ObservableUuid;
-import com.android.server.companion.presence.ObservableUuidStore;
+import com.android.server.companion.devicepresence.CompanionAppBinder;
+import com.android.server.companion.devicepresence.DevicePresenceProcessor;
+import com.android.server.companion.devicepresence.ObservableUuid;
+import com.android.server.companion.devicepresence.ObservableUuidStore;
 import com.android.server.companion.transport.CompanionTransportManager;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.wm.ActivityTaskManagerInternal;
@@ -448,15 +451,26 @@
             }
 
             return Binder.withCleanCallingIdentity(() -> {
+                final Intent intent;
                 if (!isRestrictedSettingsAllowed(getContext(), callingPackage, callingUid)) {
                     Slog.e(TAG, "Side loaded app must enable restricted "
                             + "setting before request the notification access");
-                    return null;
+                    if (Flags.enhancedConfirmationModeApisEnabled()) {
+                        intent = getContext()
+                                .getSystemService(EnhancedConfirmationManager.class)
+                                .createRestrictedSettingDialogIntent(callingPackage,
+                                        AppOpsManager.OPSTR_ACCESS_NOTIFICATIONS);
+                    } else {
+                        return null;
+                    }
+                } else {
+                    intent = NotificationAccessConfirmationActivityContract.launcherIntent(
+                            getContext(), userId, component);
                 }
+
                 return PendingIntent.getActivityAsUser(getContext(),
                         0 /* request code */,
-                        NotificationAccessConfirmationActivityContract.launcherIntent(
-                                getContext(), userId, component),
+                        intent,
                         PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT
                                 | PendingIntent.FLAG_CANCEL_CURRENT,
                         null /* options */,
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java b/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java
index daa8fdb..9cfb535 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java
@@ -36,8 +36,8 @@
 import com.android.server.companion.datatransfer.SystemDataTransferProcessor;
 import com.android.server.companion.datatransfer.contextsync.BitmapUtils;
 import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncController;
-import com.android.server.companion.presence.DevicePresenceProcessor;
-import com.android.server.companion.presence.ObservableUuid;
+import com.android.server.companion.devicepresence.DevicePresenceProcessor;
+import com.android.server.companion.devicepresence.ObservableUuid;
 import com.android.server.companion.transport.CompanionTransportManager;
 
 import java.io.PrintWriter;
diff --git a/services/companion/java/com/android/server/companion/association/DisassociationProcessor.java b/services/companion/java/com/android/server/companion/association/DisassociationProcessor.java
index acf683d..8c1116b 100644
--- a/services/companion/java/com/android/server/companion/association/DisassociationProcessor.java
+++ b/services/companion/java/com/android/server/companion/association/DisassociationProcessor.java
@@ -37,8 +37,8 @@
 import android.util.Slog;
 
 import com.android.server.companion.datatransfer.SystemDataTransferRequestStore;
-import com.android.server.companion.presence.CompanionAppBinder;
-import com.android.server.companion.presence.DevicePresenceProcessor;
+import com.android.server.companion.devicepresence.CompanionAppBinder;
+import com.android.server.companion.devicepresence.DevicePresenceProcessor;
 import com.android.server.companion.transport.CompanionTransportManager;
 
 /**
diff --git a/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java b/services/companion/java/com/android/server/companion/devicepresence/BleDeviceProcessor.java
similarity index 61%
rename from services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java
rename to services/companion/java/com/android/server/companion/devicepresence/BleDeviceProcessor.java
index 407b9da..6cdc02e 100644
--- a/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java
+++ b/services/companion/java/com/android/server/companion/devicepresence/BleDeviceProcessor.java
@@ -15,27 +15,15 @@
  */
 
 
-package com.android.server.companion.presence;
+package com.android.server.companion.devicepresence;
 
 import static android.bluetooth.BluetoothAdapter.ACTION_BLE_STATE_CHANGED;
 import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED;
-import static android.bluetooth.BluetoothAdapter.EXTRA_PREVIOUS_STATE;
-import static android.bluetooth.BluetoothAdapter.EXTRA_STATE;
-import static android.bluetooth.BluetoothAdapter.nameForState;
-import static android.bluetooth.le.ScanCallback.SCAN_FAILED_ALREADY_STARTED;
-import static android.bluetooth.le.ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED;
-import static android.bluetooth.le.ScanCallback.SCAN_FAILED_FEATURE_UNSUPPORTED;
-import static android.bluetooth.le.ScanCallback.SCAN_FAILED_INTERNAL_ERROR;
-import static android.bluetooth.le.ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES;
-import static android.bluetooth.le.ScanCallback.SCAN_FAILED_SCANNING_TOO_FREQUENTLY;
 import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES;
 import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_FIRST_MATCH;
 import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_MATCH_LOST;
 import static android.bluetooth.le.ScanSettings.SCAN_MODE_LOW_POWER;
 
-import static com.android.server.companion.presence.DevicePresenceProcessor.DEBUG;
-import static com.android.server.companion.utils.Utils.btDeviceToString;
-
 import static java.util.Objects.requireNonNull;
 
 import android.annotation.MainThread;
@@ -56,21 +44,19 @@
 import android.content.IntentFilter;
 import android.os.Handler;
 import android.os.Looper;
-import android.util.Log;
 import android.util.Slog;
 
 import com.android.server.companion.association.AssociationStore;
 import com.android.server.companion.association.AssociationStore.ChangeType;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
 @SuppressLint("LongLogTag")
-class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener {
-    private static final String TAG = "CDM_BleCompanionDeviceScanner";
+class BleDeviceProcessor implements AssociationStore.OnChangeListener {
+    private static final String TAG = "CDM_BleDeviceProcessor";
 
     interface Callback {
         void onBleCompanionDeviceFound(int associationId, int userId);
@@ -78,26 +64,27 @@
         void onBleCompanionDeviceLost(int associationId, int userId);
     }
 
-    private final @NonNull AssociationStore mAssociationStore;
-    private final @NonNull Callback mCallback;
+    @NonNull
+    private final AssociationStore mAssociationStore;
+    @NonNull
+    private final Callback mCallback;
 
     // Non-null after init().
-    private @Nullable BluetoothAdapter mBtAdapter;
+    @Nullable
+    private BluetoothAdapter mBtAdapter;
     // Non-null after init() and when BLE is available. Otherwise - null.
-    private @Nullable BluetoothLeScanner mBleScanner;
+    @Nullable
+    private BluetoothLeScanner mBleScanner;
     // Only accessed from the Main thread.
     private boolean mScanning = false;
 
-    BleCompanionDeviceScanner(
-            @NonNull AssociationStore associationStore, @NonNull Callback callback) {
+    BleDeviceProcessor(@NonNull AssociationStore associationStore, @NonNull Callback callback) {
         mAssociationStore = associationStore;
         mCallback = callback;
     }
 
     @MainThread
     void init(@NonNull Context context, @NonNull BluetoothAdapter btAdapter) {
-        if (DEBUG) Log.i(TAG, "init()");
-
         if (mBtAdapter != null) {
             throw new IllegalStateException(getClass().getSimpleName() + " is already initialized");
         }
@@ -113,9 +100,7 @@
     final void restartScan() {
         enforceInitialized();
 
-        if (DEBUG) Log.i(TAG , "restartScan()");
         if (mBleScanner == null) {
-            if (DEBUG) Log.d(TAG, "  > BLE is not available");
             return;
         }
 
@@ -138,12 +123,8 @@
         enforceInitialized();
 
         final boolean bleAvailable = mBtAdapter.isLeEnabled();
-        if (DEBUG) {
-            Log.i(TAG, "checkBleState() bleAvailable=" + bleAvailable);
-        }
         if ((bleAvailable && mBleScanner != null) || (!bleAvailable && mBleScanner == null)) {
             // Nothing changed.
-            if (DEBUG) Log.i(TAG, "  > BLE status did not change");
             return;
         }
 
@@ -153,12 +134,9 @@
                 // Oops, that's a race condition. Can return.
                 return;
             }
-            if (DEBUG) Log.i(TAG, "  > BLE is now available");
 
             startScan();
         } else {
-            if (DEBUG) Log.i(TAG, "  > BLE is now unavailable");
-
             stopScanIfNeeded();
             mBleScanner = null;
         }
@@ -194,13 +172,7 @@
             }
         }
         if (macAddresses.isEmpty()) {
-            if (DEBUG) Log.i(TAG, "  > there are no (associated) devices to Scan for.");
             return;
-        } else {
-            if (DEBUG) {
-                Log.d(TAG, "  > addresses=(n=" + macAddresses.size() + ")"
-                        + "[" + String.join(", ", macAddresses) + "]");
-            }
         }
 
         final List<ScanFilter> filters = new ArrayList<>(macAddresses.size());
@@ -230,7 +202,6 @@
 
         Slog.i(TAG, "stopBleScan()");
         if (!mScanning) {
-            if (DEBUG) Log.d(TAG, "  > not scanning.");
             return;
         }
         // mScanCallback is non-null here - it cannot be null when mScanning is true.
@@ -252,26 +223,16 @@
 
     @MainThread
     private void notifyDeviceFound(@NonNull BluetoothDevice device) {
-        if (DEBUG) Log.i(TAG, "notifyDevice_Found()" + btDeviceToString(device));
-
-        final List<AssociationInfo> associations =
-                mAssociationStore.getActiveAssociationsByAddress(device.getAddress());
-        if (DEBUG) Log.d(TAG, "  > associations=" + Arrays.toString(associations.toArray()));
-
-        for (AssociationInfo association : associations) {
+        for (AssociationInfo association : mAssociationStore.getActiveAssociationsByAddress(
+                device.getAddress())) {
             mCallback.onBleCompanionDeviceFound(association.getId(), association.getUserId());
         }
     }
 
     @MainThread
     private void notifyDeviceLost(@NonNull BluetoothDevice device) {
-        if (DEBUG) Log.i(TAG, "notifyDevice_Lost()" + btDeviceToString(device));
-
-        final List<AssociationInfo> associations =
-                mAssociationStore.getActiveAssociationsByAddress(device.getAddress());
-        if (DEBUG) Log.d(TAG, "  > associations=" + Arrays.toString(associations.toArray()));
-
-        for (AssociationInfo association : associations) {
+        for (AssociationInfo association : mAssociationStore.getActiveAssociationsByAddress(
+                device.getAddress())) {
             mCallback.onBleCompanionDeviceLost(association.getId(), association.getUserId());
         }
     }
@@ -280,17 +241,6 @@
         final BroadcastReceiver receiver = new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
-                final int prevState = intent.getIntExtra(EXTRA_PREVIOUS_STATE, -1);
-                final int state = intent.getIntExtra(EXTRA_STATE, -1);
-
-                if (DEBUG) {
-                    // The action is either STATE_CHANGED or BLE_STATE_CHANGED.
-                    final String action =
-                            intent.getAction().replace("android.bluetooth.adapter.", "bt.");
-                    Log.d(TAG, "on(Broadcast)Receive() " + action + ": "
-                            + nameForBtState(prevState) + "->" + nameForBtState(state));
-                }
-
                 checkBleState();
             }
         };
@@ -313,16 +263,6 @@
         public void onScanResult(int callbackType, ScanResult result) {
             final BluetoothDevice device = result.getDevice();
 
-            if (DEBUG) {
-                Log.d(TAG, "onScanResult() " + nameForBleScanCallbackType(callbackType)
-                        + " device=" + btDeviceToString(device));
-                Log.v(TAG, "  > scanResult=" + result);
-
-                final List<AssociationInfo> associations =
-                        mAssociationStore.getActiveAssociationsByAddress(device.getAddress());
-                Log.v(TAG, "  > associations=" + Arrays.toString(associations.toArray()));
-            }
-
             switch (callbackType) {
                 case CALLBACK_TYPE_FIRST_MATCH:
                     notifyDeviceFound(device);
@@ -342,60 +282,20 @@
         @MainThread
         @Override
         public void onScanFailed(int errorCode) {
-            if (DEBUG) Log.w(TAG, "onScanFailed() " + nameForBleScanErrorCode(errorCode));
             mScanning = false;
         }
     };
 
-    private static String nameForBtState(int state) {
-        return nameForState(state) + "(" + state + ")";
-    }
-
     private static String nameForBleScanCallbackType(int callbackType) {
-        final String name;
-        switch (callbackType) {
-            case CALLBACK_TYPE_ALL_MATCHES:
-                name = "ALL_MATCHES";
-                break;
-            case CALLBACK_TYPE_FIRST_MATCH:
-                name = "FIRST_MATCH";
-                break;
-            case CALLBACK_TYPE_MATCH_LOST:
-                name = "MATCH_LOST";
-                break;
-            default:
-                name = "Unknown";
-        }
+        final String name = switch (callbackType) {
+            case CALLBACK_TYPE_ALL_MATCHES -> "ALL_MATCHES";
+            case CALLBACK_TYPE_FIRST_MATCH -> "FIRST_MATCH";
+            case CALLBACK_TYPE_MATCH_LOST -> "MATCH_LOST";
+            default -> "Unknown";
+        };
         return name + "(" + callbackType + ")";
     }
 
-    private static String nameForBleScanErrorCode(int errorCode) {
-        final String name;
-        switch (errorCode) {
-            case SCAN_FAILED_ALREADY_STARTED:
-                name = "ALREADY_STARTED";
-                break;
-            case SCAN_FAILED_APPLICATION_REGISTRATION_FAILED:
-                name = "APPLICATION_REGISTRATION_FAILED";
-                break;
-            case SCAN_FAILED_INTERNAL_ERROR:
-                name = "INTERNAL_ERROR";
-                break;
-            case SCAN_FAILED_FEATURE_UNSUPPORTED:
-                name = "FEATURE_UNSUPPORTED";
-                break;
-            case SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES:
-                name = "OUT_OF_HARDWARE_RESOURCES";
-                break;
-            case SCAN_FAILED_SCANNING_TOO_FREQUENTLY:
-                name = "SCANNING_TOO_FREQUENTLY";
-                break;
-            default:
-                name = "Unknown";
-        }
-        return name + "(" + errorCode + ")";
-    }
-
     private static final ScanSettings SCAN_SETTINGS = new ScanSettings.Builder()
             .setCallbackType(CALLBACK_TYPE_FIRST_MATCH | CALLBACK_TYPE_MATCH_LOST)
             .setScanMode(SCAN_MODE_LOW_POWER)
diff --git a/services/companion/java/com/android/server/companion/presence/BluetoothCompanionDeviceConnectionListener.java b/services/companion/java/com/android/server/companion/devicepresence/BluetoothDeviceProcessor.java
similarity index 62%
rename from services/companion/java/com/android/server/companion/presence/BluetoothCompanionDeviceConnectionListener.java
rename to services/companion/java/com/android/server/companion/devicepresence/BluetoothDeviceProcessor.java
index e1a8db4..612c156 100644
--- a/services/companion/java/com/android/server/companion/presence/BluetoothCompanionDeviceConnectionListener.java
+++ b/services/companion/java/com/android/server/companion/devicepresence/BluetoothDeviceProcessor.java
@@ -14,14 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.server.companion.presence;
+package com.android.server.companion.devicepresence;
 
 import static android.companion.DevicePresenceEvent.EVENT_BT_CONNECTED;
 import static android.companion.DevicePresenceEvent.EVENT_BT_DISCONNECTED;
 
-import static com.android.server.companion.presence.DevicePresenceProcessor.DEBUG;
-import static com.android.server.companion.utils.Utils.btDeviceToString;
-
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
 import android.bluetooth.BluetoothAdapter;
@@ -32,8 +29,6 @@
 import android.os.HandlerExecutor;
 import android.os.ParcelUuid;
 import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
 
 import com.android.internal.util.ArrayUtils;
 import com.android.server.companion.association.AssociationStore;
@@ -45,10 +40,10 @@
 import java.util.Map;
 
 @SuppressLint("LongLogTag")
-public class BluetoothCompanionDeviceConnectionListener
+public class BluetoothDeviceProcessor
         extends BluetoothAdapter.BluetoothConnectionCallback
         implements AssociationStore.OnChangeListener {
-    private static final String TAG = "CDM_BluetoothCompanionDeviceConnectionListener";
+    private static final String TAG = "CDM_BluetoothDeviceProcessor";
 
     interface Callback {
         void onBluetoothCompanionDeviceConnected(int associationId, int userId);
@@ -58,24 +53,25 @@
         void onDevicePresenceEventByUuid(ObservableUuid uuid, int event);
     }
 
-    private final @NonNull AssociationStore mAssociationStore;
-    private final @NonNull Callback mCallback;
+    @NonNull
+    private final AssociationStore mAssociationStore;
+    @NonNull
+    private final ObservableUuidStore mObservableUuidStore;
+    @NonNull
+    private final Callback mCallback;
+
     /** A set of ALL connected BT device (not only companion.) */
-    private final @NonNull Map<MacAddress, BluetoothDevice> mAllConnectedDevices = new HashMap<>();
+    @NonNull
+    private final Map<MacAddress, BluetoothDevice> mAllConnectedDevices = new HashMap<>();
 
-    private final @NonNull ObservableUuidStore mObservableUuidStore;
-
-    BluetoothCompanionDeviceConnectionListener(UserManager userManager,
-            @NonNull AssociationStore associationStore,
+    BluetoothDeviceProcessor(@NonNull AssociationStore associationStore,
             @NonNull ObservableUuidStore observableUuidStore, @NonNull Callback callback) {
         mAssociationStore = associationStore;
         mObservableUuidStore = observableUuidStore;
         mCallback = callback;
     }
 
-    public void init(@NonNull BluetoothAdapter btAdapter) {
-        if (DEBUG) Log.i(TAG, "init()");
-
+    void init(@NonNull BluetoothAdapter btAdapter) {
         btAdapter.registerBluetoothConnectionCallback(
                 new HandlerExecutor(Handler.getMain()), /* callback */this);
         mAssociationStore.registerLocalListener(this);
@@ -87,13 +83,9 @@
      */
     @Override
     public void onDeviceConnected(@NonNull BluetoothDevice device) {
-        if (DEBUG) Log.i(TAG, "onDevice_Connected() " + btDeviceToString(device));
-
         final MacAddress macAddress = MacAddress.fromString(device.getAddress());
-        final int userId = UserHandle.myUserId();
 
         if (mAllConnectedDevices.put(macAddress, device) != null) {
-            if (DEBUG) Log.w(TAG, "Device " + btDeviceToString(device) + " is already connected.");
             return;
         }
 
@@ -108,18 +100,9 @@
     @Override
     public void onDeviceDisconnected(@NonNull BluetoothDevice device,
             int reason) {
-        if (DEBUG) {
-            Log.i(TAG, "onDevice_Disconnected() " + btDeviceToString(device));
-            Log.d(TAG, "  reason=" + disconnectReasonToString(reason));
-        }
-
         final MacAddress macAddress = MacAddress.fromString(device.getAddress());
-        final int userId = UserHandle.myUserId();
 
         if (mAllConnectedDevices.remove(macAddress) == null) {
-            if (DEBUG) {
-                Log.w(TAG, "The device wasn't tracked as connected " + btDeviceToString(device));
-            }
             return;
         }
 
@@ -130,22 +113,6 @@
         int userId = UserHandle.myUserId();
         final List<AssociationInfo> associations =
                 mAssociationStore.getActiveAssociationsByAddress(device.getAddress());
-        final List<ObservableUuid> observableUuids =
-                mObservableUuidStore.getObservableUuidsForUser(userId);
-        final ParcelUuid[] bluetoothDeviceUuids = device.getUuids();
-
-        final List<ParcelUuid> deviceUuids = ArrayUtils.isEmpty(bluetoothDeviceUuids)
-                ? Collections.emptyList() : Arrays.asList(bluetoothDeviceUuids);
-
-        if (DEBUG) {
-            Log.d(TAG, "onDevice_ConnectivityChanged() " + btDeviceToString(device)
-                    + " connected=" + connected);
-            if (associations.isEmpty()) {
-                Log.d(TAG, "  > No CDM associations");
-            } else {
-                Log.d(TAG, "  > associations=" + Arrays.toString(associations.toArray()));
-            }
-        }
 
         for (AssociationInfo association : associations) {
             if (!association.isNotifyOnDeviceNearby()) continue;
@@ -157,44 +124,25 @@
             }
         }
 
+        final List<ObservableUuid> observableUuids =
+                mObservableUuidStore.getObservableUuidsForUser(userId);
+        final ParcelUuid[] bluetoothDeviceUuids = device.getUuids();
+        final List<ParcelUuid> deviceUuids = ArrayUtils.isEmpty(bluetoothDeviceUuids)
+                ? Collections.emptyList() : Arrays.asList(bluetoothDeviceUuids);
+
         for (ObservableUuid uuid : observableUuids) {
             if (deviceUuids.contains(uuid.getUuid())) {
                 mCallback.onDevicePresenceEventByUuid(uuid, connected ? EVENT_BT_CONNECTED
-                                : EVENT_BT_DISCONNECTED);
+                        : EVENT_BT_DISCONNECTED);
             }
         }
     }
 
     @Override
     public void onAssociationAdded(AssociationInfo association) {
-        if (DEBUG) Log.d(TAG, "onAssociation_Added() " + association);
-
         if (mAllConnectedDevices.containsKey(association.getDeviceMacAddress())) {
             mCallback.onBluetoothCompanionDeviceConnected(
                     association.getId(), association.getUserId());
         }
     }
-
-    @Override
-    public void onAssociationRemoved(AssociationInfo association) {
-        // Intentionally do nothing: CompanionDevicePresenceMonitor will do all the bookkeeping
-        // required.
-    }
-
-    @Override
-    public void onAssociationUpdated(AssociationInfo association, boolean addressChanged) {
-        if (DEBUG) {
-            Log.d(TAG, "onAssociation_Updated() addrChange=" + addressChanged
-                    + " " + association);
-        }
-
-        if (!addressChanged) {
-            // Don't need to do anything.
-            return;
-        }
-
-        // At the moment CDM does allow changing association addresses, so we will never come here.
-        // This will be implemented when CDM support updating addresses.
-        throw new IllegalArgumentException("Address changes are not supported.");
-    }
 }
diff --git a/services/companion/java/com/android/server/companion/presence/CompanionAppBinder.java b/services/companion/java/com/android/server/companion/devicepresence/CompanionAppBinder.java
similarity index 99%
rename from services/companion/java/com/android/server/companion/presence/CompanionAppBinder.java
rename to services/companion/java/com/android/server/companion/devicepresence/CompanionAppBinder.java
index b6348ea..60f4688 100644
--- a/services/companion/java/com/android/server/companion/presence/CompanionAppBinder.java
+++ b/services/companion/java/com/android/server/companion/devicepresence/CompanionAppBinder.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.companion.presence;
+package com.android.server.companion.devicepresence;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
diff --git a/services/companion/java/com/android/server/companion/presence/CompanionServiceConnector.java b/services/companion/java/com/android/server/companion/devicepresence/CompanionServiceConnector.java
similarity index 99%
rename from services/companion/java/com/android/server/companion/presence/CompanionServiceConnector.java
rename to services/companion/java/com/android/server/companion/devicepresence/CompanionServiceConnector.java
index c01c319..5923e70c 100644
--- a/services/companion/java/com/android/server/companion/presence/CompanionServiceConnector.java
+++ b/services/companion/java/com/android/server/companion/devicepresence/CompanionServiceConnector.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.companion.presence;
+package com.android.server.companion.devicepresence;
 
 import static android.content.Context.BIND_ALMOST_PERCEPTIBLE;
 import static android.content.Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE;
diff --git a/services/companion/java/com/android/server/companion/presence/DevicePresenceProcessor.java b/services/companion/java/com/android/server/companion/devicepresence/DevicePresenceProcessor.java
similarity index 96%
rename from services/companion/java/com/android/server/companion/presence/DevicePresenceProcessor.java
rename to services/companion/java/com/android/server/companion/devicepresence/DevicePresenceProcessor.java
index 092886c..cfb7f337 100644
--- a/services/companion/java/com/android/server/companion/presence/DevicePresenceProcessor.java
+++ b/services/companion/java/com/android/server/companion/devicepresence/DevicePresenceProcessor.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.companion.presence;
+package com.android.server.companion.devicepresence;
 
 import static android.companion.AssociationRequest.DEVICE_PROFILE_AUTOMOTIVE_PROJECTION;
 import static android.companion.DevicePresenceEvent.EVENT_BLE_APPEARED;
@@ -24,6 +24,7 @@
 import static android.companion.DevicePresenceEvent.EVENT_SELF_MANAGED_APPEARED;
 import static android.companion.DevicePresenceEvent.EVENT_SELF_MANAGED_DISAPPEARED;
 import static android.companion.DevicePresenceEvent.NO_ASSOCIATION;
+import static android.content.Context.BLUETOOTH_SERVICE;
 import static android.os.Process.ROOT_UID;
 import static android.os.Process.SHELL_UID;
 
@@ -35,6 +36,7 @@
 import android.annotation.TestApi;
 import android.annotation.UserIdInt;
 import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
 import android.companion.AssociationInfo;
 import android.companion.DeviceNotAssociatedException;
 import android.companion.DevicePresenceEvent;
@@ -49,7 +51,6 @@
 import android.os.PowerManagerInternal;
 import android.os.RemoteException;
 import android.os.UserManager;
-import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
@@ -80,8 +81,7 @@
  */
 @SuppressLint("LongLogTag")
 public class DevicePresenceProcessor implements AssociationStore.OnChangeListener,
-        BluetoothCompanionDeviceConnectionListener.Callback, BleCompanionDeviceScanner.Callback {
-    static final boolean DEBUG = false;
+        BluetoothDeviceProcessor.Callback, BleDeviceProcessor.Callback {
     private static final String TAG = "CDM_DevicePresenceProcessor";
 
     @NonNull
@@ -93,9 +93,9 @@
     @NonNull
     private final ObservableUuidStore mObservableUuidStore;
     @NonNull
-    private final BluetoothCompanionDeviceConnectionListener mBtConnectionListener;
+    private final BluetoothDeviceProcessor mBluetoothDeviceProcessor;
     @NonNull
-    private final BleCompanionDeviceScanner mBleScanner;
+    private final BleDeviceProcessor mBleDeviceProcessor;
     @NonNull
     private final PowerManagerInternal mPowerManagerInternal;
     @NonNull
@@ -142,7 +142,7 @@
 
     public DevicePresenceProcessor(@NonNull Context context,
             @NonNull CompanionAppBinder companionAppBinder,
-            UserManager userManager,
+            @NonNull UserManager userManager,
             @NonNull AssociationStore associationStore,
             @NonNull ObservableUuidStore observableUuidStore,
             @NonNull PowerManagerInternal powerManagerInternal) {
@@ -151,25 +151,27 @@
         mAssociationStore = associationStore;
         mObservableUuidStore = observableUuidStore;
         mUserManager = userManager;
-        mBtConnectionListener = new BluetoothCompanionDeviceConnectionListener(userManager,
-                associationStore, mObservableUuidStore,
-                /* BluetoothCompanionDeviceConnectionListener.Callback */ this);
-        mBleScanner = new BleCompanionDeviceScanner(associationStore,
-                /* BleCompanionDeviceScanner.Callback */ this);
+        mBluetoothDeviceProcessor = new BluetoothDeviceProcessor(associationStore,
+                mObservableUuidStore, this);
+        mBleDeviceProcessor = new BleDeviceProcessor(associationStore, this);
         mPowerManagerInternal = powerManagerInternal;
     }
 
     /** Initialize {@link DevicePresenceProcessor} */
     public void init(Context context) {
-        if (DEBUG) Slog.i(TAG, "init()");
-
-        final BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
-        if (btAdapter != null) {
-            mBtConnectionListener.init(btAdapter);
-            mBleScanner.init(context, btAdapter);
-        } else {
-            Slog.w(TAG, "BluetoothAdapter is NOT available.");
+        BluetoothManager bm = (BluetoothManager) context.getSystemService(BLUETOOTH_SERVICE);
+        if (bm == null) {
+            Slog.w(TAG, "BluetoothManager is not available.");
+            return;
         }
+        final BluetoothAdapter btAdapter = bm.getAdapter();
+        if (btAdapter == null) {
+            Slog.w(TAG, "BluetoothAdapter is NOT available.");
+            return;
+        }
+
+        mBluetoothDeviceProcessor.init(btAdapter);
+        mBleDeviceProcessor.init(context, btAdapter);
 
         mAssociationStore.registerLocalListener(this);
     }
@@ -280,7 +282,7 @@
      * For legacy device presence below Android V.
      *
      * @deprecated Use {@link #startObservingDevicePresence(ObservingDevicePresenceRequest, String,
-     *             int)}
+     * int)}
      */
     @Deprecated
     public void startObservingDevicePresence(int userId, String packageName, String deviceAddress)
@@ -310,7 +312,7 @@
      * For legacy device presence below Android V.
      *
      * @deprecated Use {@link #stopObservingDevicePresence(ObservingDevicePresenceRequest, String,
-     *             int)}
+     * int)}
      */
     @Deprecated
     public void stopObservingDevicePresence(int userId, String packageName, String deviceAddress)
@@ -496,7 +498,7 @@
 
             // Stop the BLE scan if all devices report BT connected status and BLE was present.
             if (canStopBleScan()) {
-                mBleScanner.stopScanIfNeeded();
+                mBleDeviceProcessor.stopScanIfNeeded();
             }
 
         }
@@ -513,7 +515,7 @@
         }
 
         // Start BLE scanning when the device is disconnected.
-        mBleScanner.startScan();
+        mBleDeviceProcessor.startScan();
 
         onDevicePresenceEvent(mConnectedBtDevices, associationId, EVENT_BT_DISCONNECTED);
         // If current device is BLE present but BT is disconnected , means it will be
@@ -724,7 +726,7 @@
         final ParcelUuid parcelUuid = uuid.getUuid();
         final int userId = uuid.getUserId();
         if (!mUserManager.isUserUnlockingOrUnlocked(userId)) {
-            onDeviceLocked(/* associationId */ -1, userId, eventType, parcelUuid);
+            onDeviceLocked(NO_ASSOCIATION, userId, eventType, parcelUuid);
             return;
         }
 
@@ -930,10 +932,6 @@
     @Override
     public void onAssociationRemoved(@NonNull AssociationInfo association) {
         final int id = association.getId();
-        if (DEBUG) {
-            Log.i(TAG, "onAssociationRemoved() id=" + id);
-            Log.d(TAG, "  > association=" + association);
-        }
 
         mConnectedBtDevices.remove(id);
         mNearbyBleDevices.remove(id);
@@ -1004,8 +1002,8 @@
                     if (deviceEvents != null) {
                         deviceEvents.removeIf(deviceEvent ->
                                 deviceEvent.getEvent() == EVENT_BLE_APPEARED
-                                && Objects.equals(deviceEvent.getUuid(), uuid)
-                                && deviceEvent.getAssociationId() == associationId);
+                                        && Objects.equals(deviceEvent.getUuid(), uuid)
+                                        && deviceEvent.getAssociationId() == associationId);
                     }
                 }
             }
@@ -1018,8 +1016,8 @@
                     if (deviceEvents != null) {
                         deviceEvents.removeIf(deviceEvent ->
                                 deviceEvent.getEvent() == EVENT_BT_CONNECTED
-                                && Objects.equals(deviceEvent.getUuid(), uuid)
-                                && deviceEvent.getAssociationId() == associationId);
+                                        && Objects.equals(deviceEvent.getUuid(), uuid)
+                                        && deviceEvent.getAssociationId() == associationId);
                     }
                 }
             }
@@ -1054,7 +1052,7 @@
                     return;
                 }
 
-                switch(event) {
+                switch (event) {
                     case EVENT_BLE_APPEARED:
                         onBleCompanionDeviceFound(
                                 associationInfo.getId(), associationInfo.getUserId());
diff --git a/services/companion/java/com/android/server/companion/presence/ObservableUuid.java b/services/companion/java/com/android/server/companion/devicepresence/ObservableUuid.java
similarity index 96%
rename from services/companion/java/com/android/server/companion/presence/ObservableUuid.java
rename to services/companion/java/com/android/server/companion/devicepresence/ObservableUuid.java
index 9cfa270..c9f60ca 100644
--- a/services/companion/java/com/android/server/companion/presence/ObservableUuid.java
+++ b/services/companion/java/com/android/server/companion/devicepresence/ObservableUuid.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.companion.presence;
+package com.android.server.companion.devicepresence;
 
 import android.annotation.NonNull;
 import android.annotation.UserIdInt;
diff --git a/services/companion/java/com/android/server/companion/presence/ObservableUuidStore.java b/services/companion/java/com/android/server/companion/devicepresence/ObservableUuidStore.java
similarity index 99%
rename from services/companion/java/com/android/server/companion/presence/ObservableUuidStore.java
rename to services/companion/java/com/android/server/companion/devicepresence/ObservableUuidStore.java
index fa0f6bd..4678a16 100644
--- a/services/companion/java/com/android/server/companion/presence/ObservableUuidStore.java
+++ b/services/companion/java/com/android/server/companion/devicepresence/ObservableUuidStore.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.companion.presence;
+package com.android.server.companion.devicepresence;
 
 import static com.android.internal.util.XmlUtils.readIntAttribute;
 import static com.android.internal.util.XmlUtils.readLongAttribute;
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 4a2030f..66313e6 100644
--- a/services/companion/java/com/android/server/companion/virtual/Android.bp
+++ b/services/companion/java/com/android/server/companion/virtual/Android.bp
@@ -10,6 +10,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/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
index 9e3f5ce..f38d772b 100644
--- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
+++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java
@@ -334,7 +334,7 @@
             // The error dialog alerting users that streaming is blocked is always allowed.
             return true;
         }
-        if (!mAllowedUsers.contains(activityUser)) {
+        if (!activityUser.isSystem() && !mAllowedUsers.contains(activityUser)) {
             Slog.d(TAG, "Virtual device launch disallowed from user " + activityUser);
             return false;
         }
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index 8b98d12..215f640 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -28,8 +28,6 @@
 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_CLIPBOARD;
 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_RECENTS;
 import static android.content.pm.PackageManager.ACTION_REQUEST_PERMISSIONS;
-import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
-import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 import static android.companion.virtualdevice.flags.Flags.virtualCameraServiceDiscovery;
 
 import android.annotation.EnforcePermission;
@@ -1068,6 +1066,10 @@
 
     @Override
     public boolean hasCustomAudioInputSupport() throws RemoteException {
+        return hasCustomAudioInputSupportInternal();
+    }
+
+    private boolean hasCustomAudioInputSupportInternal() {
         if (!Flags.vdmPublicApis()) {
             return false;
         }
@@ -1079,8 +1081,8 @@
             return false;
         }
 
-        if (getDevicePolicy(POLICY_TYPE_AUDIO) == VirtualDeviceParams.DEVICE_POLICY_DEFAULT) {
-            return false;
+        if (getDevicePolicy(POLICY_TYPE_AUDIO) == VirtualDeviceParams.DEVICE_POLICY_CUSTOM) {
+            return true;
         }
         final long token = Binder.clearCallingIdentity();
         try {
@@ -1108,10 +1110,10 @@
         mParams.dump(fout, indent + indent);
         fout.println(indent + "mVirtualDisplayIds: ");
         synchronized (mVirtualDeviceLock) {
-            fout.println("    mDevicePolicies: " + mDevicePolicies);
             for (int i = 0; i < mVirtualDisplays.size(); i++) {
                 fout.println(indent + "  " + mVirtualDisplays.keyAt(i));
             }
+            fout.println("    mDevicePolicies: " + mDevicePolicies);
             fout.println(indent + "mDefaultShowPointerIcon: " + mDefaultShowPointerIcon);
         }
         mInputController.dump(fout);
@@ -1119,6 +1121,8 @@
         if (mVirtualCameraController != null) {
             mVirtualCameraController.dump(fout, indent);
         }
+        fout.println(
+                indent + "hasCustomAudioInputSupport: " + hasCustomAudioInputSupportInternal());
     }
 
     // For display mirroring, we want to dispatch all key events to the source (default) display,
@@ -1150,8 +1154,8 @@
                 Flags.vdmCustomHome() ? mParams.getHomeComponent() : null;
 
         final GenericWindowPolicyController gwpc = new GenericWindowPolicyController(
-                FLAG_SECURE,
-                SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
+                WindowManager.LayoutParams.FLAG_SECURE,
+                WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
                 mAttributionSource,
                 getAllowedUserHandles(),
                 activityLaunchAllowedByDefault,
@@ -1265,7 +1269,7 @@
         // if the secure window is shown on a non-secure virtual display.
         DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
         Display display = displayManager.getDisplay(displayId);
-        if ((display.getFlags() & FLAG_SECURE) == 0) {
+        if ((display.getFlags() & Display.FLAG_SECURE) == 0) {
             showToastWhereUidIsRunning(uid, com.android.internal.R.string.vdm_secure_window,
                     Toast.LENGTH_LONG, mContext.getMainLooper());
 
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/Android.bp b/services/core/Android.bp
index 7f5867f..c7d9942 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -246,7 +246,7 @@
         "biometrics_flags_lib",
         "am_flags_lib",
         "com_android_server_accessibility_flags_lib",
-        "com_android_systemui_shared_flags_lib",
+        "//frameworks/libs/systemui:com_android_systemui_shared_flags_lib",
         "com_android_wm_shell_flags_lib",
         "com.android.server.utils_aconfig-java",
         "service-jobscheduler-deviceidle.flags-aconfig-java",
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index 25337a4..baae40b 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -62,6 +62,18 @@
             "file_patterns": ["SensorPrivacyService\\.java"]
         },
         {
+            "name": "FrameworksMockingServicesTests",
+            "options": [
+                {
+                    "include-filter": "com.android.server.SensitiveContentProtectionManagerServiceContentTest"
+                },
+                {
+                    "include-filter": "com.android.server.SensitiveContentProtectionManagerServiceNotificationTest"
+                }
+            ],
+            "file_patterns": ["SensitiveContentProtectionManagerService\\.java"]
+        },
+        {
             "name": "FrameworksServicesTests",
             "options": [
                 {
@@ -163,6 +175,9 @@
                 }
             ],
             "file_patterns": ["PinnerService\\.java"]
+        },
+        {
+            "name": "SelinuxFrameworksTests"
         }
     ]
 }
diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java
index 1d1e2d9..626fa70 100644
--- a/services/core/java/com/android/server/VpnManagerService.java
+++ b/services/core/java/com/android/server/VpnManagerService.java
@@ -1007,6 +1007,71 @@
         }
     }
 
+    /**
+     * Get the vpn profile owned by the calling uid with the given name from the vpn database.
+     *
+     * <p>Note this method should not be used for platform VPN profiles. </p>
+     *
+     * @param name The name of the profile to retrieve.
+     * @return the unstructured blob for the matching vpn profile.
+     * Returns null if no profile with a matching name was found.
+     * @hide
+     */
+    @Override
+    @Nullable
+    public byte[] getFromVpnProfileStore(@NonNull String name) {
+        return mVpnProfileStore.get(name);
+    }
+
+    /**
+     * Put the given vpn profile owned by the calling uid with the given name into the vpn database.
+     * Existing profiles with the same name will be replaced.
+     *
+     * <p>Note this method should not be used for platform VPN profiles.
+     * To update a platform VPN, use provisionVpnProfile() instead. </p>
+     *
+     * @param name The name of the profile to put.
+     * @param blob The profile.
+     * @return true if the profile was successfully added. False otherwise.
+     * @hide
+     */
+    @Override
+    public boolean putIntoVpnProfileStore(@NonNull String name, @NonNull byte[] blob) {
+        return mVpnProfileStore.put(name, blob);
+    }
+
+    /**
+     * Removes the vpn profile owned by the calling uid with the given name from the vpn database.
+     *
+     * <p>Note this method should not be used for platform VPN profiles.
+     * To remove a platform VPN, use deleteVpnProfile() instead.</p>
+     *
+     * @param name The name of the profile to be removed.
+     * @return true if a profile was removed. False if no profile with a matching name was found.
+     * @hide
+     */
+    @Override
+    public boolean removeFromVpnProfileStore(@NonNull String name) {
+        return mVpnProfileStore.remove(name);
+    }
+
+    /**
+     * Returns a list of the name suffixes of the vpn profiles owned by the calling uid in the vpn
+     * database matching the given prefix, sorted in ascending order.
+     *
+     * <p>Note this method should not be used for platform VPN profiles. </p>
+     *
+     * @param prefix The prefix to match.
+     * @return an array of strings representing the name suffixes stored in the profile database
+     * matching the given prefix. The return value may be empty but never null.
+     * @hide
+     */
+    @Override
+    @NonNull
+    public String[] listFromVpnProfileStore(@NonNull String prefix) {
+        return mVpnProfileStore.list(prefix);
+    }
+
     private void ensureRunningOnHandlerThread() {
         if (mHandler.getLooper().getThread() != Thread.currentThread()) {
             throw new IllegalStateException(
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 1334a95..603a95c 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -897,6 +897,11 @@
                         }
                     }
                     for (String packageNameToNotify : accountRemovedReceivers) {
+                        int currentVisibility =
+                                resolveAccountVisibility(account, packageNameToNotify, accounts);
+                        if (isVisible(currentVisibility)) {
+                            continue;
+                        }
                         sendAccountRemovedBroadcast(
                                 account,
                                 packageNameToNotify,
@@ -3666,6 +3671,11 @@
 
             // Strip auth token from result.
             result.remove(AccountManager.KEY_AUTHTOKEN);
+            if (!checkKeyIntent(Binder.getCallingUid(), result)) {
+                onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
+                        "invalid intent in bundle returned");
+                return;
+            }
 
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG,
@@ -5276,6 +5286,11 @@
                     } else {
                         if (mStripAuthTokenFromResult) {
                             result.remove(AccountManager.KEY_AUTHTOKEN);
+                            if (!checkKeyIntent(Binder.getCallingUid(), result)) {
+                                onError(AccountManager.ERROR_CODE_INVALID_RESPONSE,
+                                        "invalid intent in bundle returned");
+                                return;
+                            }
                         }
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.v(TAG, getClass().getSimpleName()
diff --git a/services/core/java/com/android/server/am/AccessCheckDelegateHelper.java b/services/core/java/com/android/server/am/AccessCheckDelegateHelper.java
new file mode 100644
index 0000000..62c6329
--- /dev/null
+++ b/services/core/java/com/android/server/am/AccessCheckDelegateHelper.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.annotation.Nullable;
+import android.os.Process;
+import android.os.UserHandle;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.server.appop.AppOpsService;
+import com.android.server.pm.permission.AccessCheckDelegate;
+import com.android.server.pm.permission.PermissionManagerServiceInternal;
+
+import java.util.Collections;
+import java.util.List;
+
+class AccessCheckDelegateHelper {
+    private final ActivityManagerGlobalLock mProcLock;
+
+    @GuardedBy("mProcLock")
+    private final List<ActiveInstrumentation> mActiveInstrumentation;
+
+    private final AppOpsService mAppOpsService;
+
+    private final PermissionManagerServiceInternal mPermissionManagerInternal;
+
+    @GuardedBy("mProcLock")
+    private AccessCheckDelegate mAccessCheckDelegate;
+
+    AccessCheckDelegateHelper(ActivityManagerGlobalLock procLock,
+            List<ActiveInstrumentation> activeInstrumentation, AppOpsService appOpsService,
+            PermissionManagerServiceInternal permissionManagerInternal) {
+        mProcLock = procLock;
+        mActiveInstrumentation = activeInstrumentation;
+        mAppOpsService = appOpsService;
+        mPermissionManagerInternal = permissionManagerInternal;
+    }
+
+    @GuardedBy("mProcLock")
+    private AccessCheckDelegate getAccessCheckDelegateLPr(boolean create) {
+        if (create && mAccessCheckDelegate == null) {
+            mAccessCheckDelegate = new AccessCheckDelegate.AccessCheckDelegateImpl();
+            mAppOpsService.setCheckOpsDelegate(mAccessCheckDelegate);
+            mPermissionManagerInternal.setCheckPermissionDelegate(mAccessCheckDelegate);
+        }
+
+        return mAccessCheckDelegate;
+    }
+
+    @GuardedBy("mProcLock")
+    private void removeAccessCheckDelegateLPr() {
+        mAccessCheckDelegate = null;
+        mAppOpsService.setCheckOpsDelegate(null);
+        mPermissionManagerInternal.setCheckPermissionDelegate(null);
+    }
+
+    void startDelegateShellPermissionIdentity(int delegateUid,
+            @Nullable String[] permissions) {
+        if (UserHandle.getCallingAppId() != Process.SHELL_UID
+                && UserHandle.getCallingAppId() != Process.ROOT_UID) {
+            throw new SecurityException("Only the shell can delegate its permissions");
+        }
+
+        synchronized (mProcLock) {
+            AccessCheckDelegate delegate = getAccessCheckDelegateLPr(false);
+            if (delegate != null && !delegate.isDelegateAndOwnerUid(delegateUid)) {
+                throw new SecurityException("Shell can delegate permissions only "
+                        + "to one instrumentation at a time");
+            }
+            final int instrCount = mActiveInstrumentation.size();
+            for (int i = 0; i < instrCount; i++) {
+                final ActiveInstrumentation instr =
+                        mActiveInstrumentation.get(i);
+                if (instr.mTargetInfo.uid != delegateUid) {
+                    continue;
+                }
+
+                // If instrumentation started from the shell the connection is not null
+                if (instr.mUiAutomationConnection == null) {
+                    throw new SecurityException("Shell can delegate its permissions"
+                            + " only to an instrumentation started from the shell");
+                }
+
+                final String packageName = instr.mTargetInfo.packageName;
+                delegate = getAccessCheckDelegateLPr(true);
+                delegate.setShellPermissionDelegate(delegateUid, packageName, permissions);
+                return;
+            }
+        }
+    }
+
+    void stopDelegateShellPermissionIdentity() {
+        if (UserHandle.getCallingAppId() != Process.SHELL_UID
+                && UserHandle.getCallingAppId() != Process.ROOT_UID) {
+            throw new SecurityException("Only the shell can delegate its permissions");
+        }
+        synchronized (mProcLock) {
+            AccessCheckDelegate delegate = getAccessCheckDelegateLPr(false);
+            if (delegate == null) {
+                return;
+            }
+
+            if (!delegate.hasShellPermissionDelegate()) {
+                return;
+            }
+
+            delegate.removeShellPermissionDelegate();
+
+            if (!delegate.hasDelegateOrOverrides()) {
+                removeAccessCheckDelegateLPr();
+            }
+        }
+    }
+
+    List<String> getDelegatedShellPermissions() {
+        if (UserHandle.getCallingAppId() != Process.SHELL_UID
+                && UserHandle.getCallingAppId() != Process.ROOT_UID) {
+            throw new SecurityException("Only the shell can get delegated permissions");
+        }
+        synchronized (mProcLock) {
+            AccessCheckDelegate delegate = getAccessCheckDelegateLPr(false);
+            if (delegate == null) {
+                return Collections.EMPTY_LIST;
+            }
+
+            return delegate.getDelegatedPermissionNames();
+        }
+    }
+
+    void addOverridePermissionState(int originatingUid, int uid, String permission, int result) {
+        if (UserHandle.getCallingAppId() != Process.ROOT_UID) {
+            throw new SecurityException("Only root can override permissions");
+        }
+
+        synchronized (mProcLock) {
+            final int instrCount = mActiveInstrumentation.size();
+            for (int i = 0; i < instrCount; i++) {
+                final ActiveInstrumentation instr =
+                        mActiveInstrumentation.get(i);
+                if (instr.mTargetInfo.uid != originatingUid) {
+                    continue;
+                }
+                // If instrumentation started from the shell the connection is not null
+                if (instr.mSourceUid != Process.ROOT_UID || instr.mUiAutomationConnection == null) {
+                    throw new SecurityException("Root can only override permissions only if the "
+                            + "owning app was instrumented from root.");
+                }
+
+                AccessCheckDelegate delegate =
+                        getAccessCheckDelegateLPr(true);
+                if (delegate.hasOverriddenPermissions()
+                        && !delegate.isDelegateAndOwnerUid(originatingUid)) {
+                    throw new SecurityException("Only one instrumentation to grant"
+                            + " overrides is allowed at a time.");
+                }
+
+                delegate.addOverridePermissionState(originatingUid, uid, permission, result);
+                return;
+            }
+        }
+    }
+
+    void removeOverridePermissionState(int originatingUid, int uid, String permission) {
+        if (UserHandle.getCallingAppId() != Process.ROOT_UID) {
+            throw new SecurityException("Only root can override permissions.");
+        }
+
+        synchronized (mProcLock) {
+            AccessCheckDelegate delegate = getAccessCheckDelegateLPr(false);
+            if (delegate == null) {
+                return;
+            }
+
+            if (!delegate.isDelegateAndOwnerUid(originatingUid)) {
+                if (delegate.hasOverriddenPermissions()) {
+                    throw new SecurityException("Only the granter of current overrides can remove "
+                            + "them.");
+                }
+                return;
+            }
+
+            delegate.removeOverridePermissionState(uid, permission);
+
+            if (!delegate.hasDelegateOrOverrides()) {
+                removeAccessCheckDelegateLPr();
+            }
+        }
+    }
+
+    void clearOverridePermissionStates(int originatingUid, int uid) {
+        if (UserHandle.getCallingAppId() != Process.ROOT_UID) {
+            throw new SecurityException("Only root can override permissions.");
+        }
+        synchronized (mProcLock) {
+            AccessCheckDelegate delegate = getAccessCheckDelegateLPr(false);
+            if (delegate == null) {
+                return;
+            }
+
+            if (!delegate.isDelegateAndOwnerUid(originatingUid)) {
+                if (delegate.hasOverriddenPermissions()) {
+                    throw new SecurityException(
+                            "Only the granter of current overrides can remove them.");
+                }
+                return;
+            }
+
+            delegate.clearOverridePermissionStates(uid);
+
+            if (!delegate.hasDelegateOrOverrides()) {
+                removeAccessCheckDelegateLPr();
+            }
+        }
+    }
+
+    void clearAllOverridePermissionStates(int originatingUid) {
+        if (UserHandle.getCallingAppId() != Process.ROOT_UID) {
+            throw new SecurityException("Only root can override permissions.");
+        }
+        synchronized (mProcLock) {
+            AccessCheckDelegate delegate = getAccessCheckDelegateLPr(false);
+            if (delegate == null) {
+                return;
+            }
+
+            if (!delegate.isDelegateAndOwnerUid(originatingUid)) {
+                if (delegate.hasOverriddenPermissions()) {
+                    throw new SecurityException(
+                            "Only the granter of current overrides can remove them.");
+                }
+                return;
+            }
+
+            delegate.clearAllOverridePermissionStates();
+
+            if (!delegate.hasDelegateOrOverrides()) {
+                removeAccessCheckDelegateLPr();
+            }
+        }
+    }
+
+    void onInstrumentationFinished(int uid, String packageName) {
+        synchronized (mProcLock) {
+            AccessCheckDelegate delegate = getAccessCheckDelegateLPr(false);
+            if (delegate != null) {
+                if (delegate.isDelegatePackage(uid, packageName)) {
+                    delegate.removeShellPermissionDelegate();
+                }
+                if (delegate.isDelegateAndOwnerUid(uid)) {
+                    delegate.clearAllOverridePermissionStates();
+                }
+                if (!delegate.hasDelegateOrOverrides()) {
+                    removeAccessCheckDelegateLPr();
+                }
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 90a9d1b..7ea82b0 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1192,7 +1192,7 @@
             // Use that as a shortcut if possible to avoid having to recheck all the conditions.
             final boolean whileInUseAllowsUiJobScheduling =
                     ActivityManagerService.doesReasonCodeAllowSchedulingUserInitiatedJobs(
-                            r.getFgsAllowWiu_forStart());
+                            r.getFgsAllowWiu_forStart(), callingUid);
             r.updateAllowUiJobScheduling(whileInUseAllowsUiJobScheduling
                     || mAm.canScheduleUserInitiatedJobs(callingUid, callingPid, callingPackage));
         } else {
@@ -5555,6 +5555,7 @@
             boolean enqueueOomAdj, @ServiceBindingOomAdjPolicy int serviceBindingOomAdjPolicy)
             throws TransactionTooLargeException {
         if (r.app != null && r.app.isThreadReady()) {
+            r.updateOomAdjSeq();
             sendServiceArgsLocked(r, execInFg, false);
             return null;
         }
@@ -8157,7 +8158,7 @@
                 BackgroundStartPrivileges.NONE);
         @ReasonCode int allowStartFgs = shouldAllowFgsStartForegroundNoBindingCheckLocked(
                 allowWhileInUse, callingPid, callingUid, callingPackage, null /* targetService */,
-                BackgroundStartPrivileges.NONE, null);
+                BackgroundStartPrivileges.NONE);
 
         if (allowStartFgs == REASON_DENIED) {
             if (canBindingClientStartFgsLocked(callingUid) != null) {
@@ -8413,8 +8414,7 @@
                                                 allowWhileInUse2,
                                                 clientPid, clientUid, clientPackageName,
                                                 null /* targetService */,
-                                                BackgroundStartPrivileges.NONE,
-                                                pr);
+                                                BackgroundStartPrivileges.NONE);
                                 if (allowStartFgs != REASON_DENIED) {
                                     return new Pair<>(allowStartFgs, clientPackageName);
                                 } else {
@@ -8451,7 +8451,7 @@
         ActivityManagerService.FgsTempAllowListItem tempAllowListReason =
                 r.mInfoTempFgsAllowListReason = mAm.isAllowlistedForFgsStartLOSP(callingUid);
         int ret = shouldAllowFgsStartForegroundNoBindingCheckLocked(allowWhileInUse, callingPid,
-                callingUid, callingPackage, r, backgroundStartPrivileges, null);
+                callingUid, callingPackage, r, backgroundStartPrivileges);
 
         // If an app (App 1) is bound by another app (App 2) that could start an FGS, then App 1
         // is also allowed to start an FGS. We check all the binding
@@ -8507,8 +8507,7 @@
     private @ReasonCode int shouldAllowFgsStartForegroundNoBindingCheckLocked(
             @ReasonCode int allowWhileInUse, int callingPid, int callingUid, String callingPackage,
             @Nullable ServiceRecord targetService,
-            BackgroundStartPrivileges backgroundStartPrivileges,
-            @Nullable ProcessRecord targetRecord) {
+            BackgroundStartPrivileges backgroundStartPrivileges) {
         int ret = allowWhileInUse;
 
         if (ret == REASON_DENIED) {
@@ -8565,31 +8564,24 @@
             }
         }
 
-        // The flag being enabled isn't enough to deny background start: we need to also check
-        // if there is a system alert UI present.
         if (ret == REASON_DENIED) {
-            // Flag check: are we disabling SAW FGS background starts?
-            final boolean shouldDisableSaw = Flags.fgsDisableSaw()
-                    && CompatChanges.isChangeEnabled(FGS_SAW_RESTRICTIONS, callingUid);
-            if (shouldDisableSaw) {
-                if (targetRecord == null) {
-                    synchronized (mAm.mPidsSelfLocked) {
-                        targetRecord = mAm.mPidsSelfLocked.get(callingPid);
-                    }
-                }
-                if (targetRecord != null) {
-                    if (targetRecord.mState.hasOverlayUi()) {
-                        if (mAm.mAtmInternal.hasSystemAlertWindowPermission(callingUid, callingPid,
-                                callingPackage)) {
-                            ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
+            if (mAm.mAtmInternal.hasSystemAlertWindowPermission(
+                                    callingUid, callingPid, callingPackage)) {
+                // Starting from Android V, it is not enough to only have the SYSTEM_ALERT_WINDOW
+                // permission granted - apps must also be showing an overlay window.
+                if (Flags.fgsDisableSaw()
+                        && CompatChanges.isChangeEnabled(FGS_SAW_RESTRICTIONS, callingUid)) {
+                    final UidRecord uidRecord = mAm.mProcessList.getUidRecordLOSP(callingUid);
+                    if (uidRecord != null) {
+                        for (int i = uidRecord.getNumOfProcs() - 1; i >= 0; i--) {
+                            final ProcessRecord pr = uidRecord.getProcessRecordByIndex(i);
+                            if (pr != null && pr.mState.hasOverlayUi()) {
+                                ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
+                                break;
+                            }
                         }
                     }
-                } else {
-                    Slog.e(TAG, "Could not find process record for SAW check");
-                }
-            } else {
-                if (mAm.mAtmInternal.hasSystemAlertWindowPermission(callingUid, callingPid,
-                        callingPackage)) {
+                } else { // pre-V logic
                     ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
                 }
             }
diff --git a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
index 55b161a..dcda5c2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
+++ b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
@@ -55,9 +55,7 @@
     static final boolean DEBUG_BACKGROUND_CHECK = DEBUG_ALL || false;
     static final boolean DEBUG_BACKUP = DEBUG_ALL || false;
     static final boolean DEBUG_BROADCAST = DEBUG_ALL || false;
-    static final boolean DEBUG_BROADCAST_BACKGROUND = DEBUG_BROADCAST || false;
     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
-    static final boolean DEBUG_BROADCAST_DEFERRAL = DEBUG_BROADCAST || false;
     static final boolean DEBUG_COMPACTION = DEBUG_ALL || false;
     static final boolean DEBUG_FREEZER = DEBUG_ALL || false;
     static final boolean DEBUG_LRU = DEBUG_ALL || false;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5941fd7..458bd94 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -51,7 +51,6 @@
 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SHELL;
 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SYSTEM_INIT;
 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UI_VISIBILITY;
-import static android.app.AppOpsManager.MODE_ALLOWED;
 import static android.app.AppOpsManager.OP_NONE;
 import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_BACKUP;
 import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_INSTRUMENTATION;
@@ -136,6 +135,7 @@
 import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__INTERNAL_NON_EXPORTED_COMPONENT_MATCH;
 import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NEW_MUTABLE_IMPLICIT_PENDING_INTENT_RETRIEVED;
 import static com.android.sdksandbox.flags.Flags.sdkSandboxInstrumentationInfo;
+import static com.android.server.am.ActiveServices.FGS_SAW_RESTRICTIONS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALLOWLISTS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
@@ -250,7 +250,6 @@
 import android.app.ProcessMemoryState;
 import android.app.ProfilerInfo;
 import android.app.ServiceStartNotAllowedException;
-import android.app.SyncNotedAppOp;
 import android.app.WaitResult;
 import android.app.assist.ActivityId;
 import android.app.backup.BackupAnnotations.BackupDestination;
@@ -414,6 +413,7 @@
 import com.android.internal.os.BinderCallHeavyHitterWatcher.BinderCallHeavyHitterListener;
 import com.android.internal.os.BinderCallHeavyHitterWatcher.HeavyHitterContainer;
 import com.android.internal.os.BinderInternal;
+import com.android.internal.os.BinderInternal.BinderProxyCountEventListener;
 import com.android.internal.os.BinderTransactionNameResolver;
 import com.android.internal.os.ByteTransferPipe;
 import com.android.internal.os.IResultReceiver;
@@ -425,17 +425,11 @@
 import com.android.internal.pm.pkg.parsing.ParsingPackageUtils;
 import com.android.internal.policy.AttributeCache;
 import com.android.internal.protolog.common.ProtoLog;
-import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.MemInfoReader;
 import com.android.internal.util.Preconditions;
-import com.android.internal.util.function.DodecFunction;
-import com.android.internal.util.function.HexFunction;
-import com.android.internal.util.function.OctFunction;
-import com.android.internal.util.function.QuadFunction;
-import com.android.internal.util.function.UndecFunction;
 import com.android.server.AlarmManagerInternal;
 import com.android.server.BootReceiver;
 import com.android.server.DeviceIdleInternal;
@@ -614,8 +608,8 @@
     private static final int MINIMUM_MEMORY_GROWTH_THRESHOLD = 10 * 1000; // 10 MB
 
     /**
-     * The number of binder proxies we need to have before we start warning and
-     * dumping debug info.
+     * The number of binder proxies we need to have before we start dumping debug info
+     * and kill the offenders.
      */
     private static final int BINDER_PROXY_HIGH_WATERMARK = 6000;
 
@@ -625,6 +619,11 @@
      */
     private static final int BINDER_PROXY_LOW_WATERMARK = 5500;
 
+    /**
+     * The number of binder proxies we need to have before we start warning.
+     */
+    private static final int BINDER_PROXY_WARNING_WATERMARK = 5750;
+
     // Max character limit for a notification title. If the notification title is larger than this
     // the notification will not be legible to the user.
     private static final int MAX_BUGREPORT_TITLE_SIZE = 100;
@@ -763,6 +762,8 @@
     @GuardedBy("mDeliveryGroupPolicyIgnoredActions")
     private final ArraySet<String> mDeliveryGroupPolicyIgnoredActions = new ArraySet();
 
+    private AccessCheckDelegateHelper mAccessCheckDelegateHelper;
+
     /**
      * Uids of apps with current active camera sessions.  Access synchronized on
      * the IntArray instance itself, and no other locks must be acquired while that
@@ -4417,7 +4418,9 @@
                         packageName, null, userId);
         }
 
-        if (packageName == null || uninstalling || packageStateStopped) {
+        final boolean clearPendingIntentsForStoppedApp = (android.content.pm.Flags.stayStopped()
+                && packageStateStopped);
+        if (packageName == null || uninstalling || clearPendingIntentsForStoppedApp) {
             didSomething |= mPendingIntentController.removePendingIntentsForPackage(
                     packageName, userId, appId, doit);
         }
@@ -6461,7 +6464,7 @@
      * This is a shortcut and <b>DOES NOT</b> include all reasons.
      * Use {@link #canScheduleUserInitiatedJobs(int, int, String)} to cover all cases.
      */
-    static boolean doesReasonCodeAllowSchedulingUserInitiatedJobs(int reasonCode) {
+    static boolean doesReasonCodeAllowSchedulingUserInitiatedJobs(int reasonCode, int uid) {
         switch (reasonCode) {
             case REASON_PROC_STATE_PERSISTENT:
             case REASON_PROC_STATE_PERSISTENT_UI:
@@ -6471,11 +6474,21 @@
             case REASON_SYSTEM_UID:
             case REASON_START_ACTIVITY_FLAG:
             case REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD:
-            case REASON_SYSTEM_ALERT_WINDOW_PERMISSION:
             case REASON_COMPANION_DEVICE_MANAGER:
             case REASON_BACKGROUND_ACTIVITY_PERMISSION:
             case REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION:
                 return true;
+            case REASON_SYSTEM_ALERT_WINDOW_PERMISSION:
+                if (!Flags.fgsDisableSaw()
+                        || !CompatChanges.isChangeEnabled(FGS_SAW_RESTRICTIONS, uid)) {
+                    return true;
+                } else {
+                    // With the new SAW restrictions starting Android V, only allow the app to
+                    // schedule a user-initiated job if it's currently showing an overlay window
+                    // in additional to holding the permission - this additional logic will be
+                    // checked in #canScheduleUserInitiatedJobs(int, int, String) below since this
+                    // method is simply a shortcut for checking based on the reason codes.
+                }
         }
         return false;
     }
@@ -6488,7 +6501,7 @@
      */
     @GuardedBy(anyOf = {"this", "mProcLock"})
     private boolean isProcessInStateToScheduleUserInitiatedJobsLocked(
-            @Nullable ProcessRecord pr, long nowElapsed) {
+            @Nullable ProcessRecord pr, long nowElapsed, int uid) {
         if (pr == null) {
             return false;
         }
@@ -6505,7 +6518,7 @@
         final int procstate = state.getCurProcState();
         if (procstate <= PROCESS_STATE_BOUND_TOP) {
             if (doesReasonCodeAllowSchedulingUserInitiatedJobs(
-                    getReasonCodeFromProcState(procstate))) {
+                    getReasonCodeFromProcState(procstate), uid)) {
                 return true;
             }
         }
@@ -6547,7 +6560,8 @@
             final long nowElapsed = SystemClock.elapsedRealtime();
             final BackgroundStartPrivileges backgroundStartPrivileges;
             if (processRecord != null) {
-                if (isProcessInStateToScheduleUserInitiatedJobsLocked(processRecord, nowElapsed)) {
+                if (isProcessInStateToScheduleUserInitiatedJobsLocked(
+                        processRecord, nowElapsed, uid)) {
                     return true;
                 }
                 backgroundStartPrivileges = processRecord.getBackgroundStartPrivileges();
@@ -6573,17 +6587,30 @@
             }
 
             final UidRecord uidRecord = mProcessList.getUidRecordLOSP(uid);
+            final boolean hasSawPermission = mAtmInternal.hasSystemAlertWindowPermission(uid, pid,
+                                                            pkgName);
+            final boolean strictSawCheckEnabled = Flags.fgsDisableSaw()
+                            && CompatChanges.isChangeEnabled(FGS_SAW_RESTRICTIONS, uid);
             if (uidRecord != null) {
                 for (int i = uidRecord.getNumOfProcs() - 1; i >= 0; --i) {
                     ProcessRecord pr = uidRecord.getProcessRecordByIndex(i);
-                    if (isProcessInStateToScheduleUserInitiatedJobsLocked(pr, nowElapsed)) {
+                    if (isProcessInStateToScheduleUserInitiatedJobsLocked(pr, nowElapsed, uid)) {
                         return true;
+                    } else if (hasSawPermission && strictSawCheckEnabled) {
+                        // isProcessInStateToScheduleUserInitiatedJobsLocked() doesn't do a strict
+                        // check for the SAW permission which is enabled from V onwards, so perform
+                        // that here (pre-V versions will be checked in the conditional below)
+                        // Starting Android V, only allow the app to schedule a user-initiated job
+                        // if it's granted the permission and currently showing an overlay window
+                        if (pr != null && pr.mState.hasOverlayUi()) {
+                            return true;
+                        }
                     }
                 }
             }
 
-            if (mAtmInternal.hasSystemAlertWindowPermission(uid, pid, pkgName)) {
-                // REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
+            if (hasSawPermission && !strictSawCheckEnabled) {
+                // REASON_SYSTEM_ALERT_WINDOW_PERMISSION (pre-V)
                 return true;
             }
 
@@ -6906,6 +6933,16 @@
         return mPermissionManagerInt;
     }
 
+    private AccessCheckDelegateHelper getAccessCheckDelegateHelper() {
+        // Intentionally hold no locks: in case of race conditions, the mPermissionManagerInt will
+        // be set to the same value anyway.
+        if (mAccessCheckDelegateHelper == null) {
+            mAccessCheckDelegateHelper = new AccessCheckDelegateHelper(mProcLock,
+                    mActiveInstrumentation, mAppOpsService, getPermissionManagerInternal());
+        }
+        return mAccessCheckDelegateHelper;
+    }
+
     /** Returns whether the given package was ever launched since install */
     boolean wasPackageEverLaunched(String packageName, @UserIdInt int userId) {
         boolean wasLaunched = false;
@@ -9063,34 +9100,10 @@
 
             t.traceBegin("setBinderProxies");
             BinderInternal.nSetBinderProxyCountWatermarks(BINDER_PROXY_HIGH_WATERMARK,
-                    BINDER_PROXY_LOW_WATERMARK);
+                    BINDER_PROXY_LOW_WATERMARK, BINDER_PROXY_WARNING_WATERMARK);
             BinderInternal.nSetBinderProxyCountEnabled(true);
-            BinderInternal.setBinderProxyCountCallback(
-                    (uid) -> {
-                        Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
-                                + Process.myUid());
-                        BinderProxy.dumpProxyDebugInfo();
-                        CriticalEventLog.getInstance().logExcessiveBinderCalls(uid);
-                        if (uid == Process.SYSTEM_UID) {
-                            Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
-                        } else {
-                            killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
-                                    ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE,
-                                    ApplicationExitInfo.SUBREASON_EXCESSIVE_BINDER_OBJECTS,
-                                    "Too many Binders sent to SYSTEM");
-                            // We need to run a GC here, because killing the processes involved
-                            // actually isn't guaranteed to free up the proxies; in fact, if the
-                            // GC doesn't run for a long time, we may even exceed the global
-                            // proxy limit for a process (20000), resulting in system_server itself
-                            // being killed.
-                            // Note that the GC here might not actually clean up all the proxies,
-                            // because the binder reference decrements will come in asynchronously;
-                            // but if new processes belonging to the UID keep adding proxies, we
-                            // will get another callback here, and run the GC again - this time
-                            // cleaning up the old proxies.
-                            VMRuntime.getRuntime().requestConcurrentGC();
-                        }
-                    }, mHandler);
+            BinderInternal.setBinderProxyCountCallback(new MyBinderProxyCountEventListener(),
+                    mHandler);
             t.traceEnd(); // setBinderProxies
 
             t.traceEnd(); // ActivityManagerStartApps
@@ -9105,6 +9118,46 @@
         }
     }
 
+    private class MyBinderProxyCountEventListener implements BinderProxyCountEventListener {
+        @Override
+        public void onLimitReached(int uid) {
+            Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
+                    + Process.myUid());
+            BinderProxy.dumpProxyDebugInfo();
+            CriticalEventLog.getInstance().logExcessiveBinderCalls(uid);
+            if (uid == Process.SYSTEM_UID) {
+                Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
+            } else {
+                killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid),
+                        ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE,
+                        ApplicationExitInfo.SUBREASON_EXCESSIVE_BINDER_OBJECTS,
+                        "Too many Binders sent to SYSTEM");
+                // We need to run a GC here, because killing the processes involved
+                // actually isn't guaranteed to free up the proxies; in fact, if the
+                // GC doesn't run for a long time, we may even exceed the global
+                // proxy limit for a process (20000), resulting in system_server itself
+                // being killed.
+                // Note that the GC here might not actually clean up all the proxies,
+                // because the binder reference decrements will come in asynchronously;
+                // but if new processes belonging to the UID keep adding proxies, we
+                // will get another callback here, and run the GC again - this time
+                // cleaning up the old proxies.
+                VMRuntime.getRuntime().requestConcurrentGC();
+            }
+        }
+
+        @Override
+        public void onWarningThresholdReached(int uid) {
+            if (Flags.logExcessiveBinderProxies()) {
+                Slog.w(TAG, "Uid " + uid + " sent too many ("
+                        + BINDER_PROXY_WARNING_WATERMARK + ") Binders to uid " + Process.myUid());
+                FrameworkStatsLog.write(
+                        FrameworkStatsLog.EXCESSIVE_BINDER_PROXY_COUNT_REPORTED,
+                        uid);
+            }
+        }
+    }
+
     private void watchDeviceProvisioning(Context context) {
         // setting system property based on whether device is provisioned
 
@@ -12033,18 +12086,23 @@
         for (int i=0; i<items.size(); i++) {
             MemItem mi = items.get(i);
             if (!isCompact) {
-                pw.printf("%s%s: %s%s\n", prefix, stringifyKBSize(dumpPss ? mi.pss : mi.mRss),
+                String printFormat = "%s%s: %s%s\n";
+                if ((dumpPss && dumpSwapPss) || dumpPrivateDirty) {
+                    StringBuilder format = new StringBuilder();
+                    format.append("%s%s: %-60s%s");
+                    if (dumpSwapPss) {
+                        format.append(String.format("(%s in swap%s", stringifyKBSize(mi.swapPss),
+                                dumpPrivateDirty ? ", " : ")"));
+                    }
+                    if (dumpPrivateDirty) {
+                        format.append(String.format("%s%s private dirty)", dumpSwapPss ? "" : "(",
+                                stringifyKBSize(mi.mPrivateDirty)));
+                    }
+                    printFormat = format.append("\n").toString();
+                }
+                pw.printf(printFormat, prefix, stringifyKBSize(dumpPss ? mi.pss : mi.mRss),
                             mi.label,
                             mi.userId != UserHandle.USER_SYSTEM ? " (user " + mi.userId + ")" : "");
-                if (dumpPss && dumpSwapPss) {
-                    pw.printf("(%s in swap%s", stringifyKBSize(mi.swapPss),
-                            dumpPrivateDirty ? ", " : ")");
-                }
-                if (dumpPrivateDirty) {
-                    pw.printf("%s%s private dirty)", dumpSwapPss ? "" : "(",
-                            stringifyKBSize(mi.mPrivateDirty));
-                }
-                pw.printf("\n");
             } else if (mi.isProc) {
                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
                 pw.print(","); pw.print(mi.id); pw.print(",");
@@ -16551,8 +16609,8 @@
                         // Go back to the default mode of denying OP_NO_ISOLATED_STORAGE app op.
                         mAppOpsService.setMode(AppOpsManager.OP_NO_ISOLATED_STORAGE, app.uid,
                                 app.info.packageName, AppOpsManager.MODE_ERRORED);
-                        mAppOpsService.setAppOpsServiceDelegate(null);
-                        getPermissionManagerInternal().stopShellPermissionIdentityDelegation();
+                        getAccessCheckDelegateHelper()
+                                .onInstrumentationFinished(app.uid, app.info.packageName);
                         mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
                                 instr.mUiAutomationConnection).sendToTarget();
                     }
@@ -17566,7 +17624,8 @@
 
     @Override
     public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
-            boolean runGc, String path, ParcelFileDescriptor fd, RemoteCallback finishCallback) {
+            boolean runGc, String dumpBitmaps,
+            String path, ParcelFileDescriptor fd, RemoteCallback finishCallback) {
         try {
             // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
             // its own permission (same as profileControl).
@@ -17600,7 +17659,8 @@
                         }
                     }, null);
 
-                thread.dumpHeap(managed, mallocInfo, runGc, path, fd, intermediateCallback);
+                thread.dumpHeap(managed, mallocInfo, runGc, dumpBitmaps,
+                                path, fd, intermediateCallback);
                 fd = null;
                 return true;
             }
@@ -18075,7 +18135,8 @@
         public ComponentName startSdkSandboxService(Intent service, int clientAppUid,
                 String clientAppPackage, String processName) throws RemoteException {
             validateSdkSandboxParams(service, clientAppUid, clientAppPackage, processName);
-            if (mAppOpsService.checkPackage(clientAppUid, clientAppPackage) != MODE_ALLOWED) {
+            if (mAppOpsService.checkPackage(clientAppUid, clientAppPackage)
+                    != AppOpsManager.MODE_ALLOWED) {
                 throw new IllegalArgumentException("uid does not belong to provided package");
             }
             // TODO(b/269598719): Is passing the application thread of the system_server alright?
@@ -18144,7 +18205,8 @@
                 String processName, long flags)
                 throws RemoteException {
             validateSdkSandboxParams(service, clientAppUid, clientAppPackage, processName);
-            if (mAppOpsService.checkPackage(clientAppUid, clientAppPackage) != MODE_ALLOWED) {
+            if (mAppOpsService.checkPackage(clientAppUid, clientAppPackage)
+                    != AppOpsManager.MODE_ALLOWED) {
                 throw new IllegalArgumentException("uid does not belong to provided package");
             }
             if (conn == null) {
@@ -20452,268 +20514,41 @@
     @Override
     public void startDelegateShellPermissionIdentity(int delegateUid,
             @Nullable String[] permissions) {
-        if (UserHandle.getCallingAppId() != Process.SHELL_UID
-                && UserHandle.getCallingAppId() != Process.ROOT_UID) {
-            throw new SecurityException("Only the shell can delegate its permissions");
-        }
-
-        // We allow delegation only to one instrumentation started from the shell
-        synchronized (mProcLock) {
-            // If the delegate is already set up for the target UID, nothing to do.
-            if (mAppOpsService.getAppOpsServiceDelegate() != null) {
-                if (!(mAppOpsService.getAppOpsServiceDelegate() instanceof ShellDelegate)) {
-                    throw new IllegalStateException("Bad shell delegate state");
-                }
-                final ShellDelegate delegate = (ShellDelegate) mAppOpsService
-                        .getAppOpsServiceDelegate();
-                if (delegate.getDelegateUid() != delegateUid) {
-                    throw new SecurityException("Shell can delegate permissions only "
-                            + "to one instrumentation at a time");
-                }
-            }
-
-            final int instrCount = mActiveInstrumentation.size();
-            for (int i = 0; i < instrCount; i++) {
-                final ActiveInstrumentation instr = mActiveInstrumentation.get(i);
-                if (instr.mTargetInfo.uid != delegateUid) {
-                    continue;
-                }
-                // If instrumentation started from the shell the connection is not null
-                if (instr.mUiAutomationConnection == null) {
-                    throw new SecurityException("Shell can delegate its permissions" +
-                            " only to an instrumentation started from the shell");
-                }
-
-                // Hook them up...
-                final ShellDelegate shellDelegate = new ShellDelegate(delegateUid,
-                        permissions);
-                mAppOpsService.setAppOpsServiceDelegate(shellDelegate);
-                final String packageName = instr.mTargetInfo.packageName;
-                final List<String> permissionNames = permissions != null ?
-                        Arrays.asList(permissions) : null;
-                getPermissionManagerInternal().startShellPermissionIdentityDelegation(
-                        delegateUid, packageName, permissionNames);
-                return;
-            }
-        }
+        getAccessCheckDelegateHelper()
+                .startDelegateShellPermissionIdentity(delegateUid, permissions);
     }
 
     @Override
     public void stopDelegateShellPermissionIdentity() {
-        if (UserHandle.getCallingAppId() != Process.SHELL_UID
-                && UserHandle.getCallingAppId() != Process.ROOT_UID) {
-            throw new SecurityException("Only the shell can delegate its permissions");
-        }
-        synchronized (mProcLock) {
-            mAppOpsService.setAppOpsServiceDelegate(null);
-            getPermissionManagerInternal().stopShellPermissionIdentityDelegation();
-        }
+        getAccessCheckDelegateHelper().stopDelegateShellPermissionIdentity();
     }
 
     @Override
     public List<String> getDelegatedShellPermissions() {
-        if (UserHandle.getCallingAppId() != Process.SHELL_UID
-                && UserHandle.getCallingAppId() != Process.ROOT_UID) {
-            throw new SecurityException("Only the shell can get delegated permissions");
-        }
-        synchronized (mProcLock) {
-            return getPermissionManagerInternal().getDelegatedShellPermissions();
-        }
+        return getAccessCheckDelegateHelper().getDelegatedShellPermissions();
     }
 
-    private class ShellDelegate implements CheckOpsDelegate {
-        private final int mTargetUid;
-        @Nullable
-        private final String[] mPermissions;
+    @Override
+    public void addOverridePermissionState(int originatingUid, int uid, String permission,
+            int result) {
+        getAccessCheckDelegateHelper()
+                .addOverridePermissionState(originatingUid, uid, permission, result);
+    }
 
-        ShellDelegate(int targetUid, @Nullable String[] permissions) {
-            mTargetUid = targetUid;
-            mPermissions = permissions;
-        }
+    @Override
+    public void removeOverridePermissionState(int originatingUid, int uid, String permission) {
+        getAccessCheckDelegateHelper()
+                .removeOverridePermissionState(originatingUid, uid, permission);
+    }
 
-        int getDelegateUid() {
-            return mTargetUid;
-        }
+    @Override
+    public void clearOverridePermissionStates(int originatingUid, int uid) {
+        getAccessCheckDelegateHelper().clearOverridePermissionStates(originatingUid, uid);
+    }
 
-        @Override
-        public int checkOperation(int code, int uid, String packageName, String attributionTag,
-                int virtualDeviceId, boolean raw, HexFunction<Integer, Integer, String, String,
-                        Integer, Boolean, Integer> superImpl) {
-            if (uid == mTargetUid && isTargetOp(code)) {
-                final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
-                        Process.SHELL_UID);
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    return superImpl.apply(code, shellUid, "com.android.shell", null,
-                            virtualDeviceId, raw);
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-            return superImpl.apply(code, uid, packageName, attributionTag, virtualDeviceId, raw);
-        }
-
-        @Override
-        public int checkAudioOperation(int code, int usage, int uid, String packageName,
-                QuadFunction<Integer, Integer, Integer, String, Integer> superImpl) {
-            if (uid == mTargetUid && isTargetOp(code)) {
-                final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
-                        Process.SHELL_UID);
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    return superImpl.apply(code, usage, shellUid, "com.android.shell");
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-            return superImpl.apply(code, usage, uid, packageName);
-        }
-
-        @Override
-        public SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
-                @Nullable String featureId, int virtualDeviceId, boolean shouldCollectAsyncNotedOp,
-                @Nullable String message, boolean shouldCollectMessage,
-                @NonNull OctFunction<Integer, Integer, String, String, Integer, Boolean, String,
-                        Boolean, SyncNotedAppOp> superImpl) {
-            if (uid == mTargetUid && isTargetOp(code)) {
-                final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
-                        Process.SHELL_UID);
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    return superImpl.apply(code, shellUid, "com.android.shell", featureId,
-                            virtualDeviceId, shouldCollectAsyncNotedOp, message,
-                            shouldCollectMessage);
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-            return superImpl.apply(code, uid, packageName, featureId, virtualDeviceId,
-                    shouldCollectAsyncNotedOp, message, shouldCollectMessage);
-        }
-
-        @Override
-        public SyncNotedAppOp noteProxyOperation(int code,
-                @NonNull AttributionSource attributionSource, boolean shouldCollectAsyncNotedOp,
-                @Nullable String message, boolean shouldCollectMessage, boolean skiProxyOperation,
-                @NonNull HexFunction<Integer, AttributionSource, Boolean, String, Boolean,
-                                Boolean, SyncNotedAppOp> superImpl) {
-            if (attributionSource.getUid() == mTargetUid && isTargetOp(code)) {
-                final int shellUid = UserHandle.getUid(UserHandle.getUserId(
-                        attributionSource.getUid()), Process.SHELL_UID);
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    return superImpl.apply(code, new AttributionSource(shellUid,
-                            Process.INVALID_PID, "com.android.shell",
-                            attributionSource.getAttributionTag(), attributionSource.getToken(),
-                            /*renouncedPermissions*/ null, attributionSource.getDeviceId(),
-                            attributionSource.getNext()),
-                            shouldCollectAsyncNotedOp, message, shouldCollectMessage,
-                            skiProxyOperation);
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-            return superImpl.apply(code, attributionSource, shouldCollectAsyncNotedOp,
-                    message, shouldCollectMessage, skiProxyOperation);
-        }
-
-        @Override
-        public SyncNotedAppOp startOperation(IBinder token, int code, int uid,
-                @Nullable String packageName, @Nullable String attributionTag, int virtualDeviceId,
-                boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
-                @Nullable String message, boolean shouldCollectMessage,
-                @AttributionFlags int attributionFlags, int attributionChainId,
-                @NonNull DodecFunction<IBinder, Integer, Integer, String, String, Integer, Boolean,
-                        Boolean, String, Boolean, Integer, Integer, SyncNotedAppOp> superImpl) {
-            if (uid == mTargetUid && isTargetOp(code)) {
-                final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
-                        Process.SHELL_UID);
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    return superImpl.apply(token, code, shellUid, "com.android.shell",
-                            attributionTag, virtualDeviceId, startIfModeDefault,
-                            shouldCollectAsyncNotedOp, message, shouldCollectMessage,
-                            attributionFlags, attributionChainId);
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-            return superImpl.apply(token, code, uid, packageName, attributionTag, virtualDeviceId,
-                    startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
-                    attributionFlags, attributionChainId);
-        }
-
-        @Override
-        public SyncNotedAppOp startProxyOperation(@NonNull IBinder clientId, int code,
-                @NonNull AttributionSource attributionSource, boolean startIfModeDefault,
-                boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
-                boolean skipProxyOperation, @AttributionFlags int proxyAttributionFlags,
-                @AttributionFlags int proxiedAttributionFlags, int attributionChainId,
-                @NonNull UndecFunction<IBinder, Integer, AttributionSource,
-                        Boolean, Boolean, String, Boolean, Boolean, Integer, Integer, Integer,
-                        SyncNotedAppOp> superImpl) {
-            if (attributionSource.getUid() == mTargetUid && isTargetOp(code)) {
-                final int shellUid = UserHandle.getUid(UserHandle.getUserId(
-                        attributionSource.getUid()), Process.SHELL_UID);
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    return superImpl.apply(clientId, code, new AttributionSource(shellUid,
-                            Process.INVALID_PID, "com.android.shell",
-                            attributionSource.getAttributionTag(), attributionSource.getToken(),
-                            /*renouncedPermissions*/ null, attributionSource.getDeviceId(),
-                            attributionSource.getNext()),
-                            startIfModeDefault, shouldCollectAsyncNotedOp, message,
-                            shouldCollectMessage, skipProxyOperation, proxyAttributionFlags,
-                            proxiedAttributionFlags, attributionChainId);
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-            return superImpl.apply(clientId, code, attributionSource, startIfModeDefault,
-                    shouldCollectAsyncNotedOp, message, shouldCollectMessage, skipProxyOperation,
-                    proxyAttributionFlags, proxiedAttributionFlags, attributionChainId);
-        }
-
-        @Override
-        public void finishProxyOperation(@NonNull IBinder clientId, int code,
-                @NonNull AttributionSource attributionSource, boolean skipProxyOperation,
-                @NonNull QuadFunction<IBinder, Integer, AttributionSource, Boolean,
-                        Void> superImpl) {
-            if (attributionSource.getUid() == mTargetUid && isTargetOp(code)) {
-                final int shellUid = UserHandle.getUid(UserHandle.getUserId(
-                        attributionSource.getUid()), Process.SHELL_UID);
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    superImpl.apply(clientId, code, new AttributionSource(shellUid,
-                            Process.INVALID_PID, "com.android.shell",
-                            attributionSource.getAttributionTag(), attributionSource.getToken(),
-                            /*renouncedPermissions*/ null, attributionSource.getDeviceId(),
-                            attributionSource.getNext()),
-                            skipProxyOperation);
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-            superImpl.apply(clientId, code, attributionSource, skipProxyOperation);
-        }
-
-        private boolean isTargetOp(int code) {
-            // null permissions means all ops are targeted
-            if (mPermissions == null) {
-                return true;
-            }
-            // no permission for the op means the op is targeted
-            final String permission = AppOpsManager.opToPermission(code);
-            if (permission == null) {
-                return true;
-            }
-            return isTargetPermission(permission);
-        }
-
-        private boolean isTargetPermission(@NonNull String permission) {
-            // null permissions means all permissions are targeted
-            return (mPermissions == null || ArrayUtils.contains(mPermissions, permission));
-        }
+    @Override
+    public void clearAllOverridePermissionStates(int originatingUid) {
+        getAccessCheckDelegateHelper().clearAllOverridePermissionStates(originatingUid);
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 5a97e87..755631c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -1239,6 +1239,7 @@
         final PrintWriter err = getErrPrintWriter();
         boolean managed = true;
         boolean mallocInfo = false;
+        String dumpBitmaps = null;
         int userId = UserHandle.USER_CURRENT;
         boolean runGc = false;
 
@@ -1257,6 +1258,11 @@
             } else if (opt.equals("-m")) {
                 managed = false;
                 mallocInfo = true;
+            } else if (opt.equals("-b")) {
+                dumpBitmaps = getNextArg();
+                if (dumpBitmaps == null) {
+                    dumpBitmaps = "png"; // default to PNG in dumping bitmaps
+                }
             } else {
                 err.println("Error: Unknown option: " + opt);
                 return -1;
@@ -1288,8 +1294,8 @@
             }
         }, null);
 
-        if (!mInterface.dumpHeap(process, userId, managed, mallocInfo, runGc, heapFile, fd,
-                finishCallback)) {
+        if (!mInterface.dumpHeap(process, userId, managed, mallocInfo, runGc, dumpBitmaps,
+                heapFile, fd, finishCallback)) {
             err.println("HEAP DUMP FAILED on process " + process);
             return -1;
         }
@@ -4284,11 +4290,14 @@
             pw.println("      --user <USER_ID> | current: When supplying a process name,");
             pw.println("          specify user of process to profile; uses current user if not");
             pw.println("          specified.");
-            pw.println("  dumpheap [--user <USER_ID> current] [-n] [-g] <PROCESS> <FILE>");
+            pw.println("  dumpheap [--user <USER_ID> current] [-n] [-g] [-b <format>] ");
+            pw.println("           <PROCESS> <FILE>");
             pw.println("      Dump the heap of a process.  The given <PROCESS> argument may");
             pw.println("        be either a process name or pid.  Options are:");
             pw.println("      -n: dump native heap instead of managed heap");
             pw.println("      -g: force GC before dumping the heap");
+            pw.println("      -b <format>: dump contents of bitmaps in the format specified,");
+            pw.println("         which can be \"png\", \"jpg\" or \"webp\".");
             pw.println("      --user <USER_ID> | current: When supplying a process name,");
             pw.println("          specify user of process to dump; uses current user if not specified.");
             pw.println("  set-debug-app [-w] [--persistent] <PACKAGE>");
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/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java
index 147f8d1..374abe0 100644
--- a/services/core/java/com/android/server/am/AppBatteryTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryTracker.java
@@ -2014,7 +2014,7 @@
             if (!mBgCurrentDrainHighThresholdByBgLocation) {
                 return false;
             }
-            if (mTracker.mContext.checkPermission(ACCESS_BACKGROUND_LOCATION,
+            if (mTracker.mInjector.checkPermission(ACCESS_BACKGROUND_LOCATION,
                     Process.INVALID_PID, uid) == PERMISSION_GRANTED) {
                 return true;
             }
diff --git a/services/core/java/com/android/server/am/AppPermissionTracker.java b/services/core/java/com/android/server/am/AppPermissionTracker.java
index c641b35..a47beae 100644
--- a/services/core/java/com/android/server/am/AppPermissionTracker.java
+++ b/services/core/java/com/android/server/am/AppPermissionTracker.java
@@ -293,7 +293,7 @@
                 mPermissionGranted = true;
                 return;
             }
-            mPermissionGranted = mContext.checkPermission(mPermission, Process.INVALID_PID, mUid)
+            mPermissionGranted = mInjector.checkPermission(mPermission, Process.INVALID_PID, mUid)
                     == PERMISSION_GRANTED;
         }
 
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index 51aae77..6c16fba0 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -1051,7 +1051,9 @@
                                     + mProfile.mApp + " to " + mDumpUri.getPath());
                         }
                         thread.dumpHeap(/* managed= */ true,
-                                /* mallocInfo= */ false, /* runGc= */ false,
+                                /* mallocInfo= */ false,
+                                /* runGc= */ false,
+                                /* dumpbitmaps= */ null,
                                 mDumpUri.getPath(), fd,
                                 /* finishCallback= */ null);
                     } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index 88f6bc9..8b1300b 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -235,6 +235,7 @@
     private final HandlerThread mBgHandlerThread;
     private final BgHandler mBgHandler;
     private final HandlerExecutor mBgExecutor;
+    private final HandlerExecutor mExecutor;
 
     // No lock is needed, as it's immutable after initialization in constructor.
     private final ArrayList<BaseAppStateTracker> mAppStateTrackers = new ArrayList<>();
@@ -1489,6 +1490,7 @@
         mConstantsObserver = new ConstantsObserver(mBgHandler, mContext);
         mNotificationHelper = new NotificationHelper(this);
         injector.initAppStateTrackers(this);
+        mExecutor = new HandlerExecutor(injector.getDefaultHandler());
     }
 
     void onSystemReady() {
@@ -1506,7 +1508,7 @@
         mInjector.getAppStateTracker().addBackgroundRestrictedAppListener(
                 mBackgroundRestrictionListener);
         mInjector.getAppStandbyInternal().addListener(mAppIdleStateChangeListener);
-        mInjector.getRoleManager().addOnRoleHoldersChangedListenerAsUser(mBgExecutor,
+        mInjector.getRoleManager().addOnRoleHoldersChangedListenerAsUser(mExecutor,
                 mRoleHolderChangedListener, UserHandle.ALL);
         mInjector.scheduleInitTrackers(mBgHandler, () -> {
             for (int i = 0, size = mAppStateTrackers.size(); i < size; i++) {
@@ -2896,7 +2898,7 @@
         for (int i = 0; i < numPhones; i++) {
             final PhoneCarrierPrivilegesCallback callback = new PhoneCarrierPrivilegesCallback(i);
             callbacks.add(callback);
-            telephonyManager.registerCarrierPrivilegesCallback(i, mBgExecutor, callback);
+            telephonyManager.registerCarrierPrivilegesCallback(i, mExecutor, callback);
         }
         mCarrierPrivilegesCallbacks = callbacks;
     }
@@ -3288,6 +3290,10 @@
             return System.currentTimeMillis();
         }
 
+        Handler getDefaultHandler() {
+            return mAppRestrictionController.mActivityManagerService.mHandler;
+        }
+
         boolean isTest() {
             return false;
         }
diff --git a/services/core/java/com/android/server/am/BaseAppStateTracker.java b/services/core/java/com/android/server/am/BaseAppStateTracker.java
index 8d60910..5179d58 100644
--- a/services/core/java/com/android/server/am/BaseAppStateTracker.java
+++ b/services/core/java/com/android/server/am/BaseAppStateTracker.java
@@ -75,11 +75,11 @@
     static final int STATE_TYPE_INDEX_PERMISSION = 4;
 
     protected final AppRestrictionController mAppRestrictionController;
-    protected final Injector<T> mInjector;
     protected final Context mContext;
     protected final Handler mBgHandler;
     protected final Object mLock;
     protected final ArrayList<StateListener> mStateListeners = new ArrayList<>();
+    final Injector<T> mInjector;
 
     interface StateListener {
         void onStateChange(int uid, String packageName, boolean start, long now, int stateType);
@@ -292,6 +292,7 @@
         RoleManager mRoleManager;
         NotificationManagerInternal mNotificationManagerInternal;
         IAppOpsService mIAppOpsService;
+        Context mContext;
 
         void setPolicy(T policy) {
             mAppStatePolicy = policy;
@@ -316,6 +317,7 @@
                     NotificationManagerInternal.class);
             mIAppOpsService = IAppOpsService.Stub.asInterface(
                     ServiceManager.getService(Context.APP_OPS_SERVICE));
+            mContext = context;
 
             getPolicy().onSystemReady();
         }
@@ -390,5 +392,9 @@
         IAppOpsService getIAppOpsService() {
             return mIAppOpsService;
         }
+
+        int checkPermission(String perm, int pid, int uid) {
+            return mContext.checkPermission(perm, pid, uid);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index de27bc7..fa6b54b 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -98,6 +98,8 @@
 import java.util.Random;
 import java.util.Set;
 
+import dalvik.annotation.optimization.NeverCompile;
+
 public final class CachedAppOptimizer {
 
     // Flags stored in the DeviceConfig API.
@@ -582,6 +584,7 @@
             mTotalCpuTimeMillis += totalCpuTimeMillis;
         }
 
+        @NeverCompile
         public void dump(PrintWriter pw) {
             long totalCompactRequested = mSomeCompactRequested + mFullCompactRequested;
             long totalCompactPerformed = mSomeCompactPerformed + mFullCompactPerformed;
@@ -735,6 +738,7 @@
     }
 
     @GuardedBy("mProcLock")
+    @NeverCompile
     void dump(PrintWriter pw) {
         pw.println("CachedAppOptimizer settings");
         synchronized (mPhenotypeFlagLock) {
@@ -1835,6 +1839,7 @@
             return mRssAfterCompaction;
         }
 
+        @NeverCompile
         void dump(PrintWriter pw) {
             pw.println("    (" + mProcessName + "," + mSourceType.name() + "," + mDeltaAnonRssKBs
                     + "," + mZramConsumedKBs + "," + mAnonMemFreedKBs + "," + getCompactEfficiency()
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index bf7cc10..b517631 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -9,7 +9,6 @@
 sudheersai@google.com
 suprabh@google.com
 varunshah@google.com
-kwekua@google.com
 bookatz@google.com
 jji@google.com
 
@@ -18,6 +17,7 @@
 
 # Permissions & Packages
 patb@google.com
+per-file AccessCheckDelegateHelper.java = file:/core/java/android/permission/OWNERS
 
 # Battery Stats
 joeo@google.com
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 9c1ce66..5a750c2 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -71,7 +71,7 @@
 import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK;
 import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
 import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL;
-import static android.media.audio.Flags.foregroundAudioControl;
+import static android.media.audio.Flags.roForegroundAudioControl;
 import static android.os.Process.SCHED_OTHER;
 import static android.os.Process.THREAD_GROUP_BACKGROUND;
 import static android.os.Process.THREAD_GROUP_DEFAULT;
@@ -2212,7 +2212,7 @@
                             (fgsType & FOREGROUND_SERVICE_TYPE_LOCATION)
                                     != 0 ? PROCESS_CAPABILITY_FOREGROUND_LOCATION : 0;
 
-                    if (foregroundAudioControl()) { // flag check
+                    if (roForegroundAudioControl()) { // flag check
                         final int fgsAudioType = FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
                                 | FOREGROUND_SERVICE_TYPE_CAMERA
                                 | FOREGROUND_SERVICE_TYPE_MICROPHONE
diff --git a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
index a8fe734..ea92571 100644
--- a/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
+++ b/services/core/java/com/android/server/am/ProcessCachedOptimizerRecord.java
@@ -25,6 +25,8 @@
 
 import java.io.PrintWriter;
 
+import dalvik.annotation.optimization.NeverCompile;
+
 /**
  * The state info of app when it's cached, used by the optimizer.
  */
@@ -340,6 +342,7 @@
     }
 
     @GuardedBy("mProcLock")
+    @NeverCompile
     void dump(PrintWriter pw, String prefix, long nowUptime) {
         pw.print(prefix); pw.print("lastCompactTime="); pw.print(mLastCompactTime);
         pw.print(" lastCompactProfile=");
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 48a9d6a..6779f7a 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -351,6 +351,7 @@
     // LMK_UPDATE_PROPS
     // LMK_KILL_OCCURRED
     // LMK_START_MONITORING
+    // LMK_BOOT_COMPLETED
     static final byte LMK_TARGET = 0;
     static final byte LMK_PROCPRIO = 1;
     static final byte LMK_PROCREMOVE = 2;
@@ -361,6 +362,7 @@
     static final byte LMK_UPDATE_PROPS = 7;
     static final byte LMK_KILL_OCCURRED = 8; // Msg to subscribed clients on kill occurred event
     static final byte LMK_START_MONITORING = 9; // Start monitoring if delayed earlier
+    static final byte LMK_BOOT_COMPLETED = 10;
 
     // Low Memory Killer Daemon command codes.
     // These must be kept in sync with async_event_type definitions in lmkd.h
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index fd847f1..e1ccf4d 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 0673013..54e4571 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/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index fb62785..debd9d0 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -2671,14 +2671,10 @@
         }
     }
 
-    public CheckOpsDelegate getAppOpsServiceDelegate() {
-        synchronized (AppOpsService.this) {
-            final CheckOpsDelegateDispatcher dispatcher = mCheckOpsDelegateDispatcher;
-            return (dispatcher != null) ? dispatcher.getCheckOpsDelegate() : null;
-        }
-    }
-
-    public void setAppOpsServiceDelegate(CheckOpsDelegate delegate) {
+    /**
+     * Sets the CheckOpDelegate
+     */
+    public void setCheckOpsDelegate(CheckOpsDelegate delegate) {
         synchronized (AppOpsService.this) {
             final CheckOpsDelegateDispatcher oldDispatcher = mCheckOpsDelegateDispatcher;
             final CheckOpsDelegate policy = (oldDispatcher != null) ? oldDispatcher.mPolicy : null;
@@ -7157,10 +7153,6 @@
             mCheckOpsDelegate = checkOpsDelegate;
         }
 
-        public @NonNull CheckOpsDelegate getCheckOpsDelegate() {
-            return mCheckOpsDelegate;
-        }
-
         public int checkOperation(int code, int uid, String packageName,
                 @Nullable String attributionTag, int virtualDeviceId, boolean raw) {
             if (mPolicy != null) {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 951f676..77654d4 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -1517,8 +1517,9 @@
         sendLMsgNoDelay(MSG_L_SYNCHRONIZE_ADI_DEVICES_IN_INVENTORY, SENDMSG_QUEUE, deviceState);
     }
 
-    /*package*/ void postUpdatedAdiDeviceState(AdiDeviceState deviceState) {
-        sendLMsgNoDelay(MSG_L_UPDATED_ADI_DEVICE_STATE, SENDMSG_QUEUE, deviceState);
+    /*package*/ void postUpdatedAdiDeviceState(AdiDeviceState deviceState, boolean initSA) {
+        sendILMsgNoDelay(
+                MSG_IL_UPDATED_ADI_DEVICE_STATE, SENDMSG_QUEUE, initSA ? 1 : 0, deviceState);
     }
 
     /*package*/ static final class CommunicationDeviceInfo {
@@ -1820,18 +1821,17 @@
                                         + "received with null profile proxy: "
                                         + btInfo)).printLog(TAG));
                     } else {
-                        @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec =
+                        final Pair<Integer, Boolean> codecAndChanged =
                                 mBtHelper.getCodecWithFallback(btInfo.mDevice,
                                         btInfo.mProfile, btInfo.mIsLeOutput,
                                         "MSG_L_SET_BT_ACTIVE_DEVICE");
                         synchronized (mSetModeLock) {
                             synchronized (mDeviceStateLock) {
-                                mDeviceInventory.onSetBtActiveDevice(btInfo, codec,
-                                        (btInfo.mProfile
-                                                != BluetoothProfile.LE_AUDIO
+                                mDeviceInventory.onSetBtActiveDevice(btInfo, codecAndChanged.first,
+                                        (btInfo.mProfile != BluetoothProfile.LE_AUDIO
                                                 || btInfo.mIsLeOutput)
-                                                ? mAudioService.getBluetoothContextualVolumeStream()
-                                                : AudioSystem.STREAM_DEFAULT);
+                                            ? mAudioService.getBluetoothContextualVolumeStream()
+                                            : AudioSystem.STREAM_DEFAULT);
                                 if (btInfo.mProfile == BluetoothProfile.LE_AUDIO
                                         || btInfo.mProfile
                                         == BluetoothProfile.HEARING_AID) {
@@ -1866,13 +1866,13 @@
                     break;
                 case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: {
                     final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj;
-                    @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec =
-                            mBtHelper.getCodecWithFallback(btInfo.mDevice,
-                                    btInfo.mProfile, btInfo.mIsLeOutput,
-                                    "MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE");
+                    final Pair<Integer, Boolean> codecAndChanged = mBtHelper.getCodecWithFallback(
+                            btInfo.mDevice, btInfo.mProfile, btInfo.mIsLeOutput,
+                            "MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE");
                     synchronized (mDeviceStateLock) {
-                        mDeviceInventory.onBluetoothDeviceConfigChange(
-                                btInfo, codec, BtHelper.EVENT_DEVICE_CONFIG_CHANGE);
+                        mDeviceInventory.onBluetoothDeviceConfigChange(btInfo,
+                                codecAndChanged.first, codecAndChanged.second,
+                                BtHelper.EVENT_DEVICE_CONFIG_CHANGE);
                     }
                 } break;
                 case MSG_BROADCAST_AUDIO_BECOMING_NOISY:
@@ -2049,8 +2049,8 @@
                         }
                     } break;
 
-                case MSG_L_UPDATED_ADI_DEVICE_STATE:
-                    mAudioService.onUpdatedAdiDeviceState((AdiDeviceState) msg.obj);
+                case MSG_IL_UPDATED_ADI_DEVICE_STATE:
+                    mAudioService.onUpdatedAdiDeviceState((AdiDeviceState) msg.obj, msg.arg1 == 1);
                     break;
 
                 default:
@@ -2137,7 +2137,7 @@
     private static final int MSG_CHECK_COMMUNICATION_ROUTE_CLIENT_STATE = 56;
     private static final int MSG_I_UPDATE_LE_AUDIO_GROUP_ADDRESSES = 57;
     private static final int MSG_L_SYNCHRONIZE_ADI_DEVICES_IN_INVENTORY = 58;
-    private static final int MSG_L_UPDATED_ADI_DEVICE_STATE = 59;
+    private static final int MSG_IL_UPDATED_ADI_DEVICE_STATE = 59;
 
 
 
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 14428c4..f38b381 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -173,7 +173,7 @@
                 if (ads.getAudioDeviceCategory() != category && (userDefined
                         || category != AUDIO_DEVICE_CATEGORY_UNKNOWN)) {
                     ads.setAudioDeviceCategory(category);
-                    mDeviceBroker.postUpdatedAdiDeviceState(ads);
+                    mDeviceBroker.postUpdatedAdiDeviceState(ads, false /*initSA*/);
                     mDeviceBroker.postPersistAudioDeviceSettings();
                 }
                 mDeviceBroker.postSynchronizeAdiDevicesInInventory(ads);
@@ -186,7 +186,7 @@
             mDeviceInventory.put(ads.getDeviceId(), ads);
             checkDeviceInventorySize_l();
 
-            mDeviceBroker.postUpdatedAdiDeviceState(ads);
+            mDeviceBroker.postUpdatedAdiDeviceState(ads, true /*initSA*/);
             mDeviceBroker.postPersistAudioDeviceSettings();
         }
     }
@@ -216,7 +216,7 @@
             checkDeviceInventorySize_l();
         }
         if (updatedCategory.get()) {
-            mDeviceBroker.postUpdatedAdiDeviceState(deviceState);
+            mDeviceBroker.postUpdatedAdiDeviceState(deviceState, false /*initSA*/);
         }
         mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState);
     }
@@ -318,7 +318,7 @@
                     }
                     ads2.setAudioDeviceCategory(updatedDevice.getAudioDeviceCategory());
 
-                    mDeviceBroker.postUpdatedAdiDeviceState(ads2);
+                    mDeviceBroker.postUpdatedAdiDeviceState(ads2, false /*initSA*/);
                     AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
                             "synchronizeBleDeviceInInventory synced device pair ads1="
                                     + updatedDevice + " ads2=" + ads2).printLog(TAG));
@@ -339,7 +339,7 @@
                     }
                     ads2.setAudioDeviceCategory(updatedDevice.getAudioDeviceCategory());
 
-                    mDeviceBroker.postUpdatedAdiDeviceState(ads2);
+                    mDeviceBroker.postUpdatedAdiDeviceState(ads2, false /*initSA*/);
                     AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
                             "synchronizeBleDeviceInInventory synced device pair ads1="
                                     + updatedDevice + " peer ads2=" + ads2).printLog(TAG));
@@ -364,7 +364,7 @@
             }
             ads.setAudioDeviceCategory(updatedDevice.getAudioDeviceCategory());
 
-            mDeviceBroker.postUpdatedAdiDeviceState(ads);
+            mDeviceBroker.postUpdatedAdiDeviceState(ads, false /*initSA*/);
             AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
                     "synchronizeDeviceProfilesInInventory synced device pair ads1="
                             + updatedDevice + " ads2=" + ads).printLog(TAG));
@@ -868,7 +868,8 @@
     @GuardedBy("mDeviceBroker.mDeviceStateLock")
     /*package*/ void onBluetoothDeviceConfigChange(
             @NonNull AudioDeviceBroker.BtDeviceInfo btInfo,
-            @AudioSystem.AudioFormatNativeEnumForBtCodec int codec, int event) {
+            @AudioSystem.AudioFormatNativeEnumForBtCodec int codec,
+            boolean codecChanged, int event) {
         MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId
                 + "onBluetoothDeviceConfigChange")
                 .set(MediaMetrics.Property.EVENT, BtHelper.deviceEventToString(event));
@@ -916,14 +917,12 @@
 
 
             if (event == BtHelper.EVENT_DEVICE_CONFIG_CHANGE) {
-                boolean codecChange = false;
                 if (btInfo.mProfile == BluetoothProfile.A2DP
                         || btInfo.mProfile == BluetoothProfile.LE_AUDIO
                         || btInfo.mProfile == BluetoothProfile.LE_AUDIO_BROADCAST) {
-                    if (di.mDeviceCodecFormat != codec) {
+                    if (codecChanged) {
                         di.mDeviceCodecFormat = codec;
                         mConnectedDevices.replace(key, di);
-                        codecChange = true;
                         final int res = mAudioSystem.handleDeviceConfigChange(
                                 btInfo.mAudioSystemDevice, address,
                                 BtHelper.getName(btDevice), codec);
@@ -947,7 +946,7 @@
                         }
                     }
                 }
-                if (!codecChange) {
+                if (!codecChanged) {
                     updateBluetoothPreferredModes_l(btDevice /*connectedDevice*/);
                 }
             }
diff --git a/services/core/java/com/android/server/audio/AudioManagerShellCommand.java b/services/core/java/com/android/server/audio/AudioManagerShellCommand.java
index 85acf70..570d4e9 100644
--- a/services/core/java/com/android/server/audio/AudioManagerShellCommand.java
+++ b/services/core/java/com/android/server/audio/AudioManagerShellCommand.java
@@ -53,6 +53,12 @@
                 return getSoundDoseValue();
             case "reset-sound-dose-timeout":
                 return resetSoundDoseTimeout();
+            case "set-volume":
+                return setVolume();
+            case "adj-mute":
+                return adjMute();
+            case "adj-unmute":
+                return adjUnmute();
         }
         return 0;
     }
@@ -78,6 +84,12 @@
         pw.println("    Returns the current sound dose value");
         pw.println("  reset-sound-dose-timeout");
         pw.println("    Resets the sound dose timeout used for momentary exposure");
+        pw.println("  set-volume STREAM_TYPE VOLUME_INDEX");
+        pw.println("    Sets the volume for STREAM_TYPE to VOLUME_INDEX");
+        pw.println("  adj-mute STREAM_TYPE");
+        pw.println("    mutes the STREAM_TYPE");
+        pw.println("  adj-unmute STREAM_TYPE");
+        pw.println("    unmutes the STREAM_TYPE");
     }
 
     private int setSurroundFormatEnabled() {
@@ -216,4 +228,54 @@
         getOutPrintWriter().println("Reset sound dose momentary exposure timeout");
         return 0;
     }
+
+    private int setVolume() {
+        final Context context = mService.mContext;
+        final AudioManager am = context.getSystemService(AudioManager.class);
+        final int stream = readIntArg();
+        final int index = readIntArg();
+        getOutPrintWriter().println("calling AudioManager.setStreamVolume("
+                + stream + ", " + index + ", 0)");
+        am.setStreamVolume(stream, index, 0);
+        return 0;
+    }
+
+    private int adjMute() {
+        final Context context = mService.mContext;
+        final AudioManager am = context.getSystemService(AudioManager.class);
+        final int stream = readIntArg();
+        getOutPrintWriter().println("calling AudioManager.adjustStreamVolume("
+                + stream + ", AudioManager.ADJUST_MUTE, 0)");
+        am.adjustStreamVolume(stream, AudioManager.ADJUST_MUTE, 0);
+        return 0;
+    }
+
+    private int adjUnmute() {
+        final Context context = mService.mContext;
+        final AudioManager am = context.getSystemService(AudioManager.class);
+        final int stream = readIntArg();
+        getOutPrintWriter().println("calling AudioManager.adjustStreamVolume("
+                + stream + ", AudioManager.ADJUST_UNMUTE, 0)");
+        am.adjustStreamVolume(stream, AudioManager.ADJUST_UNMUTE, 0);
+        return 0;
+    }
+
+    private int readIntArg() throws IllegalArgumentException {
+        String argText = getNextArg();
+
+        if (argText == null) {
+            getErrPrintWriter().println("Error: no argument provided");
+            throw new IllegalArgumentException("No argument provided");
+        }
+
+        int argIntVal = Integer.MIN_VALUE;
+        try {
+            argIntVal = Integer.parseInt(argText);
+        } catch (NumberFormatException e) {
+            getErrPrintWriter().println("Error: wrong format for argument " + argText);
+            throw new IllegalArgumentException("Wrong format for argument " + argText);
+        }
+
+        return argIntVal;
+    }
 }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index be47f85..5ba0af4 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -34,7 +34,7 @@
 import static android.media.audio.Flags.automaticBtDeviceType;
 import static android.media.audio.Flags.featureSpatialAudioHeadtrackingLowLatency;
 import static android.media.audio.Flags.focusFreezeTestApi;
-import static android.media.audio.Flags.foregroundAudioControl;
+import static android.media.audio.Flags.roForegroundAudioControl;
 import static android.media.audiopolicy.Flags.enableFadeManagerConfiguration;
 import static android.os.Process.FIRST_APPLICATION_UID;
 import static android.os.Process.INVALID_UID;
@@ -47,6 +47,7 @@
 import static com.android.media.audio.Flags.disablePrescaleAbsoluteVolume;
 import static com.android.media.audio.Flags.ringerModeAffectsAlarm;
 import static com.android.media.audio.Flags.setStreamVolumeOrder;
+import static com.android.media.audio.Flags.vgsVssSyncMuteOrder;
 import static com.android.server.audio.SoundDoseHelper.ACTION_CHECK_MUSIC_ACTIVE;
 import static com.android.server.utils.EventLogger.Event.ALOGE;
 import static com.android.server.utils.EventLogger.Event.ALOGI;
@@ -4539,10 +4540,13 @@
                 + focusFreezeTestApi());
         pw.println("\tcom.android.media.audio.disablePrescaleAbsoluteVolume:"
                 + disablePrescaleAbsoluteVolume());
+
         pw.println("\tcom.android.media.audio.setStreamVolumeOrder:"
                 + setStreamVolumeOrder());
-        pw.println("\tandroid.media.audio.foregroundAudioControl:"
-                + foregroundAudioControl());
+        pw.println("\tandroid.media.audio.roForegroundAudioControl:"
+                + roForegroundAudioControl());
+        pw.println("\tcom.android.media.audio.vgsVssSyncMuteOrder:"
+                + vgsVssSyncMuteOrder());
     }
 
     private void dumpAudioMode(PrintWriter pw) {
@@ -8316,13 +8320,23 @@
                                         synced = true;
                                         continue;
                                     }
+                                    if (vgsVssSyncMuteOrder()) {
+                                        if ((isMuted() != streamMuted) && isVssMuteBijective(
+                                                stream)) {
+                                            mStreamStates[stream].mute(isMuted(),
+                                                    "VGS.applyAllVolumes#1");
+                                        }
+                                    }
                                     if (indexForStream != index) {
                                         mStreamStates[stream].setIndex(index * 10, device, caller,
                                                 true /*hasModifyAudioSettings*/);
                                     }
-                                    if ((isMuted() != streamMuted) && isVssMuteBijective(stream)) {
-                                        mStreamStates[stream].mute(isMuted(),
-                                                "VGS.applyAllVolumes#1");
+                                    if (!vgsVssSyncMuteOrder()) {
+                                        if ((isMuted() != streamMuted) && isVssMuteBijective(
+                                                stream)) {
+                                            mStreamStates[stream].mute(isMuted(),
+                                                    "VGS.applyAllVolumes#1");
+                                        }
                                     }
                                 }
                             }
@@ -8854,6 +8868,7 @@
             boolean changed;
             int oldIndex;
             final boolean isCurrentDevice;
+            final StringBuilder aliasStreamIndexes = new StringBuilder();
             synchronized (mSettingsLock) {
                 synchronized (VolumeStreamState.class) {
                     oldIndex = getIndex(device);
@@ -8880,13 +8895,17 @@
                                 (changed || !aliasStreamState.hasIndexForDevice(device))) {
                             final int scaledIndex =
                                     rescaleIndex(aliasIndex, mStreamType, streamType);
-                            aliasStreamState.setIndex(scaledIndex, device, caller,
-                                    hasModifyAudioSettings);
+                            boolean changedAlias = aliasStreamState.setIndex(scaledIndex, device,
+                                    caller, hasModifyAudioSettings);
                             if (isCurrentDevice) {
-                                aliasStreamState.setIndex(scaledIndex,
+                                changedAlias |= aliasStreamState.setIndex(scaledIndex,
                                         getDeviceForStream(streamType), caller,
                                         hasModifyAudioSettings);
                             }
+                            if (changedAlias) {
+                                aliasStreamIndexes.append(AudioSystem.streamToString(streamType))
+                                        .append(":").append((scaledIndex + 5) / 10).append(" ");
+                            }
                         }
                     }
                     // Mirror changes in SPEAKER ringtone volume on SCO when
@@ -8926,8 +8945,15 @@
                                 oldIndex);
                         mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE_ALIAS,
                                 mStreamVolumeAlias[mStreamType]);
-                        AudioService.sVolumeLogger.enqueue(new VolChangedBroadcastEvent(
-                                mStreamType, mStreamVolumeAlias[mStreamType], index, oldIndex));
+                        if (mStreamType == mStreamVolumeAlias[mStreamType]) {
+                            String aliasStreamIndexesString = "";
+                            if (!aliasStreamIndexes.isEmpty()) {
+                                aliasStreamIndexesString =
+                                        " aliased streams: " + aliasStreamIndexes;
+                            }
+                            AudioService.sVolumeLogger.enqueue(new VolChangedBroadcastEvent(
+                                    mStreamType, aliasStreamIndexesString, index, oldIndex));
+                        }
                         sendBroadcastToAll(mVolumeChanged, mVolumeChangedOptions);
                     }
                 }
@@ -11270,7 +11296,8 @@
         mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(deviceState);
         mDeviceBroker.postPersistAudioDeviceSettings();
 
-        mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes());
+        mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes(),
+                false /* initState */);
         mSoundDoseHelper.setAudioDeviceCategory(addr, internalType,
                 btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES);
     }
@@ -11341,11 +11368,11 @@
 
     /** Update the sound dose and spatializer state based on the new AdiDeviceState. */
     @VisibleForTesting(visibility = PACKAGE)
-    public void onUpdatedAdiDeviceState(AdiDeviceState deviceState) {
+    public void onUpdatedAdiDeviceState(AdiDeviceState deviceState, boolean initSA) {
         if (deviceState == null) {
             return;
         }
-        mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes());
+        mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes(), initSA);
         mSoundDoseHelper.setAudioDeviceCategory(deviceState.getDeviceAddress(),
                 deviceState.getInternalDeviceType(),
                 deviceState.getAudioDeviceCategory() == AUDIO_DEVICE_CATEGORY_HEADPHONES);
diff --git a/services/core/java/com/android/server/audio/AudioServiceEvents.java b/services/core/java/com/android/server/audio/AudioServiceEvents.java
index 3b1c011..749044e 100644
--- a/services/core/java/com/android/server/audio/AudioServiceEvents.java
+++ b/services/core/java/com/android/server/audio/AudioServiceEvents.java
@@ -151,13 +151,13 @@
 
     static final class VolChangedBroadcastEvent extends EventLogger.Event {
         final int mStreamType;
-        final int mAliasStreamType;
+        final String mAliasStreamIndexes;
         final int mIndex;
         final int mOldIndex;
 
-        VolChangedBroadcastEvent(int stream, int alias, int index, int oldIndex) {
+        VolChangedBroadcastEvent(int stream, String aliasIndexes, int index, int oldIndex) {
             mStreamType = stream;
-            mAliasStreamType = alias;
+            mAliasStreamIndexes = aliasIndexes;
             mIndex = index;
             mOldIndex = oldIndex;
         }
@@ -167,8 +167,8 @@
             return new StringBuilder("sending VOLUME_CHANGED stream:")
                     .append(AudioSystem.streamToString(mStreamType))
                     .append(" index:").append(mIndex)
-                    .append(" (was:").append(mOldIndex)
-                    .append(") alias:").append(AudioSystem.streamToString(mAliasStreamType))
+                    .append(" (was:").append(mOldIndex).append(")")
+                    .append(mAliasStreamIndexes)
                     .toString();
         }
     }
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index f3a5fdb..edeabdc 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -98,9 +98,16 @@
 
     private @Nullable BluetoothLeAudio mLeAudio;
 
+    private @Nullable BluetoothLeAudioCodecConfig mLeAudioCodecConfig;
+
     // Reference to BluetoothA2dp to query for AbsoluteVolume.
     private @Nullable BluetoothA2dp mA2dp;
 
+    private @Nullable BluetoothCodecConfig mA2dpCodecConfig;
+
+    private @AudioSystem.AudioFormatNativeEnumForBtCodec
+            int mLeAudioBroadcastCodec = AudioSystem.AUDIO_FORMAT_DEFAULT;
+
     // If absolute volume is supported in AVRCP device
     private boolean mAvrcpAbsVolSupported = false;
 
@@ -265,12 +272,15 @@
         }
     }
 
-    /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec int getCodec(
+    private synchronized Pair<Integer, Boolean> getCodec(
             @NonNull BluetoothDevice device, @AudioService.BtProfile int profile) {
+
         switch (profile) {
             case BluetoothProfile.A2DP: {
+                boolean changed = mA2dpCodecConfig != null;
                 if (mA2dp == null) {
-                    return AudioSystem.AUDIO_FORMAT_DEFAULT;
+                    mA2dpCodecConfig = null;
+                    return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, changed);
                 }
                 BluetoothCodecStatus btCodecStatus = null;
                 try {
@@ -279,17 +289,24 @@
                     Log.e(TAG, "Exception while getting status of " + device, e);
                 }
                 if (btCodecStatus == null) {
-                    return AudioSystem.AUDIO_FORMAT_DEFAULT;
+                    mA2dpCodecConfig = null;
+                    return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, changed);
                 }
                 final BluetoothCodecConfig btCodecConfig = btCodecStatus.getCodecConfig();
                 if (btCodecConfig == null) {
-                    return AudioSystem.AUDIO_FORMAT_DEFAULT;
+                    mA2dpCodecConfig = null;
+                    return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, changed);
                 }
-                return AudioSystem.bluetoothA2dpCodecToAudioFormat(btCodecConfig.getCodecType());
+                changed = !btCodecConfig.equals(mA2dpCodecConfig);
+                mA2dpCodecConfig = btCodecConfig;
+                return new Pair<>(AudioSystem.bluetoothA2dpCodecToAudioFormat(
+                        btCodecConfig.getCodecType()), changed);
             }
             case BluetoothProfile.LE_AUDIO: {
+                boolean changed = mLeAudioCodecConfig != null;
                 if (mLeAudio == null) {
-                    return AudioSystem.AUDIO_FORMAT_DEFAULT;
+                    mLeAudioCodecConfig = null;
+                    return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, changed);
                 }
                 BluetoothLeAudioCodecStatus btLeCodecStatus = null;
                 int groupId = mLeAudio.getGroupId(device);
@@ -299,42 +316,54 @@
                     Log.e(TAG, "Exception while getting status of " + device, e);
                 }
                 if (btLeCodecStatus == null) {
-                    return AudioSystem.AUDIO_FORMAT_DEFAULT;
+                    mLeAudioCodecConfig = null;
+                    return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, changed);
                 }
                 BluetoothLeAudioCodecConfig btLeCodecConfig =
                         btLeCodecStatus.getOutputCodecConfig();
                 if (btLeCodecConfig == null) {
-                    return AudioSystem.AUDIO_FORMAT_DEFAULT;
+                    mLeAudioCodecConfig = null;
+                    return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, changed);
                 }
-                return AudioSystem.bluetoothLeCodecToAudioFormat(btLeCodecConfig.getCodecType());
+                changed = !btLeCodecConfig.equals(mLeAudioCodecConfig);
+                mLeAudioCodecConfig = btLeCodecConfig;
+                return new Pair<>(AudioSystem.bluetoothLeCodecToAudioFormat(
+                        btLeCodecConfig.getCodecType()), changed);
+            }
+            case BluetoothProfile.LE_AUDIO_BROADCAST: {
+                // We assume LC3 for LE Audio broadcast codec as there is no API to get the codec
+                // config on LE Broadcast profile proxy.
+                boolean changed = mLeAudioBroadcastCodec != AudioSystem.AUDIO_FORMAT_LC3;
+                mLeAudioBroadcastCodec = AudioSystem.AUDIO_FORMAT_LC3;
+                return new Pair<>(mLeAudioBroadcastCodec, changed);
             }
             default:
-                return AudioSystem.AUDIO_FORMAT_DEFAULT;
+                return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, false);
         }
     }
 
-    /*package*/ synchronized @AudioSystem.AudioFormatNativeEnumForBtCodec
-            int getCodecWithFallback(
-                    @NonNull BluetoothDevice device, @AudioService.BtProfile int profile,
-                    boolean isLeOutput, @NonNull String source) {
+    /*package*/ synchronized Pair<Integer, Boolean>
+                    getCodecWithFallback(@NonNull BluetoothDevice device,
+                                         @AudioService.BtProfile int profile,
+                                         boolean isLeOutput, @NonNull String source) {
         // For profiles other than A2DP and LE Audio output, the audio codec format must be
         // AUDIO_FORMAT_DEFAULT as native audio policy manager expects a specific audio format
         // only if audio HW module selection based on format is supported for the device type.
         if (!(profile == BluetoothProfile.A2DP
                 || (isLeOutput && ((profile == BluetoothProfile.LE_AUDIO)
                         || (profile == BluetoothProfile.LE_AUDIO_BROADCAST))))) {
-            return AudioSystem.AUDIO_FORMAT_DEFAULT;
+            return new Pair<>(AudioSystem.AUDIO_FORMAT_DEFAULT, false);
         }
-        @AudioSystem.AudioFormatNativeEnumForBtCodec int codec =
+        Pair<Integer, Boolean> codecAndChanged =
                 getCodec(device, profile);
-        if (codec == AudioSystem.AUDIO_FORMAT_DEFAULT) {
+        if (codecAndChanged.first == AudioSystem.AUDIO_FORMAT_DEFAULT) {
             AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
                     "getCodec DEFAULT from " + source + " fallback to "
                             + (profile == BluetoothProfile.A2DP ? "SBC" : "LC3")));
-            return profile == BluetoothProfile.A2DP
-                    ? AudioSystem.AUDIO_FORMAT_SBC : AudioSystem.AUDIO_FORMAT_LC3;
+            return new Pair<>(profile == BluetoothProfile.A2DP
+                    ? AudioSystem.AUDIO_FORMAT_SBC : AudioSystem.AUDIO_FORMAT_LC3, true);
         }
-        return codec;
+        return codecAndChanged;
     }
 
     // @GuardedBy("mDeviceBroker.mSetModeLock")
@@ -539,15 +568,19 @@
                 break;
             case BluetoothProfile.A2DP:
                 mA2dp = null;
+                mA2dpCodecConfig = null;
                 break;
             case BluetoothProfile.HEARING_AID:
                 mHearingAid = null;
                 break;
             case BluetoothProfile.LE_AUDIO:
                 mLeAudio = null;
+                mLeAudioCodecConfig = null;
+                break;
+            case BluetoothProfile.LE_AUDIO_BROADCAST:
+                mLeAudioBroadcastCodec = AudioSystem.AUDIO_FORMAT_DEFAULT;
                 break;
             case BluetoothProfile.A2DP_SINK:
-            case BluetoothProfile.LE_AUDIO_BROADCAST:
                 // nothing to do in BtHelper
                 break;
             default:
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 08da32e..28af222 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -235,6 +235,10 @@
     public int trackPlayer(PlayerBase.PlayerIdCard pic) {
         final int newPiid = AudioSystem.newAudioPlayerId();
         if (DEBUG) { Log.v(TAG, "trackPlayer() new piid=" + newPiid); }
+        if (newPiid == PLAYER_PIID_INVALID) {
+            Log.w(TAG, "invalid piid assigned from AudioSystem");
+            return newPiid;
+        }
         final AudioPlaybackConfiguration apc =
                 new AudioPlaybackConfiguration(pic, newPiid,
                         Binder.getCallingUid(), Binder.getCallingPid());
@@ -365,15 +369,14 @@
             sEventLogger.enqueue(new PlayerEvent(piid, event, eventValue));
 
             if (event == AudioPlaybackConfiguration.PLAYER_UPDATE_PORT_ID) {
-                mEventHandler.sendMessage(
-                        mEventHandler.obtainMessage(MSG_II_UPDATE_PORT_EVENT, eventValue, piid));
+                mPortIdToPiid.put(eventValue, piid);
                 return;
             } else if (event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
                 for (Integer uidInteger: mBannedUids) {
                     if (checkBanPlayer(apc, uidInteger.intValue())) {
                         // player was banned, do not update its state
                         sEventLogger.enqueue(new EventLogger.StringEvent(
-                                "not starting piid:" + piid + " ,is banned"));
+                                "not starting piid:" + piid + ", is banned"));
                         return;
                     }
                 }
@@ -429,16 +432,12 @@
         synchronized (mPlayerLock) {
             int piid = mPortIdToPiid.get(portId, PLAYER_PIID_INVALID);
             if (piid == PLAYER_PIID_INVALID) {
-                if (DEBUG) {
-                    Log.v(TAG, "No piid assigned for invalid/internal port id " + portId);
-                }
+                Log.w(TAG, "No piid assigned for invalid/internal port id " + portId);
                 return;
             }
             final AudioPlaybackConfiguration apc = mPlayers.get(piid);
             if (apc == null) {
-                if (DEBUG) {
-                    Log.v(TAG, "No AudioPlaybackConfiguration assigned for piid " + piid);
-                }
+                Log.w(TAG, "No AudioPlaybackConfiguration assigned for piid " + piid);
                 return;
             }
 
@@ -470,11 +469,18 @@
     public void releasePlayer(int piid, int binderUid) {
         if (DEBUG) { Log.v(TAG, "releasePlayer() for piid=" + piid); }
         boolean change = false;
+        if (piid == PLAYER_PIID_INVALID) {
+            Log.w(TAG, "Received releasePlayer with invalid piid: " + piid);
+            sEventLogger.enqueue(new EventLogger.StringEvent("releasePlayer with invalid piid:"
+                    + piid + ", uid:" + binderUid));
+            return;
+        }
+
         synchronized(mPlayerLock) {
             final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid));
             if (checkConfigurationCaller(piid, apc, binderUid)) {
                 sEventLogger.enqueue(new EventLogger.StringEvent(
-                        "releasing player piid:" + piid));
+                        "releasing player piid:" + piid + ", uid:" + binderUid));
                 mPlayers.remove(new Integer(piid));
                 mDuckingManager.removeReleased(apc);
                 mFadeOutManager.removeReleased(apc);
@@ -484,8 +490,10 @@
                         AudioPlaybackConfiguration.PLAYER_DEVICEID_INVALID);
 
                 // remove all port ids mapped to the released player
-                mEventHandler.sendMessage(
-                        mEventHandler.obtainMessage(MSG_I_CLEAR_PORTS_FOR_PIID, piid, /*arg2=*/0));
+                int portIdx;
+                while ((portIdx = mPortIdToPiid.indexOfValue(piid)) >= 0) {
+                    mPortIdToPiid.removeAt(portIdx);
+                }
 
                 if (change && mDoNotLogPiidList.contains(piid)) {
                     // do not dispatch a change for a "do not log" player
@@ -1609,14 +1617,6 @@
     private static final int MSG_L_TIMEOUT_MUTE_AWAIT_CONNECTION = 1;
 
     /**
-     * assign new port id to piid
-     * args:
-     *     msg.arg1: port id
-     *     msg.arg2: piid
-     */
-    private static final int MSG_II_UPDATE_PORT_EVENT = 2;
-
-    /**
      * event for player getting muted
      * args:
      *     msg.arg1: piid
@@ -1624,14 +1624,7 @@
      *     msg.obj: extras describing the mute reason
      *         type: PersistableBundle
      */
-    private static final int MSG_IIL_UPDATE_PLAYER_MUTED_EVENT = 3;
-
-    /**
-     * clear all ports assigned to a given piid
-     * args:
-     *     msg.arg1: the piid
-     */
-    private static final int MSG_I_CLEAR_PORTS_FOR_PIID = 4;
+    private static final int MSG_IIL_UPDATE_PLAYER_MUTED_EVENT = 2;
 
     /**
      * event for player reporting playback format and spatialization status
@@ -1641,7 +1634,7 @@
      *     msg.obj: extras describing the sample rate, channel mask, spatialized
      *         type: PersistableBundle
      */
-    private static final int MSG_IIL_UPDATE_PLAYER_FORMAT = 5;
+    private static final int MSG_IIL_UPDATE_PLAYER_FORMAT = 3;
 
     private void initEventHandler() {
         mEventThread = new HandlerThread(TAG);
@@ -1660,11 +1653,6 @@
                         mMuteAwaitConnectionTimeoutCb.accept((AudioDeviceAttributes) msg.obj);
                         break;
 
-                    case MSG_II_UPDATE_PORT_EVENT:
-                        synchronized (mPlayerLock) {
-                            mPortIdToPiid.put(/*portId*/msg.arg1, /*piid*/msg.arg2);
-                        }
-                        break;
                     case MSG_IIL_UPDATE_PLAYER_MUTED_EVENT:
                         // TODO: replace PersistableBundle with own struct
                         PersistableBundle extras = (PersistableBundle) msg.obj;
@@ -1680,10 +1668,7 @@
                             sEventLogger.enqueue(
                                     new PlayerEvent(piid, PLAYER_UPDATE_MUTED, eventValue));
 
-                            final AudioPlaybackConfiguration apc;
-                            synchronized (mPlayerLock) {
-                                apc = mPlayers.get(piid);
-                            }
+                            final AudioPlaybackConfiguration apc = mPlayers.get(piid);
                             if (apc == null || !apc.handleMutedEvent(eventValue)) {
                                 break;  // do not dispatch
                             }
@@ -1691,21 +1676,6 @@
                         }
                         break;
 
-                    case MSG_I_CLEAR_PORTS_FOR_PIID:
-                        int piid = msg.arg1;
-                        if (piid == AudioPlaybackConfiguration.PLAYER_PIID_INVALID) {
-                            Log.w(TAG, "Received clear ports with invalid piid");
-                            break;
-                        }
-
-                        synchronized (mPlayerLock) {
-                            int portIdx;
-                            while ((portIdx = mPortIdToPiid.indexOfValue(piid)) >= 0) {
-                                mPortIdToPiid.removeAt(portIdx);
-                            }
-                        }
-                        break;
-
                     case MSG_IIL_UPDATE_PLAYER_FORMAT:
                         final PersistableBundle formatExtras = (PersistableBundle) msg.obj;
                         if (formatExtras == null) {
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 3b5fa7f..38fa79f 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -295,11 +295,11 @@
             // could have been called another time after boot in case of audioserver restart
             addCompatibleAudioDevice(
                     new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""),
-                            false /*forceEnable*/);
+                            false /*forceEnable*/, false /*forceInit*/);
             // not force-enabling as this device might already be in the device list
             addCompatibleAudioDevice(
                     new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, ""),
-                            false /*forceEnable*/);
+                            false /*forceEnable*/, false /*forceInit*/);
         } catch (RemoteException e) {
             resetCapabilities();
         } finally {
@@ -526,7 +526,7 @@
     }
 
     synchronized void addCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
-        addCompatibleAudioDevice(ada, true /*forceEnable*/);
+        addCompatibleAudioDevice(ada, true /*forceEnable*/, false /*forceInit*/);
     }
 
     /**
@@ -540,7 +540,7 @@
      */
     @GuardedBy("this")
     private void addCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada,
-            boolean forceEnable) {
+            boolean forceEnable, boolean forceInit) {
         if (!isDeviceCompatibleWithSpatializationModes(ada)) {
             return;
         }
@@ -548,6 +548,9 @@
         final AdiDeviceState deviceState = findSACompatibleDeviceStateForAudioDeviceAttributes(ada);
         AdiDeviceState updatedDevice = null; // non-null on update.
         if (deviceState != null) {
+            if (forceInit) {
+                initSAState(deviceState);
+            }
             if (forceEnable && !deviceState.isSAEnabled()) {
                 updatedDevice = deviceState;
                 updatedDevice.setSAEnabled(true);
@@ -756,10 +759,10 @@
         }
     }
 
-    synchronized void refreshDevice(@NonNull AudioDeviceAttributes ada) {
+    synchronized void refreshDevice(@NonNull AudioDeviceAttributes ada, boolean initState) {
         final AdiDeviceState deviceState = findSACompatibleDeviceStateForAudioDeviceAttributes(ada);
         if (isAvailableForAdiDeviceState(deviceState)) {
-            addCompatibleAudioDevice(ada, /*forceEnable=*/deviceState.isSAEnabled());
+            addCompatibleAudioDevice(ada, /*forceEnable=*/deviceState.isSAEnabled(), initState);
             setHeadTrackerEnabled(deviceState.isHeadTrackerEnabled(), ada);
         } else {
             removeCompatibleAudioDevice(ada);
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/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index 14f3120..7df63b1 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -869,9 +869,7 @@
             }
 
             if (faceAidlInstances != null && faceAidlInstances.length > 0) {
-                mFaceSensorConfigurations.addAidlConfigs(faceAidlInstances,
-                        name -> IFace.Stub.asInterface(Binder.allowBlocking(
-                                ServiceManager.waitForDeclaredService(name))));
+                mFaceSensorConfigurations.addAidlConfigs(faceAidlInstances);
             }
 
             if (faceService != null) {
@@ -909,9 +907,7 @@
             }
 
             if (fingerprintAidlInstances != null && fingerprintAidlInstances.length > 0) {
-                mFingerprintSensorConfigurations.addAidlSensors(fingerprintAidlInstances,
-                        name -> IFingerprint.Stub.asInterface(Binder.allowBlocking(
-                                ServiceManager.waitForDeclaredService(name))));
+                mFingerprintSensorConfigurations.addAidlSensors(fingerprintAidlInstances);
             }
 
             if (fingerprintService != null) {
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index 3d4801b..c03b3b8 100644
--- a/services/core/java/com/android/server/biometrics/AuthSession.java
+++ b/services/core/java/com/android/server/biometrics/AuthSession.java
@@ -56,7 +56,7 @@
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.security.KeyStore;
+import android.security.KeyStoreAuthorization;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -111,7 +111,7 @@
     @NonNull private final BiometricContext mBiometricContext;
     private final IStatusBarService mStatusBarService;
     @VisibleForTesting final IBiometricSysuiReceiver mSysuiReceiver;
-    private final KeyStore mKeyStore;
+    private final KeyStoreAuthorization mKeyStoreAuthorization;
     private final Random mRandom;
     private final ClientDeathReceiver mClientDeathReceiver;
     final PreAuthInfo mPreAuthInfo;
@@ -158,7 +158,7 @@
             @NonNull BiometricContext biometricContext,
             @NonNull IStatusBarService statusBarService,
             @NonNull IBiometricSysuiReceiver sysuiReceiver,
-            @NonNull KeyStore keystore,
+            @NonNull KeyStoreAuthorization keyStoreAuthorization,
             @NonNull Random random,
             @NonNull ClientDeathReceiver clientDeathReceiver,
             @NonNull PreAuthInfo preAuthInfo,
@@ -172,8 +172,8 @@
             @NonNull PromptInfo promptInfo,
             boolean debugEnabled,
             @NonNull List<FingerprintSensorPropertiesInternal> fingerprintSensorProperties) {
-        this(context, biometricContext, statusBarService, sysuiReceiver, keystore, random,
-                clientDeathReceiver, preAuthInfo, token, requestId, operationId, userId,
+        this(context, biometricContext, statusBarService, sysuiReceiver, keyStoreAuthorization,
+                random, clientDeathReceiver, preAuthInfo, token, requestId, operationId, userId,
                 sensorReceiver, clientReceiver, opPackageName, promptInfo, debugEnabled,
                 fingerprintSensorProperties, BiometricFrameworkStatsLogger.getInstance());
     }
@@ -183,7 +183,7 @@
             @NonNull BiometricContext biometricContext,
             @NonNull IStatusBarService statusBarService,
             @NonNull IBiometricSysuiReceiver sysuiReceiver,
-            @NonNull KeyStore keystore,
+            @NonNull KeyStoreAuthorization keyStoreAuthorization,
             @NonNull Random random,
             @NonNull ClientDeathReceiver clientDeathReceiver,
             @NonNull PreAuthInfo preAuthInfo,
@@ -203,7 +203,7 @@
         mBiometricContext = biometricContext;
         mStatusBarService = statusBarService;
         mSysuiReceiver = sysuiReceiver;
-        mKeyStore = keystore;
+        mKeyStoreAuthorization = keyStoreAuthorization;
         mRandom = random;
         mClientDeathReceiver = clientDeathReceiver;
         mPreAuthInfo = preAuthInfo;
@@ -814,14 +814,14 @@
             switch (reason) {
                 case BiometricPrompt.DISMISSED_REASON_CREDENTIAL_CONFIRMED:
                     if (credentialAttestation != null) {
-                        mKeyStore.addAuthToken(credentialAttestation);
+                        mKeyStoreAuthorization.addAuthToken(credentialAttestation);
                     } else {
                         Slog.e(TAG, "credentialAttestation is null");
                     }
                 case BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRMED:
                 case BiometricPrompt.DISMISSED_REASON_BIOMETRIC_CONFIRM_NOT_REQUIRED:
                     if (mTokenEscrow != null) {
-                        final int result = mKeyStore.addAuthToken(mTokenEscrow);
+                        final int result = mKeyStoreAuthorization.addAuthToken(mTokenEscrow);
                         Slog.d(TAG, "addAuthToken: " + result);
                     } else {
                         Slog.e(TAG, "mTokenEscrow is null");
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 894b4d5..3737d6f 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -65,15 +65,11 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.ServiceSpecificException;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
-import android.security.Authorization;
 import android.security.GateKeeper;
-import android.security.KeyStore;
-import android.security.authorization.IKeystoreAuthorization;
-import android.security.authorization.ResponseCode;
+import android.security.KeyStoreAuthorization;
 import android.service.gatekeeper.IGateKeeperService;
 import android.text.TextUtils;
 import android.util.ArraySet;
@@ -123,11 +119,9 @@
     @VisibleForTesting
     IStatusBarService mStatusBarService;
     @VisibleForTesting
-    KeyStore mKeyStore;
-    @VisibleForTesting
     ITrustManager mTrustManager;
     @VisibleForTesting
-    IKeystoreAuthorization mKeystoreAuthorization;
+    KeyStoreAuthorization mKeyStoreAuthorization;
     @VisibleForTesting
     IGateKeeperService mGateKeeper;
 
@@ -674,19 +668,7 @@
             int[] authTypesArray = hardwareAuthenticators.stream()
                     .mapToInt(Integer::intValue)
                     .toArray();
-            try {
-                return mKeystoreAuthorization.getLastAuthTime(secureUserId, authTypesArray);
-            } catch (RemoteException e) {
-                Slog.w(TAG, "Error getting last auth time: " + e);
-                return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION;
-            } catch (ServiceSpecificException e) {
-                // This is returned when the feature flag test fails in keystore2
-                if (e.errorCode == ResponseCode.PERMISSION_DENIED) {
-                    throw new UnsupportedOperationException();
-                }
-
-                return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION;
-            }
+            return mKeyStoreAuthorization.getLastAuthTime(secureUserId, authTypesArray);
         }
 
         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@@ -1011,8 +993,8 @@
             return ActivityManager.getService();
         }
 
-        public IKeystoreAuthorization getKeystoreAuthorizationService() {
-            return Authorization.getService();
+        public KeyStoreAuthorization getKeyStoreAuthorization() {
+            return KeyStoreAuthorization.getInstance();
         }
 
         public IGateKeeperService getGateKeeperService() {
@@ -1036,10 +1018,6 @@
             return new SettingObserver(context, handler, callbacks);
         }
 
-        public KeyStore getKeyStore() {
-            return KeyStore.getInstance();
-        }
-
         /**
          * Allows to enable/disable debug logs.
          */
@@ -1138,7 +1116,7 @@
         mBiometricContext = injector.getBiometricContext(context);
         mUserManager = injector.getUserManager(context);
         mBiometricCameraManager = injector.getBiometricCameraManager(context);
-        mKeystoreAuthorization = injector.getKeystoreAuthorizationService();
+        mKeyStoreAuthorization = injector.getKeyStoreAuthorization();
         mGateKeeper = injector.getGateKeeperService();
         mBiometricNotificationLogger = injector.getNotificationLogger();
 
@@ -1159,7 +1137,6 @@
 
     @Override
     public void onStart() {
-        mKeyStore = mInjector.getKeyStore();
         mStatusBarService = mInjector.getStatusBarService();
         mTrustManager = mInjector.getTrustManager();
         mInjector.publishBinderService(this, mImpl);
@@ -1481,7 +1458,7 @@
 
         final boolean debugEnabled = mInjector.isDebugEnabled(getContext(), userId);
         mAuthSession = new AuthSession(getContext(), mBiometricContext, mStatusBarService,
-                createSysuiReceiver(requestId), mKeyStore, mRandom,
+                createSysuiReceiver(requestId), mKeyStoreAuthorization, mRandom,
                 createClientDeathReceiver(requestId), preAuthInfo, token, requestId,
                 operationId, userId, createBiometricSensorReceiver(requestId), receiver,
                 opPackageName, promptInfo, debugEnabled,
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/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 62c21cf..4fa8741 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -30,7 +30,7 @@
 import android.hardware.biometrics.BiometricRequestConstants;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.security.KeyStore;
+import android.security.KeyStoreAuthorization;
 import android.util.EventLog;
 import android.util.Slog;
 
@@ -255,7 +255,7 @@
 
             // For BP, BiometricService will add the authToken to Keystore.
             if (!isBiometricPrompt() && mIsStrongBiometric) {
-                final int result = KeyStore.getInstance().addAuthToken(byteToken);
+                final int result = KeyStoreAuthorization.getInstance().addAuthToken(byteToken);
                 if (result != 0) {
                     Slog.d(TAG, "Error adding auth token : " + result);
                 } else {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index 7ee2a7a..1037124 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -729,8 +729,8 @@
         private List<ServiceProvider> getProviders(
                 FaceSensorConfigurations faceSensorConfigurations) {
             final List<ServiceProvider> providers = new ArrayList<>();
-            final Pair<String, SensorProps[]> filteredSensorProps =
-                    filterAvailableHalInstances(faceSensorConfigurations);
+            final Pair<String, SensorProps[]> filteredSensorProps = filterAvailableHalInstances(
+                            faceSensorConfigurations);
             providers.add(mFaceProviderFunction.getFaceProvider(filteredSensorProps,
                     faceSensorConfigurations.getResetLockoutRequiresChallenge()));
             return providers;
@@ -739,28 +739,36 @@
         @NonNull
         private Pair<String, SensorProps[]> filterAvailableHalInstances(
                 FaceSensorConfigurations faceSensorConfigurations) {
-            Pair<String, SensorProps[]> finalSensorPair = faceSensorConfigurations.getSensorPair();
+            String finalSensorInstance = faceSensorConfigurations.getSensorInstance();
 
             if (faceSensorConfigurations.isSingleSensorConfigurationPresent()) {
-                return finalSensorPair;
+                return new Pair<>(finalSensorInstance,
+                        faceSensorConfigurations.getSensorPropForInstance(finalSensorInstance));
             }
-
-            final Pair<String, SensorProps[]> virtualSensorProps = faceSensorConfigurations
-                    .getSensorPairForInstance("virtual");
-
-            if (Utils.isVirtualEnabled(getContext())) {
-                if (virtualSensorProps != null) {
-                    return virtualSensorProps;
+            final String virtualInstance = "virtual";
+            final boolean isVirtualHalPresent =
+                    faceSensorConfigurations.doesInstanceExist(virtualInstance);
+            if (Flags.faceVhalFeature() && Utils.isVirtualEnabled(getContext())) {
+                if (isVirtualHalPresent) {
+                    return new Pair<>(virtualInstance,
+                            faceSensorConfigurations.getSensorPropForInstance(virtualInstance));
                 } else {
                     Slog.e(TAG, "Could not find virtual interface while it is enabled");
-                    return finalSensorPair;
+                    return new Pair<>(finalSensorInstance,
+                            faceSensorConfigurations.getSensorPropForInstance(finalSensorInstance));
                 }
             } else {
-                if (virtualSensorProps != null) {
-                    return faceSensorConfigurations.getSensorPairNotForInstance("virtual");
+                if (isVirtualHalPresent) {
+                    final String notAVirtualInstance =
+                            faceSensorConfigurations.getSensorNameNotForInstance(virtualInstance);
+                    if (notAVirtualInstance != null) {
+                        return new Pair<>(notAVirtualInstance, faceSensorConfigurations
+                                .getSensorPropForInstance(notAVirtualInstance));
+                    }
                 }
             }
-            return finalSensorPair;
+            return new Pair<>(finalSensorInstance, faceSensorConfigurations
+                    .getSensorPropForInstance(finalSensorInstance));
         }
 
         private Pair<List<FaceSensorPropertiesInternal>, List<String>>
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 1ba1213..2dc03ed 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -1128,27 +1128,36 @@
     @NonNull
     private Pair<String, SensorProps[]> filterAvailableHalInstances(
             FingerprintSensorConfigurations fingerprintSensorConfigurations) {
-        Pair<String, SensorProps[]> finalSensorPair =
-                fingerprintSensorConfigurations.getSensorPair();
+        final String finalSensorInstance = fingerprintSensorConfigurations.getSensorInstance();
         if (fingerprintSensorConfigurations.isSingleSensorConfigurationPresent()) {
-            return finalSensorPair;
+            return new Pair<>(finalSensorInstance,
+                    fingerprintSensorConfigurations.getSensorPropForInstance(finalSensorInstance));
         }
-
-        final Pair<String, SensorProps[]> virtualSensorPropsPair = fingerprintSensorConfigurations
-                .getSensorPairForInstance("virtual");
+        final String virtualInstance = "virtual";
+        final boolean isVirtualHalPresent =
+                fingerprintSensorConfigurations.doesInstanceExist(virtualInstance);
         if (Utils.isVirtualEnabled(getContext())) {
-            if (virtualSensorPropsPair != null) {
-                return virtualSensorPropsPair;
+            if (isVirtualHalPresent) {
+                return new Pair<>(virtualInstance,
+                        fingerprintSensorConfigurations.getSensorPropForInstance(virtualInstance));
             } else {
                 Slog.e(TAG, "Could not find virtual interface while it is enabled");
-                return finalSensorPair;
+                return new Pair<>(finalSensorInstance,
+                        fingerprintSensorConfigurations.getSensorPropForInstance(
+                                finalSensorInstance));
             }
         } else {
-            if (virtualSensorPropsPair != null) {
-                return fingerprintSensorConfigurations.getSensorPairNotForInstance("virtual");
+            if (isVirtualHalPresent) {
+                final String notAVirtualInstance = fingerprintSensorConfigurations
+                        .getSensorNameNotForInstance(virtualInstance);
+                if (notAVirtualInstance != null) {
+                    return new Pair<>(notAVirtualInstance, fingerprintSensorConfigurations
+                            .getSensorPropForInstance(notAVirtualInstance));
+                }
             }
         }
-        return finalSensorPair;
+        return new Pair<>(finalSensorInstance, fingerprintSensorConfigurations
+                .getSensorPropForInstance(finalSensorInstance));
     }
 
     private Pair<List<FingerprintSensorPropertiesInternal>, List<String>>
diff --git a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
index 3ede0a2..028b9b0 100644
--- a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
@@ -26,7 +26,7 @@
 
 import java.util.ArrayList;
 
-public class BroadcastRadioService extends SystemService {
+public final class BroadcastRadioService extends SystemService {
     private final IRadioService mServiceImpl;
 
     public BroadcastRadioService(Context context) {
diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
index 42b2682..16514fa 100644
--- a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
@@ -52,7 +52,7 @@
     private static final List<String> SERVICE_NAMES = Arrays.asList(
             IBroadcastRadio.DESCRIPTOR + "/amfm", IBroadcastRadio.DESCRIPTOR + "/dab");
 
-    private final BroadcastRadioServiceImpl mHalAidl;
+    private final BroadcastRadioServiceImpl mAidlHalClient;
     private final BroadcastRadioService mService;
 
     /**
@@ -77,14 +77,14 @@
     @VisibleForTesting
     IRadioServiceAidlImpl(BroadcastRadioService service, BroadcastRadioServiceImpl halAidl) {
         mService = Objects.requireNonNull(service, "Broadcast radio service cannot be null");
-        mHalAidl = Objects.requireNonNull(halAidl,
+        mAidlHalClient = Objects.requireNonNull(halAidl,
                 "Broadcast radio service implementation for AIDL HAL cannot be null");
     }
 
     @Override
     public List<RadioManager.ModuleProperties> listModules() {
         mService.enforcePolicyAccess();
-        return mHalAidl.listModules();
+        return mAidlHalClient.listModules();
     }
 
     @Override
@@ -97,7 +97,7 @@
         if (callback == null) {
             throw new IllegalArgumentException("Callback must not be null");
         }
-        return mHalAidl.openSession(moduleId, bandConfig, withAudio, callback);
+        return mAidlHalClient.openSession(moduleId, bandConfig, withAudio, callback);
     }
 
     @Override
@@ -110,7 +110,7 @@
         Objects.requireNonNull(listener, "Announcement listener cannot be null");
         mService.enforcePolicyAccess();
 
-        return mHalAidl.addAnnouncementListener(enabledTypes, listener);
+        return mAidlHalClient.addAnnouncementListener(enabledTypes, listener);
     }
 
     @Override
@@ -126,10 +126,10 @@
         radioPrintWriter.printf("BroadcastRadioService\n");
 
         radioPrintWriter.increaseIndent();
-        radioPrintWriter.printf("AIDL HAL:\n");
+        radioPrintWriter.printf("AIDL HAL client:\n");
 
         radioPrintWriter.increaseIndent();
-        mHalAidl.dumpInfo(radioPrintWriter);
+        mAidlHalClient.dumpInfo(radioPrintWriter);
         radioPrintWriter.decreaseIndent();
 
         radioPrintWriter.decreaseIndent();
diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
index bc72a4b..ab08342 100644
--- a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
@@ -49,8 +49,8 @@
 final class IRadioServiceHidlImpl extends IRadioService.Stub {
     private static final String TAG = "BcRadioSrvHidl";
 
-    private final com.android.server.broadcastradio.hal1.BroadcastRadioService mHal1;
-    private final com.android.server.broadcastradio.hal2.BroadcastRadioService mHal2;
+    private final com.android.server.broadcastradio.hal1.BroadcastRadioService mHal1Client;
+    private final com.android.server.broadcastradio.hal2.BroadcastRadioService mHal2Client;
 
     private final Object mLock = new Object();
 
@@ -61,10 +61,10 @@
 
     IRadioServiceHidlImpl(BroadcastRadioService service) {
         mService = Objects.requireNonNull(service, "broadcast radio service cannot be null");
-        mHal1 = new com.android.server.broadcastradio.hal1.BroadcastRadioService();
-        mV1Modules = mHal1.loadModules();
+        mHal1Client = new com.android.server.broadcastradio.hal1.BroadcastRadioService();
+        mV1Modules = mHal1Client.loadModules();
         OptionalInt max = mV1Modules.stream().mapToInt(RadioManager.ModuleProperties::getId).max();
-        mHal2 = new com.android.server.broadcastradio.hal2.BroadcastRadioService(
+        mHal2Client = new com.android.server.broadcastradio.hal2.BroadcastRadioService(
                 max.isPresent() ? max.getAsInt() + 1 : 0);
     }
 
@@ -73,17 +73,17 @@
             com.android.server.broadcastradio.hal1.BroadcastRadioService hal1,
             com.android.server.broadcastradio.hal2.BroadcastRadioService hal2) {
         mService = Objects.requireNonNull(service, "Broadcast radio service cannot be null");
-        mHal1 = Objects.requireNonNull(hal1,
+        mHal1Client = Objects.requireNonNull(hal1,
                 "Broadcast radio service implementation for HIDL 1 HAL cannot be null");
-        mV1Modules = mHal1.loadModules();
-        mHal2 = Objects.requireNonNull(hal2,
+        mV1Modules = mHal1Client.loadModules();
+        mHal2Client = Objects.requireNonNull(hal2,
                 "Broadcast radio service implementation for HIDL 2 HAL cannot be null");
     }
 
     @Override
     public List<RadioManager.ModuleProperties> listModules() {
         mService.enforcePolicyAccess();
-        Collection<RadioManager.ModuleProperties> v2Modules = mHal2.listModules();
+        Collection<RadioManager.ModuleProperties> v2Modules = mHal2Client.listModules();
         List<RadioManager.ModuleProperties> modules;
         synchronized (mLock) {
             modules = new ArrayList<>(mV1Modules.size() + v2Modules.size());
@@ -102,10 +102,10 @@
         mService.enforcePolicyAccess();
         Objects.requireNonNull(callback, "Callback must not be null");
         synchronized (mLock) {
-            if (mHal2.hasModule(moduleId)) {
-                return mHal2.openSession(moduleId, bandConfig, withAudio, callback);
+            if (mHal2Client.hasModule(moduleId)) {
+                return mHal2Client.openSession(moduleId, bandConfig, withAudio, callback);
             } else {
-                return mHal1.openTuner(moduleId, bandConfig, withAudio, callback);
+                return mHal1Client.openTuner(moduleId, bandConfig, withAudio, callback);
             }
         }
     }
@@ -121,12 +121,12 @@
         mService.enforcePolicyAccess();
 
         synchronized (mLock) {
-            if (!mHal2.hasAnyModules()) {
+            if (!mHal2Client.hasAnyModules()) {
                 Slog.w(TAG, "There are no HAL 2.0 modules registered");
                 return new AnnouncementAggregator(listener, mLock);
             }
 
-            return mHal2.addAnnouncementListener(enabledTypes, listener);
+            return mHal2Client.addAnnouncementListener(enabledTypes, listener);
         }
     }
 
@@ -143,18 +143,18 @@
         radioPw.printf("BroadcastRadioService\n");
 
         radioPw.increaseIndent();
-        radioPw.printf("HAL1: %s\n", mHal1);
+        radioPw.printf("HAL1 client: %s\n", mHal1Client);
 
         radioPw.increaseIndent();
         synchronized (mLock) {
-            radioPw.printf("Modules of HAL1: %s\n", mV1Modules);
+            radioPw.printf("Modules of HAL1 client: %s\n", mV1Modules);
         }
         radioPw.decreaseIndent();
 
-        radioPw.printf("HAL2:\n");
+        radioPw.printf("HAL2 client:\n");
 
         radioPw.increaseIndent();
-        mHal2.dumpInfo(radioPw);
+        mHal2Client.dumpInfo(radioPw);
         radioPw.decreaseIndent();
 
         radioPw.decreaseIndent();
diff --git a/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java b/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java
index 4b847a2..c705ebe 100644
--- a/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java
+++ b/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java
@@ -48,8 +48,8 @@
      * @return foreground user id.
      */
     public static int getCurrentUser() {
-        final long identity = Binder.clearCallingIdentity();
         int userId = UserHandle.USER_NULL;
+        final long identity = Binder.clearCallingIdentity();
         try {
             userId = ActivityManager.getCurrentUser();
         } catch (RuntimeException e) {
diff --git a/services/core/java/com/android/server/broadcastradio/hal1/Convert.java b/services/core/java/com/android/server/broadcastradio/hal1/Convert.java
index 219ee4c..08ff662 100644
--- a/services/core/java/com/android/server/broadcastradio/hal1/Convert.java
+++ b/services/core/java/com/android/server/broadcastradio/hal1/Convert.java
@@ -18,12 +18,13 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.util.Slog;
+
+import com.android.server.utils.Slogf;
 
 import java.util.Map;
 import java.util.Set;
 
-class Convert {
+final class Convert {
 
     private static final String TAG = "BcRadio1Srv.Convert";
 
@@ -34,12 +35,12 @@
      * side, which requires several separate java calls for each element.
      *
      * @param map map to convert.
-     * @returns array (sized the same as map) of two-element string arrays
-     *          (first element is the key, second is value).
+     * @return array (sized the same as map) of two-element string arrays
+     *         (first element is the key, second is value).
      */
     static @NonNull String[][] stringMapToNative(@Nullable Map<String, String> map) {
         if (map == null) {
-            Slog.v(TAG, "map is null, returning zero-elements array");
+            Slogf.v(TAG, "map is null, returning zero-elements array");
             return new String[0][0];
         }
 
@@ -54,7 +55,7 @@
             i++;
         }
 
-        Slog.v(TAG, "converted " + i + " element(s)");
+        Slogf.v(TAG, "converted " + i + " element(s)");
         return arr;
     }
 }
diff --git a/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java b/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java
index 8e5f6b5..7cac409 100644
--- a/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java
+++ b/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java
@@ -26,7 +26,6 @@
 import android.hardware.radio.RadioManager;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.util.Slog;
 
 import com.android.server.broadcastradio.RadioServiceUserController;
 import com.android.server.utils.Slogf;
@@ -44,9 +43,9 @@
     private final long mNativeContext;
 
     private final Object mLock = new Object();
-    @NonNull private final TunerCallback mTunerCallback;
-    @NonNull private final ITunerCallback mClientCallback;
-    @NonNull private final IBinder.DeathRecipient mDeathRecipient;
+    private final TunerCallback mTunerCallback;
+    private final ITunerCallback mClientCallback;
+    private final IBinder.DeathRecipient mDeathRecipient;
 
     private boolean mIsClosed = false;
     private boolean mIsMuted = false;
@@ -122,7 +121,7 @@
 
     private boolean checkConfiguredLocked() {
         if (mTunerCallback.isInitialConfigurationDone()) return true;
-        Slog.w(TAG, "Initial configuration is still pending, skipping the operation");
+        Slogf.w(TAG, "Initial configuration is still pending, skipping the operation");
         return false;
     }
 
@@ -159,14 +158,14 @@
             checkNotClosedLocked();
             if (mIsMuted == mute) return;
             mIsMuted = mute;
-            Slog.w(TAG, "Mute via RadioService is not implemented - please handle it via app");
+            Slogf.w(TAG, "Mute via RadioService is not implemented - please handle it via app");
         }
     }
 
     @Override
     public boolean isMuted() {
         if (!mWithAudio) {
-            Slog.w(TAG, "Tuner did not request audio, pretending it was muted");
+            Slogf.w(TAG, "Tuner did not request audio, pretending it was muted");
             return true;
         }
         synchronized (mLock) {
@@ -210,7 +209,7 @@
         if (selector == null) {
             throw new IllegalArgumentException("The argument must not be a null pointer");
         }
-        Slog.i(TAG, "Tuning to " + selector);
+        Slogf.i(TAG, "Tuning to " + selector);
         synchronized (mLock) {
             checkNotClosedLocked();
             if (!checkConfiguredLocked()) return;
diff --git a/services/core/java/com/android/server/broadcastradio/hal1/TunerCallback.java b/services/core/java/com/android/server/broadcastradio/hal1/TunerCallback.java
index aa43b75..e013643 100644
--- a/services/core/java/com/android/server/broadcastradio/hal1/TunerCallback.java
+++ b/services/core/java/com/android/server/broadcastradio/hal1/TunerCallback.java
@@ -25,7 +25,8 @@
 import android.hardware.radio.RadioTuner;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.util.Slog;
+
+import com.android.server.utils.Slogf;
 
 import java.util.List;
 import java.util.Map;
@@ -42,8 +43,8 @@
      */
     private final long mNativeContext;
 
-    @NonNull private final Tuner mTuner;
-    @NonNull private final ITunerCallback mClientCallback;
+    private final Tuner mTuner;
+    private final ITunerCallback mClientCallback;
 
     private final AtomicReference<ProgramList.Filter> mProgramListFilter = new AtomicReference<>();
     private boolean mInitialConfigurationDone = false;
@@ -76,7 +77,7 @@
         try {
             func.run();
         } catch (RemoteException e) {
-            Slog.e(TAG, "client died", e);
+            Slogf.e(TAG, "client died", e);
         }
     }
 
@@ -107,7 +108,7 @@
 
     @Override
     public void onTuneFailed(int result, ProgramSelector selector) {
-        Slog.e(TAG, "Not applicable for HAL 1.x");
+        Slogf.e(TAG, "Not applicable for HAL 1.x");
     }
 
     @Override
@@ -160,7 +161,7 @@
         try {
             modified = mTuner.getProgramList(filter.getVendorFilter());
         } catch (IllegalStateException ex) {
-            Slog.d(TAG, "Program list not ready yet");
+            Slogf.d(TAG, "Program list not ready yet");
             return;
         }
         Set<RadioManager.ProgramInfo> modifiedSet = modified.stream().collect(Collectors.toSet());
@@ -175,12 +176,12 @@
 
     @Override
     public void onConfigFlagUpdated(int flag, boolean value) {
-        Slog.w(TAG, "Not applicable for HAL 1.x");
+        Slogf.w(TAG, "Not applicable for HAL 1.x");
     }
 
     @Override
     public void onParametersUpdated(Map<String, String> parameters) {
-        Slog.w(TAG, "Not applicable for HAL 1.x");
+        Slogf.w(TAG, "Not applicable for HAL 1.x");
     }
 
     @Override
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/AnnouncementAggregator.java b/services/core/java/com/android/server/broadcastradio/hal2/AnnouncementAggregator.java
index 85c13ae..0327ee7 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/AnnouncementAggregator.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/AnnouncementAggregator.java
@@ -23,20 +23,20 @@
 import android.hardware.radio.ICloseHandle;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.server.utils.Slogf;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Objects;
 
-public class AnnouncementAggregator extends ICloseHandle.Stub {
+public final class AnnouncementAggregator extends ICloseHandle.Stub {
     private static final String TAG = "BcRadio2Srv.AnnAggr";
 
     private final Object mLock;
-    @NonNull private final IAnnouncementListener mListener;
+    private final IAnnouncementListener mListener;
     private final IBinder.DeathRecipient mDeathRecipient = new DeathRecipient();
 
     @GuardedBy("mLock")
@@ -77,14 +77,16 @@
         public void binderDied() {
             try {
                 close();
-            } catch (RemoteException ex) {}
+            } catch (RemoteException ex) {
+                Slogf.e(TAG, ex, "Cannot close Announcement aggregator for DeathRecipient");
+            }
         }
     }
 
     private void onListUpdated() {
         synchronized (mLock) {
             if (mIsClosed) {
-                Slog.e(TAG, "Announcement aggregator is closed, it shouldn't receive callbacks");
+                Slogf.e(TAG, "Announcement aggregator is closed, it shouldn't receive callbacks");
                 return;
             }
             List<Announcement> combined = new ArrayList<>();
@@ -94,7 +96,7 @@
             try {
                 mListener.onListUpdated(combined);
             } catch (RemoteException ex) {
-                Slog.e(TAG, "mListener.onListUpdated() failed: ", ex);
+                Slogf.e(TAG, "mListener.onListUpdated() failed: ", ex);
             }
         }
     }
@@ -111,7 +113,7 @@
             try {
                 closeHandle = module.addAnnouncementListener(enabledTypes, watcher);
             } catch (RemoteException ex) {
-                Slog.e(TAG, "Failed to add announcement listener", ex);
+                Slogf.e(TAG, "Failed to add announcement listener", ex);
                 return;
             }
             watcher.setCloseHandle(closeHandle);
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
index 1e31f20..3198842 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
@@ -29,8 +29,8 @@
 import android.hidl.manager.V1_0.IServiceNotification;
 import android.os.IHwBinder.DeathRecipient;
 import android.os.RemoteException;
+import android.util.ArrayMap;
 import android.util.IndentingPrintWriter;
-import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -38,7 +38,6 @@
 import com.android.server.utils.Slogf;
 
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 import java.util.stream.Collectors;
@@ -55,16 +54,17 @@
     private int mNextModuleId;
 
     @GuardedBy("mLock")
-    private final Map<String, Integer> mServiceNameToModuleIdMap = new HashMap<>();
+    private final Map<String, Integer> mServiceNameToModuleIdMap = new ArrayMap<>();
 
     // Map from module ID to RadioModule created by mServiceListener.onRegistration().
     @GuardedBy("mLock")
-    private final Map<Integer, RadioModule> mModules = new HashMap<>();
+    private final Map<Integer, RadioModule> mModules = new ArrayMap<>();
 
-    private IServiceNotification.Stub mServiceListener = new IServiceNotification.Stub() {
+    private final IServiceNotification.Stub mServiceListener = new IServiceNotification.Stub() {
         @Override
         public void onRegistration(String fqName, String serviceName, boolean preexisting) {
-            Slog.v(TAG, "onRegistration(" + fqName + ", " + serviceName + ", " + preexisting + ")");
+            Slogf.v(TAG, "onRegistration(" + fqName + ", " + serviceName + ", " + preexisting
+                    + ")");
             Integer moduleId;
             synchronized (mLock) {
                 // If the service has been registered before, reuse its previous module ID.
@@ -75,13 +75,13 @@
                     moduleId = mNextModuleId;
                 }
 
-                RadioModule module = RadioModule.tryLoadingModule(moduleId, serviceName);
-                if (module == null) {
+                RadioModule radioModule = RadioModule.tryLoadingModule(moduleId, serviceName);
+                if (radioModule == null) {
                     return;
                 }
-                Slog.v(TAG, "loaded broadcast radio module " + moduleId + ": " + serviceName
+                Slogf.v(TAG, "loaded broadcast radio module " + moduleId + ": " + serviceName
                         + " (HAL 2.0)");
-                RadioModule prevModule = mModules.put(moduleId, module);
+                RadioModule prevModule = mModules.put(moduleId, radioModule);
                 if (prevModule != null) {
                     prevModule.closeSessions(RadioTuner.ERROR_HARDWARE_FAILURE);
                 }
@@ -92,7 +92,7 @@
                 }
 
                 try {
-                    module.getService().linkToDeath(mDeathRecipient, moduleId);
+                    radioModule.getService().linkToDeath(mDeathRecipient, moduleId);
                 } catch (RemoteException ex) {
                     // Service has already died, so remove its entry from mModules.
                     mModules.remove(moduleId);
@@ -101,10 +101,10 @@
         }
     };
 
-    private DeathRecipient mDeathRecipient = new DeathRecipient() {
+    private final DeathRecipient mDeathRecipient = new DeathRecipient() {
         @Override
         public void serviceDied(long cookie) {
-            Slog.v(TAG, "serviceDied(" + cookie + ")");
+            Slogf.v(TAG, "serviceDied(" + cookie + ")");
             synchronized (mLock) {
                 int moduleId = (int) cookie;
                 RadioModule prevModule = mModules.remove(moduleId);
@@ -114,7 +114,7 @@
 
                 for (Map.Entry<String, Integer> entry : mServiceNameToModuleIdMap.entrySet()) {
                     if (entry.getValue() == moduleId) {
-                        Slog.i(TAG, "service " + entry.getKey()
+                        Slogf.i(TAG, "service " + entry.getKey()
                                 + " died; removed RadioModule with ID " + moduleId);
                         return;
                     }
@@ -128,12 +128,12 @@
         try {
             IServiceManager manager = IServiceManager.getService();
             if (manager == null) {
-                Slog.e(TAG, "failed to get HIDL Service Manager");
+                Slogf.e(TAG, "failed to get HIDL Service Manager");
                 return;
             }
             manager.registerForNotifications(IBroadcastRadio.kInterfaceName, "", mServiceListener);
         } catch (RemoteException ex) {
-            Slog.e(TAG, "failed to register for service notifications: ", ex);
+            Slogf.e(TAG, "failed to register for service notifications: ", ex);
         }
     }
 
@@ -144,12 +144,12 @@
         try {
             manager.registerForNotifications(IBroadcastRadio.kInterfaceName, "", mServiceListener);
         } catch (RemoteException ex) {
-            Slog.e(TAG, "Failed to register for service notifications: ", ex);
+            Slogf.e(TAG, "Failed to register for service notifications: ", ex);
         }
     }
 
     public @NonNull Collection<RadioManager.ModuleProperties> listModules() {
-        Slog.v(TAG, "List HIDL 2.0 modules");
+        Slogf.v(TAG, "List HIDL 2.0 modules");
         synchronized (mLock) {
             return mModules.values().stream().map(module -> module.getProperties())
                     .collect(Collectors.toList());
@@ -170,7 +170,7 @@
 
     public ITuner openSession(int moduleId, @Nullable RadioManager.BandConfig legacyConfig,
             boolean withAudio, @NonNull ITunerCallback callback) throws RemoteException {
-        Slog.v(TAG, "Open HIDL 2.0 session with module id " + moduleId);
+        Slogf.v(TAG, "Open HIDL 2.0 session with module id " + moduleId);
         if (!RadioServiceUserController.isCurrentOrSystemUser()) {
             Slogf.e(TAG, "Cannot open tuner on HAL 2.0 client for non-current user");
             throw new IllegalStateException("Cannot open session for non-current user");
@@ -198,7 +198,7 @@
 
     public ICloseHandle addAnnouncementListener(@NonNull int[] enabledTypes,
             @NonNull IAnnouncementListener listener) {
-        Slog.v(TAG, "Add announcementListener");
+        Slogf.v(TAG, "Add announcementListener");
         AnnouncementAggregator aggregator = new AnnouncementAggregator(listener, mLock);
         boolean anySupported = false;
         synchronized (mLock) {
@@ -207,12 +207,12 @@
                     aggregator.watchModule(module, enabledTypes);
                     anySupported = true;
                 } catch (UnsupportedOperationException ex) {
-                    Slog.v(TAG, "Announcements not supported for this module", ex);
+                    Slogf.v(TAG, "Announcements not supported for this module", ex);
                 }
             }
         }
         if (!anySupported) {
-            Slog.i(TAG, "There are no HAL modules that support announcements");
+            Slogf.i(TAG, "There are no HAL modules that support announcements");
         }
         return aggregator;
     }
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/Convert.java b/services/core/java/com/android/server/broadcastradio/hal2/Convert.java
index fb1138f..34bfa6c 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/Convert.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/Convert.java
@@ -37,21 +37,22 @@
 import android.hardware.radio.RadioMetadata;
 import android.hardware.radio.RadioTuner;
 import android.os.ParcelableException;
-import android.util.Slog;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.SparseArray;
+
+import com.android.server.utils.Slogf;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
 
-class Convert {
+final class Convert {
 
     private static final String TAG = "BcRadio2Srv.convert";
 
@@ -111,7 +112,7 @@
             elem.key = entry.getKey();
             elem.value = entry.getValue();
             if (elem.key == null || elem.value == null) {
-                Slog.w(TAG, "VendorKeyValue contains null pointers");
+                Slogf.w(TAG, "VendorKeyValue contains null pointers");
                 continue;
             }
             list.add(elem);
@@ -120,20 +121,21 @@
         return list;
     }
 
-    static @NonNull Map<String, String>
-    vendorInfoFromHal(@Nullable List<VendorKeyValue> info) {
-        if (info == null) return Collections.emptyMap();
-
-        Map<String, String> map = new HashMap<>();
-        for (VendorKeyValue kvp : info) {
-            if (kvp.key == null || kvp.value == null) {
-                Slog.w(TAG, "VendorKeyValue contains null pointers");
-                continue;
-            }
-            map.put(kvp.key, kvp.value);
+    static @NonNull Map<String, String> vendorInfoFromHal(@Nullable List<VendorKeyValue> info) {
+        Map<String, String> vendorInfoMap = new ArrayMap<>();
+        if (info == null) {
+            return vendorInfoMap;
         }
 
-        return map;
+        for (VendorKeyValue kvp : info) {
+            if (kvp.key == null || kvp.value == null) {
+                Slogf.w(TAG, "VendorKeyValue contains null pointers");
+                continue;
+            }
+            vendorInfoMap.put(kvp.key, kvp.value);
+        }
+
+        return vendorInfoMap;
     }
 
     private static @ProgramSelector.ProgramType int identifierTypeToProgramType(
@@ -168,7 +170,7 @@
 
     private static @NonNull int[]
     identifierTypesToProgramTypes(@NonNull int[] idTypes) {
-        Set<Integer> pTypes = new HashSet<>();
+        Set<Integer> pTypes = new ArraySet<>();
 
         for (int idType : idTypes) {
             int pType = identifierTypeToProgramType(idType);
@@ -202,7 +204,7 @@
         for (AmFmBandRange range : config.ranges) {
             FrequencyBand bandType = Utils.getBand(range.lowerBound);
             if (bandType == FrequencyBand.UNKNOWN) {
-                Slog.e(TAG, "Unknown frequency band at " + range.lowerBound + "kHz");
+                Slogf.e(TAG, "Unknown frequency band at " + range.lowerBound + "kHz");
                 continue;
             }
             if (bandType == FrequencyBand.FM) {
@@ -304,7 +306,7 @@
             @NonNull android.hardware.broadcastradio.V2_0.ProgramSelector sel) {
         if (sel.primaryId.type != 0) return false;
         if (sel.primaryId.value != 0) return false;
-        if (sel.secondaryIds.size() != 0) return false;
+        if (!sel.secondaryIds.isEmpty()) return false;
         return true;
     }
 
@@ -319,7 +321,7 @@
         return new ProgramSelector(
                 identifierTypeToProgramType(sel.primaryId.type),
                 Objects.requireNonNull(programIdentifierFromHal(sel.primaryId)),
-                secondaryIds, null);
+                secondaryIds, /* vendorIds= */ null);
     }
 
     private enum MetadataType {
@@ -335,40 +337,40 @@
         }
     }
 
-    private static final Map<Integer, MetadataDef> metadataKeys;
+    private static final SparseArray<MetadataDef> METADATA_KEYS;
     static {
-        metadataKeys = new HashMap<>();
-        metadataKeys.put(MetadataKey.RDS_PS, new MetadataDef(
+        METADATA_KEYS = new SparseArray<>();
+        METADATA_KEYS.put(MetadataKey.RDS_PS, new MetadataDef(
                 MetadataType.STRING, RadioMetadata.METADATA_KEY_RDS_PS));
-        metadataKeys.put(MetadataKey.RDS_PTY, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.RDS_PTY, new MetadataDef(
                 MetadataType.INT, RadioMetadata.METADATA_KEY_RDS_PTY));
-        metadataKeys.put(MetadataKey.RBDS_PTY, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.RBDS_PTY, new MetadataDef(
                 MetadataType.INT, RadioMetadata.METADATA_KEY_RBDS_PTY));
-        metadataKeys.put(MetadataKey.RDS_RT, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.RDS_RT, new MetadataDef(
                 MetadataType.STRING, RadioMetadata.METADATA_KEY_RDS_RT));
-        metadataKeys.put(MetadataKey.SONG_TITLE, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.SONG_TITLE, new MetadataDef(
                 MetadataType.STRING, RadioMetadata.METADATA_KEY_TITLE));
-        metadataKeys.put(MetadataKey.SONG_ARTIST, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.SONG_ARTIST, new MetadataDef(
                 MetadataType.STRING, RadioMetadata.METADATA_KEY_ARTIST));
-        metadataKeys.put(MetadataKey.SONG_ALBUM, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.SONG_ALBUM, new MetadataDef(
                 MetadataType.STRING, RadioMetadata.METADATA_KEY_ALBUM));
-        metadataKeys.put(MetadataKey.STATION_ICON, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.STATION_ICON, new MetadataDef(
                 MetadataType.INT, RadioMetadata.METADATA_KEY_ICON));
-        metadataKeys.put(MetadataKey.ALBUM_ART, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.ALBUM_ART, new MetadataDef(
                 MetadataType.INT, RadioMetadata.METADATA_KEY_ART));
-        metadataKeys.put(MetadataKey.PROGRAM_NAME, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.PROGRAM_NAME, new MetadataDef(
                 MetadataType.STRING, RadioMetadata.METADATA_KEY_PROGRAM_NAME));
-        metadataKeys.put(MetadataKey.DAB_ENSEMBLE_NAME, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.DAB_ENSEMBLE_NAME, new MetadataDef(
                 MetadataType.STRING, RadioMetadata.METADATA_KEY_DAB_ENSEMBLE_NAME));
-        metadataKeys.put(MetadataKey.DAB_ENSEMBLE_NAME_SHORT, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.DAB_ENSEMBLE_NAME_SHORT, new MetadataDef(
                 MetadataType.STRING, RadioMetadata.METADATA_KEY_DAB_ENSEMBLE_NAME_SHORT));
-        metadataKeys.put(MetadataKey.DAB_SERVICE_NAME, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.DAB_SERVICE_NAME, new MetadataDef(
                 MetadataType.STRING, RadioMetadata.METADATA_KEY_DAB_SERVICE_NAME));
-        metadataKeys.put(MetadataKey.DAB_SERVICE_NAME_SHORT, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.DAB_SERVICE_NAME_SHORT, new MetadataDef(
                 MetadataType.STRING, RadioMetadata.METADATA_KEY_DAB_SERVICE_NAME_SHORT));
-        metadataKeys.put(MetadataKey.DAB_COMPONENT_NAME, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.DAB_COMPONENT_NAME, new MetadataDef(
                 MetadataType.STRING, RadioMetadata.METADATA_KEY_DAB_COMPONENT_NAME));
-        metadataKeys.put(MetadataKey.DAB_COMPONENT_NAME_SHORT, new MetadataDef(
+        METADATA_KEYS.put(MetadataKey.DAB_COMPONENT_NAME_SHORT, new MetadataDef(
                 MetadataType.STRING, RadioMetadata.METADATA_KEY_DAB_COMPONENT_NAME_SHORT));
     }
 
@@ -376,9 +378,9 @@
         RadioMetadata.Builder builder = new RadioMetadata.Builder();
 
         for (Metadata entry : meta) {
-            MetadataDef keyDef = metadataKeys.get(entry.key);
+            MetadataDef keyDef = METADATA_KEYS.get(entry.key);
             if (keyDef == null) {
-                Slog.i(TAG, "Ignored unknown metadata entry: " + MetadataKey.toString(entry.key));
+                Slogf.i(TAG, "Ignored unknown metadata entry: " + MetadataKey.toString(entry.key));
                 continue;
             }
             if (keyDef.type == MetadataType.STRING) {
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioEventLogger.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioEventLogger.java
index 48112c4..b8d1228 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/RadioEventLogger.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioEventLogger.java
@@ -19,7 +19,8 @@
 import android.util.IndentingPrintWriter;
 import android.util.LocalLog;
 import android.util.Log;
-import android.util.Slog;
+
+import com.android.server.utils.Slogf;
 
 final class RadioEventLogger {
     private final String mTag;
@@ -30,11 +31,12 @@
         mEventLogger = new LocalLog(loggerQueueSize);
     }
 
+    @SuppressWarnings("AnnotateFormatMethod")
     void logRadioEvent(String logFormat, Object... args) {
         String log = String.format(logFormat, args);
         mEventLogger.log(log);
         if (Log.isLoggable(mTag, Log.DEBUG)) {
-            Slog.d(mTag, log);
+            Slogf.d(mTag, log);
         }
     }
 
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
index a54af2e..0e11df8 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
@@ -39,16 +39,16 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
 import android.util.MutableInt;
-import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.broadcastradio.RadioServiceUserController;
+import com.android.server.utils.Slogf;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -59,12 +59,12 @@
     private static final String TAG = "BcRadio2Srv.module";
     private static final int RADIO_EVENT_LOGGER_QUEUE_SIZE = 25;
 
-    @NonNull private final IBroadcastRadio mService;
-    @NonNull private final RadioManager.ModuleProperties mProperties;
+    private final IBroadcastRadio mService;
+    private final RadioManager.ModuleProperties mProperties;
 
     private final Object mLock = new Object();
-    @NonNull private final Handler mHandler;
-    @NonNull private final RadioEventLogger mEventLogger;
+    private final Handler mHandler;
+    private final RadioEventLogger mEventLogger;
 
     @GuardedBy("mLock")
     private ITunerSession mHalTunerSession;
@@ -144,7 +144,7 @@
 
     // Collection of active AIDL tuner sessions created through openSession().
     @GuardedBy("mLock")
-    private final Set<TunerSession> mAidlTunerSessions = new HashSet<>();
+    private final Set<TunerSession> mAidlTunerSessions = new ArraySet<>();
 
     @VisibleForTesting
     RadioModule(@NonNull IBroadcastRadio service,
@@ -158,10 +158,10 @@
     @Nullable
     static RadioModule tryLoadingModule(int idx, @NonNull String fqName) {
         try {
-            Slog.i(TAG, "Try loading module for idx " + idx + ", fqName " + fqName);
+            Slogf.i(TAG, "Try loading module for idx " + idx + ", fqName " + fqName);
             IBroadcastRadio service = IBroadcastRadio.getService(fqName);
             if (service == null) {
-                Slog.w(TAG, "No service found for fqName " + fqName);
+                Slogf.w(TAG, "No service found for fqName " + fqName);
                 return null;
             }
 
@@ -180,7 +180,7 @@
 
             return new RadioModule(service, prop);
         } catch (RemoteException ex) {
-            Slog.e(TAG, "Failed to load module " + fqName, ex);
+            Slogf.e(TAG, "Failed to load module " + fqName, ex);
             return null;
         }
     }
@@ -256,8 +256,8 @@
             }
 
             if (idTypes == null) {
-                idTypes = new HashSet<>(filter.getIdentifierTypes());
-                ids = new HashSet<>(filter.getIdentifiers());
+                idTypes = new ArraySet<>(filter.getIdentifierTypes());
+                ids = new ArraySet<>(filter.getIdentifiers());
                 includeCategories = filter.areCategoriesIncluded();
                 excludeModifications = filter.areModificationsExcluded();
                 continue;
@@ -305,7 +305,7 @@
             try {
                 mHalTunerSession.stopProgramListUpdates();
             } catch (RemoteException ex) {
-                Slog.e(TAG, "mHalTunerSession.stopProgramListUpdates() failed: ", ex);
+                Slogf.e(TAG, "mHalTunerSession.stopProgramListUpdates() failed: ", ex);
             }
             return;
         }
@@ -327,7 +327,7 @@
                     newFilter));
             Convert.throwOnError("startProgramListUpdates", halResult);
         } catch (RemoteException ex) {
-            Slog.e(TAG, "mHalTunerSession.startProgramListUpdates() failed: ", ex);
+            Slogf.e(TAG, "mHalTunerSession.startProgramListUpdates() failed: ", ex);
         }
     }
 
@@ -348,7 +348,7 @@
             try {
                 mHalTunerSession.close();
             } catch (RemoteException ex) {
-                Slog.e(TAG, "mHalTunerSession.close() failed: ", ex);
+                Slogf.e(TAG, "mHalTunerSession.close() failed: ", ex);
             }
             mHalTunerSession = null;
         }
@@ -385,18 +385,17 @@
                 runnable.run(tunerSession.mCallback);
             } catch (DeadObjectException ex) {
                 // The other side died without calling close(), so just purge it from our records.
-                Slog.e(TAG, "Removing dead TunerSession");
+                Slogf.e(TAG, "Removing dead TunerSession");
                 if (deadSessions == null) {
                     deadSessions = new ArrayList<>();
                 }
                 deadSessions.add(tunerSession);
             } catch (RemoteException ex) {
-                Slog.e(TAG, "Failed to invoke ITunerCallback: ", ex);
+                Slogf.e(TAG, "Failed to invoke ITunerCallback: ", ex);
             }
         }
         if (deadSessions != null) {
-            onTunerSessionsClosedLocked(deadSessions.toArray(
-                    new TunerSession[deadSessions.size()]));
+            onTunerSessionsClosedLocked(deadSessions.toArray(new TunerSession[0]));
         }
     }
 
@@ -429,7 +428,7 @@
                 try {
                     hwCloseHandle.value.close();
                 } catch (RemoteException ex) {
-                    Slog.e(TAG, "Failed closing announcement listener", ex);
+                    Slogf.e(TAG, "Failed closing announcement listener", ex);
                 }
                 hwCloseHandle.value = null;
             }
@@ -447,7 +446,9 @@
             rawImage[i] = rawList.get(i);
         }
 
-        if (rawImage == null || rawImage.length == 0) return null;
+        if (rawImage.length == 0) {
+            return null;
+        }
 
         return BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length);
     }
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
index 978dc01..6d435e3 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java
@@ -30,27 +30,25 @@
 import android.os.Binder;
 import android.os.RemoteException;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
 import android.util.MutableBoolean;
 import android.util.MutableInt;
-import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.broadcastradio.RadioServiceUserController;
 import com.android.server.utils.Slogf;
 
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 
-class TunerSession extends ITuner.Stub {
+final class TunerSession extends ITuner.Stub {
     private static final String TAG = "BcRadio2Srv.session";
-    private static final String kAudioDeviceName = "Radio tuner source";
     private static final int TUNER_EVENT_LOGGER_QUEUE_SIZE = 25;
 
     private final Object mLock = new Object();
-    @NonNull private final RadioEventLogger mEventLogger;
+    private final RadioEventLogger mEventLogger;
 
     private final RadioModule mModule;
     private final ITunerSession mHwSession;
@@ -99,7 +97,7 @@
             try {
                 mCallback.onError(error);
             } catch (RemoteException ex) {
-                Slog.w(TAG, "mCallback.onError() failed: ", ex);
+                Slogf.w(TAG, "mCallback.onError() failed: ", ex);
             }
         }
         mModule.onTunerSessionClosed(this);
@@ -129,7 +127,7 @@
             checkNotClosedLocked();
             mDummyConfig = Objects.requireNonNull(config);
         }
-        Slog.i(TAG, "Ignoring setConfiguration - not applicable for broadcastradio HAL 2.0");
+        Slogf.i(TAG, "Ignoring setConfiguration - not applicable for broadcastradio HAL 2.0");
         mModule.fanoutAidlCallback(cb -> cb.onConfigurationChanged(config));
     }
 
@@ -148,7 +146,7 @@
             if (mIsMuted == mute) return;
             mIsMuted = mute;
         }
-        Slog.w(TAG, "Mute via RadioService is not implemented - please handle it via app");
+        Slogf.w(TAG, "Mute via RadioService is not implemented - please handle it via app");
     }
 
     @Override
@@ -205,7 +203,7 @@
 
     @Override
     public void cancel() {
-        Slog.i(TAG, "Cancel");
+        Slogf.i(TAG, "Cancel");
         if (!RadioServiceUserController.isCurrentOrSystemUser()) {
             Slogf.w(TAG, "Cannot cancel on HAL 2.0 client from non-current user");
             return;
@@ -218,7 +216,8 @@
 
     @Override
     public void cancelAnnouncement() {
-        Slog.w(TAG, "Announcements control doesn't involve cancelling at the HAL level in HAL 2.0");
+        Slogf.w(TAG,
+                "Announcements control doesn't involve cancelling at the HAL level in HAL 2.0");
     }
 
     @Override
@@ -229,7 +228,7 @@
 
     @Override
     public boolean startBackgroundScan() {
-        Slog.w(TAG, "Explicit background scan trigger is not supported with HAL 2.0");
+        Slogf.w(TAG, "Explicit background scan trigger is not supported with HAL 2.0");
         if (!RadioServiceUserController.isCurrentOrSystemUser()) {
             Slogf.w(TAG,
                     "Cannot start background scan on HAL 2.0 client from non-current user");
@@ -240,7 +239,7 @@
     }
 
     @Override
-    public void startProgramListUpdates(ProgramList.Filter filter) throws RemoteException {
+    public void startProgramListUpdates(ProgramList.Filter filter) {
         mEventLogger.logRadioEvent("start programList updates %s", filter);
         if (!RadioServiceUserController.isCurrentOrSystemUser()) {
             Slogf.w(TAG,
@@ -250,8 +249,8 @@
         // If the AIDL client provides a null filter, it wants all updates, so use the most broad
         // filter.
         if (filter == null) {
-            filter = new ProgramList.Filter(new HashSet<Integer>(),
-                    new HashSet<android.hardware.radio.ProgramSelector.Identifier>(), true, false);
+            filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(),
+                    /* includeCategories= */ true, /* excludeModifications= */ false);
         }
         synchronized (mLock) {
             checkNotClosedLocked();
@@ -285,7 +284,7 @@
             if (mProgramInfoCache == null) {
                 return;
             }
-            clientUpdateChunks = mProgramInfoCache.filterAndUpdateFrom(halCache, true);
+            clientUpdateChunks = mProgramInfoCache.filterAndUpdateFrom(halCache, /* purge= */ true);
         }
         dispatchClientUpdateChunks(clientUpdateChunks);
     }
@@ -298,7 +297,7 @@
             try {
                 mCallback.onProgramListUpdated(chunk);
             } catch (RemoteException ex) {
-                Slog.w(TAG, "mCallback.onProgramListUpdated() failed: ", ex);
+                Slogf.w(TAG, "mCallback.onProgramListUpdated() failed: ", ex);
             }
         }
     }
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index 333f62a..3ad6a4a 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -347,6 +347,11 @@
             return target + ", enabled=" + enabled + ", syncable=" + syncable + ", backoff="
                     + backoffTime + ", delay=" + delayUntil;
         }
+
+        public String toSafeString() {
+            return target.toSafeString() + ", enabled=" + enabled + ", syncable=" + syncable
+                    + ", backoff=" + backoffTime + ", delay=" + delayUntil;
+        }
     }
 
     public static class SyncHistoryItem {
@@ -553,7 +558,7 @@
             final int size = mAuthorities.size();
             mLogger.log("Loaded ", size, " items");
             for (int i = 0; i < size; i++) {
-                mLogger.log(mAuthorities.valueAt(i));
+                mLogger.log(mAuthorities.valueAt(i).toSafeString());
             }
         }
     }
@@ -734,7 +739,7 @@
             Slog.d(TAG, "setSyncAutomatically: " + /* account + */" provider " + providerName
                     + ", user " + userId + " -> " + sync);
         }
-        mLogger.log("Set sync auto account=", account,
+        mLogger.log("Set sync auto account=", account.toSafeString(),
                 " user=", userId,
                 " authority=", providerName,
                 " value=", Boolean.toString(sync),
@@ -812,7 +817,8 @@
     private void setSyncableStateForEndPoint(EndPoint target, int syncable,
             int callingUid, int callingPid) {
         AuthorityInfo aInfo;
-        mLogger.log("Set syncable ", target, " value=", Integer.toString(syncable),
+        mLogger.log("Set syncable ", target.toSafeString(),
+                " value=", Integer.toString(syncable),
                 " cuid=", callingUid,
                 " cpid=", callingPid);
         synchronized (mAuthorities) {
diff --git a/services/core/java/com/android/server/devicestate/OWNERS b/services/core/java/com/android/server/devicestate/OWNERS
index ae79fc0..43f3f0c 100644
--- a/services/core/java/com/android/server/devicestate/OWNERS
+++ b/services/core/java/com/android/server/devicestate/OWNERS
@@ -1,3 +1,4 @@
 ogunwale@google.com
 akulian@google.com
-darryljohnson@google.com
+lihongyu@google.com
+kennethford@google.com
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 4aab9d2..06dc7f5 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -55,6 +55,7 @@
 import com.android.server.EventLogTags;
 import com.android.server.display.brightness.BrightnessEvent;
 import com.android.server.display.brightness.clamper.BrightnessClamperController;
+import com.android.server.display.config.HysteresisLevels;
 
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -673,14 +674,10 @@
         }
 
         pw.println();
-        pw.println("  mAmbientBrightnessThresholds=");
-        mAmbientBrightnessThresholds.dump(pw);
-        pw.println("  mScreenBrightnessThresholds=");
-        mScreenBrightnessThresholds.dump(pw);
-        pw.println("  mScreenBrightnessThresholdsIdle=");
-        mScreenBrightnessThresholdsIdle.dump(pw);
-        pw.println("  mAmbientBrightnessThresholdsIdle=");
-        mAmbientBrightnessThresholdsIdle.dump(pw);
+        pw.println("  mAmbientBrightnessThresholds=" + mAmbientBrightnessThresholds);
+        pw.println("  mAmbientBrightnessThresholdsIdle=" + mAmbientBrightnessThresholdsIdle);
+        pw.println("  mScreenBrightnessThresholds=" + mScreenBrightnessThresholds);
+        pw.println("  mScreenBrightnessThresholdsIdle=" + mScreenBrightnessThresholdsIdle);
     }
 
     public float[] getLastSensorValues() {
diff --git a/services/core/java/com/android/server/display/BrightnessRangeController.java b/services/core/java/com/android/server/display/BrightnessRangeController.java
index 10030b3..dc0e80c 100644
--- a/services/core/java/com/android/server/display/BrightnessRangeController.java
+++ b/services/core/java/com/android/server/display/BrightnessRangeController.java
@@ -117,6 +117,7 @@
                 () -> mNormalBrightnessModeController.setAutoBrightnessState(state),
                 () ->  mHbmController.setAutoBrightnessEnabled(state)
         );
+        mHdrClamper.setAutoBrightnessState(state);
     }
 
     void onBrightnessChanged(float brightness, float unthrottledBrightness,
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 09094ff..4bbddae 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -162,8 +162,8 @@
         DisplayDeviceInfo displayDeviceInfo = getDisplayDeviceInfoLocked();
         var width = displayDeviceInfo.width;
         var height = displayDeviceInfo.height;
-        if (mIsAnisotropyCorrectionEnabled && displayDeviceInfo.yDpi > 0
-                    && displayDeviceInfo.xDpi > 0) {
+        if (mIsAnisotropyCorrectionEnabled && displayDeviceInfo.type == Display.TYPE_EXTERNAL
+                    && displayDeviceInfo.yDpi > 0 && displayDeviceInfo.xDpi > 0) {
             if (displayDeviceInfo.xDpi > displayDeviceInfo.yDpi * MAX_ANISOTROPY) {
                 height = (int) (height * displayDeviceInfo.xDpi / displayDeviceInfo.yDpi + 0.5);
             } else if (displayDeviceInfo.xDpi * MAX_ANISOTROPY < displayDeviceInfo.yDpi) {
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 61ecb93..85a231f 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -33,7 +33,6 @@
 import android.os.PowerManager;
 import android.text.TextUtils;
 import android.util.MathUtils;
-import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.Spline;
@@ -46,7 +45,6 @@
 import com.android.server.display.config.AutoBrightness;
 import com.android.server.display.config.BlockingZoneConfig;
 import com.android.server.display.config.BrightnessLimitMap;
-import com.android.server.display.config.BrightnessThresholds;
 import com.android.server.display.config.BrightnessThrottlingMap;
 import com.android.server.display.config.BrightnessThrottlingPoint;
 import com.android.server.display.config.Density;
@@ -58,6 +56,7 @@
 import com.android.server.display.config.HbmTiming;
 import com.android.server.display.config.HdrBrightnessData;
 import com.android.server.display.config.HighBrightnessMode;
+import com.android.server.display.config.HysteresisLevels;
 import com.android.server.display.config.IdleScreenRefreshRateTimeout;
 import com.android.server.display.config.IdleScreenRefreshRateTimeoutLuxThresholdPoint;
 import com.android.server.display.config.IdleScreenRefreshRateTimeoutLuxThresholds;
@@ -80,7 +79,6 @@
 import com.android.server.display.config.SensorData;
 import com.android.server.display.config.ThermalStatus;
 import com.android.server.display.config.ThermalThrottling;
-import com.android.server.display.config.ThresholdPoint;
 import com.android.server.display.config.UsiVersion;
 import com.android.server.display.config.XmlParser;
 import com.android.server.display.feature.DisplayManagerFlags;
@@ -625,13 +623,6 @@
     private static final int DEFAULT_HIGH_REFRESH_RATE = 0;
     private static final float[] DEFAULT_BRIGHTNESS_THRESHOLDS = new float[]{};
 
-    private static final float[] DEFAULT_AMBIENT_THRESHOLD_LEVELS = new float[]{0f};
-    private static final float[] DEFAULT_AMBIENT_BRIGHTENING_THRESHOLDS = new float[]{100f};
-    private static final float[] DEFAULT_AMBIENT_DARKENING_THRESHOLDS = new float[]{200f};
-    private static final float[] DEFAULT_SCREEN_THRESHOLD_LEVELS = new float[]{0f};
-    private static final float[] DEFAULT_SCREEN_BRIGHTENING_THRESHOLDS = new float[]{100f};
-    private static final float[] DEFAULT_SCREEN_DARKENING_THRESHOLDS = new float[]{200f};
-
     private static final int INTERPOLATION_DEFAULT = 0;
     private static final int INTERPOLATION_LINEAR = 1;
 
@@ -713,38 +704,16 @@
     private long mBrightnessRampIncreaseMaxIdleMillis = 0;
     private int mAmbientHorizonLong = AMBIENT_LIGHT_LONG_HORIZON_MILLIS;
     private int mAmbientHorizonShort = AMBIENT_LIGHT_SHORT_HORIZON_MILLIS;
-    private float mScreenBrighteningMinThreshold = 0.0f;     // Retain behaviour as though there is
-    private float mScreenBrighteningMinThresholdIdle = 0.0f; // no minimum threshold for change in
-    private float mScreenDarkeningMinThreshold = 0.0f;       // screen brightness or ambient
-    private float mScreenDarkeningMinThresholdIdle = 0.0f;   // brightness.
-    private float mAmbientLuxBrighteningMinThreshold = 0.0f;
-    private float mAmbientLuxBrighteningMinThresholdIdle = 0.0f;
-    private float mAmbientLuxDarkeningMinThreshold = 0.0f;
-    private float mAmbientLuxDarkeningMinThresholdIdle = 0.0f;
 
-    // Screen brightness thresholds levels & percentages
-    private float[] mScreenBrighteningLevels = DEFAULT_SCREEN_THRESHOLD_LEVELS;
-    private float[] mScreenBrighteningPercentages = DEFAULT_SCREEN_BRIGHTENING_THRESHOLDS;
-    private float[] mScreenDarkeningLevels = DEFAULT_SCREEN_THRESHOLD_LEVELS;
-    private float[] mScreenDarkeningPercentages = DEFAULT_SCREEN_DARKENING_THRESHOLDS;
-
-    // Screen brightness thresholds levels & percentages for idle mode
-    private float[] mScreenBrighteningLevelsIdle = DEFAULT_SCREEN_THRESHOLD_LEVELS;
-    private float[] mScreenBrighteningPercentagesIdle = DEFAULT_SCREEN_BRIGHTENING_THRESHOLDS;
-    private float[] mScreenDarkeningLevelsIdle = DEFAULT_SCREEN_THRESHOLD_LEVELS;
-    private float[] mScreenDarkeningPercentagesIdle = DEFAULT_SCREEN_DARKENING_THRESHOLDS;
-
-    // Ambient brightness thresholds levels & percentages
-    private float[] mAmbientBrighteningLevels = DEFAULT_AMBIENT_THRESHOLD_LEVELS;
-    private float[] mAmbientBrighteningPercentages = DEFAULT_AMBIENT_BRIGHTENING_THRESHOLDS;
-    private float[] mAmbientDarkeningLevels = DEFAULT_AMBIENT_THRESHOLD_LEVELS;
-    private float[] mAmbientDarkeningPercentages = DEFAULT_AMBIENT_DARKENING_THRESHOLDS;
-
-    // Ambient brightness thresholds levels & percentages for idle mode
-    private float[] mAmbientBrighteningLevelsIdle = DEFAULT_AMBIENT_THRESHOLD_LEVELS;
-    private float[] mAmbientBrighteningPercentagesIdle = DEFAULT_AMBIENT_BRIGHTENING_THRESHOLDS;
-    private float[] mAmbientDarkeningLevelsIdle = DEFAULT_AMBIENT_THRESHOLD_LEVELS;
-    private float[] mAmbientDarkeningPercentagesIdle = DEFAULT_AMBIENT_DARKENING_THRESHOLDS;
+    // Hysteresis levels for screen/ambient brightness for normal/idle modes
+    private HysteresisLevels mScreenBrightnessHysteresis =
+            HysteresisLevels.loadDisplayBrightnessConfig(null, null);
+    private HysteresisLevels mScreenBrightnessIdleHysteresis =
+            HysteresisLevels.loadDisplayBrightnessIdleConfig(null, null);
+    private HysteresisLevels mAmbientBrightnessHysteresis =
+            HysteresisLevels.loadAmbientBrightnessConfig(null, null);
+    private HysteresisLevels mAmbientBrightnessIdleHysteresis =
+            HysteresisLevels.loadAmbientBrightnessIdleConfig(null, null);
 
     // A mapping between screen off sensor values and lux values
     private int[] mScreenOffBrightnessSensorValueToLux;
@@ -1302,324 +1271,20 @@
         return mAmbientHorizonShort;
     }
 
-    /**
-     * The minimum value for the screen brightness increase to actually occur.
-     * @return float value in brightness scale of 0 - 1.
-     */
-    public float getScreenBrighteningMinThreshold() {
-        return mScreenBrighteningMinThreshold;
+    public HysteresisLevels getAmbientBrightnessHysteresis() {
+        return mAmbientBrightnessHysteresis;
     }
 
-    /**
-     * The minimum value for the screen brightness decrease to actually occur.
-     * @return float value in brightness scale of 0 - 1.
-     */
-    public float getScreenDarkeningMinThreshold() {
-        return mScreenDarkeningMinThreshold;
+    public HysteresisLevels getAmbientBrightnessIdleHysteresis() {
+        return mAmbientBrightnessIdleHysteresis;
     }
 
-    /**
-     * The minimum value for the screen brightness increase to actually occur while in idle screen
-     * brightness mode.
-     * @return float value in brightness scale of 0 - 1.
-     */
-    public float getScreenBrighteningMinThresholdIdle() {
-        return mScreenBrighteningMinThresholdIdle;
+    public HysteresisLevels getScreenBrightnessHysteresis() {
+        return mScreenBrightnessHysteresis;
     }
 
-    /**
-     * The minimum value for the screen brightness decrease to actually occur while in idle screen
-     * brightness mode.
-     * @return float value in brightness scale of 0 - 1.
-     */
-    public float getScreenDarkeningMinThresholdIdle() {
-        return mScreenDarkeningMinThresholdIdle;
-    }
-
-    /**
-     * The minimum value for the ambient lux increase for a screen brightness change to actually
-     * occur.
-     * @return float value in lux.
-     */
-    public float getAmbientLuxBrighteningMinThreshold() {
-        return mAmbientLuxBrighteningMinThreshold;
-    }
-
-    /**
-     * The minimum value for the ambient lux decrease for a screen brightness change to actually
-     * occur.
-     * @return float value in lux.
-     */
-    public float getAmbientLuxDarkeningMinThreshold() {
-        return mAmbientLuxDarkeningMinThreshold;
-    }
-
-    /**
-     * The minimum value for the ambient lux increase for a screen brightness change to actually
-     * occur while in idle screen brightness mode.
-     * @return float value in lux.
-     */
-    public float getAmbientLuxBrighteningMinThresholdIdle() {
-        return mAmbientLuxBrighteningMinThresholdIdle;
-    }
-
-    /**
-     * The minimum value for the ambient lux decrease for a screen brightness change to actually
-     * occur while in idle screen brightness mode.
-     * @return float value in lux.
-     */
-    public float getAmbientLuxDarkeningMinThresholdIdle() {
-        return mAmbientLuxDarkeningMinThresholdIdle;
-    }
-
-    /**
-     * The array that describes the range of screen brightness that each threshold percentage
-     * applies within.
-     *
-     * The (zero-based) index is calculated as follows
-     * value = current screen brightness value
-     * level = mScreenBrighteningLevels
-     *
-     * condition                       return
-     * value < level[0]                = 0.0f
-     * level[n] <= value < level[n+1]  = mScreenBrighteningPercentages[n]
-     * level[MAX] <= value             = mScreenBrighteningPercentages[MAX]
-     *
-     * @return the screen brightness levels between 0.0 and 1.0 for which each
-     * mScreenBrighteningPercentages applies
-     */
-    public float[] getScreenBrighteningLevels() {
-        return mScreenBrighteningLevels;
-    }
-
-    /**
-     * The array that describes the screen brightening threshold percentage change at each screen
-     * brightness level described in mScreenBrighteningLevels.
-     *
-     * @return the percentages between 0 and 100 of brightness increase required in order for the
-     * screen brightness to change
-     */
-    public float[] getScreenBrighteningPercentages() {
-        return mScreenBrighteningPercentages;
-    }
-
-    /**
-     * The array that describes the range of screen brightness that each threshold percentage
-     * applies within.
-     *
-     * The (zero-based) index is calculated as follows
-     * value = current screen brightness value
-     * level = mScreenDarkeningLevels
-     *
-     * condition                       return
-     * value < level[0]                = 0.0f
-     * level[n] <= value < level[n+1]  = mScreenDarkeningPercentages[n]
-     * level[MAX] <= value             = mScreenDarkeningPercentages[MAX]
-     *
-     * @return the screen brightness levels between 0.0 and 1.0 for which each
-     * mScreenDarkeningPercentages applies
-     */
-    public float[] getScreenDarkeningLevels() {
-        return mScreenDarkeningLevels;
-    }
-
-    /**
-     * The array that describes the screen darkening threshold percentage change at each screen
-     * brightness level described in mScreenDarkeningLevels.
-     *
-     * @return the percentages between 0 and 100 of brightness decrease required in order for the
-     * screen brightness to change
-     */
-    public float[] getScreenDarkeningPercentages() {
-        return mScreenDarkeningPercentages;
-    }
-
-    /**
-     * The array that describes the range of ambient brightness that each threshold
-     * percentage applies within.
-     *
-     * The (zero-based) index is calculated as follows
-     * value = current ambient brightness value
-     * level = mAmbientBrighteningLevels
-     *
-     * condition                       return
-     * value < level[0]                = 0.0f
-     * level[n] <= value < level[n+1]  = mAmbientBrighteningPercentages[n]
-     * level[MAX] <= value             = mAmbientBrighteningPercentages[MAX]
-     *
-     * @return the ambient brightness levels from 0 lux upwards for which each
-     * mAmbientBrighteningPercentages applies
-     */
-    public float[] getAmbientBrighteningLevels() {
-        return mAmbientBrighteningLevels;
-    }
-
-    /**
-     * The array that describes the ambient brightening threshold percentage change at each ambient
-     * brightness level described in mAmbientBrighteningLevels.
-     *
-     * @return the percentages between 0 and 100 of brightness increase required in order for the
-     * screen brightness to change
-     */
-    public float[] getAmbientBrighteningPercentages() {
-        return mAmbientBrighteningPercentages;
-    }
-
-    /**
-     * The array that describes the range of ambient brightness that each threshold percentage
-     * applies within.
-     *
-     * The (zero-based) index is calculated as follows
-     * value = current ambient brightness value
-     * level = mAmbientDarkeningLevels
-     *
-     * condition                       return
-     * value < level[0]                = 0.0f
-     * level[n] <= value < level[n+1]  = mAmbientDarkeningPercentages[n]
-     * level[MAX] <= value             = mAmbientDarkeningPercentages[MAX]
-     *
-     * @return the ambient brightness levels from 0 lux upwards for which each
-     * mAmbientDarkeningPercentages applies
-     */
-    public float[] getAmbientDarkeningLevels() {
-        return mAmbientDarkeningLevels;
-    }
-
-    /**
-     * The array that describes the ambient darkening threshold percentage change at each ambient
-     * brightness level described in mAmbientDarkeningLevels.
-     *
-     * @return the percentages between 0 and 100 of brightness decrease required in order for the
-     * screen brightness to change
-     */
-    public float[] getAmbientDarkeningPercentages() {
-        return mAmbientDarkeningPercentages;
-    }
-
-    /**
-     * The array that describes the range of screen brightness that each threshold percentage
-     * applies within whilst in idle screen brightness mode.
-     *
-     * The (zero-based) index is calculated as follows
-     * value = current screen brightness value
-     * level = mScreenBrighteningLevelsIdle
-     *
-     * condition                       return
-     * value < level[0]                = 0.0f
-     * level[n] <= value < level[n+1]  = mScreenBrighteningPercentagesIdle[n]
-     * level[MAX] <= value             = mScreenBrighteningPercentagesIdle[MAX]
-     *
-     * @return the screen brightness levels between 0.0 and 1.0 for which each
-     * mScreenBrighteningPercentagesIdle applies
-     */
-    public float[] getScreenBrighteningLevelsIdle() {
-        return mScreenBrighteningLevelsIdle;
-    }
-
-    /**
-     * The array that describes the screen brightening threshold percentage change at each screen
-     * brightness level described in mScreenBrighteningLevelsIdle.
-     *
-     * @return the percentages between 0 and 100 of brightness increase required in order for the
-     * screen brightness to change while in idle mode.
-     */
-    public float[] getScreenBrighteningPercentagesIdle() {
-        return mScreenBrighteningPercentagesIdle;
-    }
-
-    /**
-     * The array that describes the range of screen brightness that each threshold percentage
-     * applies within whilst in idle screen brightness mode.
-     *
-     * The (zero-based) index is calculated as follows
-     * value = current screen brightness value
-     * level = mScreenDarkeningLevelsIdle
-     *
-     * condition                       return
-     * value < level[0]                = 0.0f
-     * level[n] <= value < level[n+1]  = mScreenDarkeningPercentagesIdle[n]
-     * level[MAX] <= value             = mScreenDarkeningPercentagesIdle[MAX]
-     *
-     * @return the screen brightness levels between 0.0 and 1.0 for which each
-     * mScreenDarkeningPercentagesIdle applies
-     */
-    public float[] getScreenDarkeningLevelsIdle() {
-        return mScreenDarkeningLevelsIdle;
-    }
-
-    /**
-     * The array that describes the screen darkening threshold percentage change at each screen
-     * brightness level described in mScreenDarkeningLevelsIdle.
-     *
-     * @return the percentages between 0 and 100 of brightness decrease required in order for the
-     * screen brightness to change while in idle mode.
-     */
-    public float[] getScreenDarkeningPercentagesIdle() {
-        return mScreenDarkeningPercentagesIdle;
-    }
-
-    /**
-     * The array that describes the range of ambient brightness that each threshold percentage
-     * applies within whilst in idle screen brightness mode.
-     *
-     * The (zero-based) index is calculated as follows
-     * value = current ambient brightness value
-     * level = mAmbientBrighteningLevelsIdle
-     *
-     * condition                       return
-     * value < level[0]                = 0.0f
-     * level[n] <= value < level[n+1]  = mAmbientBrighteningPercentagesIdle[n]
-     * level[MAX] <= value             = mAmbientBrighteningPercentagesIdle[MAX]
-     *
-     * @return the ambient brightness levels from 0 lux upwards for which each
-     * mAmbientBrighteningPercentagesIdle applies
-     */
-    public float[] getAmbientBrighteningLevelsIdle() {
-        return mAmbientBrighteningLevelsIdle;
-    }
-
-    /**
-     * The array that describes the ambient brightness threshold percentage change whilst in
-     * idle screen brightness mode at each ambient brightness level described in
-     * mAmbientBrighteningLevelsIdle.
-     *
-     * @return the percentages between 0 and 100 of ambient brightness increase required in order
-     * for the screen brightness to change
-     */
-    public float[] getAmbientBrighteningPercentagesIdle() {
-        return mAmbientBrighteningPercentagesIdle;
-    }
-
-    /**
-     * The array that describes the range of ambient brightness that each threshold percentage
-     * applies within whilst in idle screen brightness mode.
-     *
-     * The (zero-based) index is calculated as follows
-     * value = current ambient brightness value
-     * level = mAmbientDarkeningLevelsIdle
-     *
-     * condition                       return
-     * value < level[0]                = 0.0f
-     * level[n] <= value < level[n+1]  = mAmbientDarkeningPercentagesIdle[n]
-     * level[MAX] <= value             = mAmbientDarkeningPercentagesIdle[MAX]
-     *
-     * @return the ambient brightness levels from 0 lux upwards for which each
-     * mAmbientDarkeningPercentagesIdle applies
-     */
-    public float[] getAmbientDarkeningLevelsIdle() {
-        return mAmbientDarkeningLevelsIdle;
-    }
-
-    /**
-     * The array that describes the ambient brightness threshold percentage change whilst in
-     * idle screen brightness mode at each ambient brightness level described in
-     * mAmbientDarkeningLevelsIdle.
-     *
-     * @return the percentages between 0 and 100 of ambient brightness decrease required in order
-     * for the screen brightness to change
-     */
-    public float[] getAmbientDarkeningPercentagesIdle() {
-        return mAmbientDarkeningPercentagesIdle;
+    public HysteresisLevels getScreenBrightnessIdleHysteresis() {
+        return mScreenBrightnessIdleHysteresis;
     }
 
     public SensorData getAmbientLightSensor() {
@@ -1985,49 +1650,13 @@
                 + "mAmbientHorizonLong=" + mAmbientHorizonLong
                 + ", mAmbientHorizonShort=" + mAmbientHorizonShort
                 + "\n"
-                + "mScreenDarkeningMinThreshold=" + mScreenDarkeningMinThreshold
-                + ", mScreenDarkeningMinThresholdIdle=" + mScreenDarkeningMinThresholdIdle
-                + ", mScreenBrighteningMinThreshold=" + mScreenBrighteningMinThreshold
-                + ", mScreenBrighteningMinThresholdIdle=" + mScreenBrighteningMinThresholdIdle
-                + ", mAmbientLuxDarkeningMinThreshold=" + mAmbientLuxDarkeningMinThreshold
-                + ", mAmbientLuxDarkeningMinThresholdIdle=" + mAmbientLuxDarkeningMinThresholdIdle
-                + ", mAmbientLuxBrighteningMinThreshold=" + mAmbientLuxBrighteningMinThreshold
-                + ", mAmbientLuxBrighteningMinThresholdIdle="
-                + mAmbientLuxBrighteningMinThresholdIdle
+                + "mAmbientBrightnessHysteresis=" + mAmbientBrightnessHysteresis
                 + "\n"
-                + "mScreenBrighteningLevels=" + Arrays.toString(
-                mScreenBrighteningLevels)
-                + ", mScreenBrighteningPercentages=" + Arrays.toString(
-                mScreenBrighteningPercentages)
-                + ", mScreenDarkeningLevels=" + Arrays.toString(
-                mScreenDarkeningLevels)
-                + ", mScreenDarkeningPercentages=" + Arrays.toString(
-                mScreenDarkeningPercentages)
-                + ", mAmbientBrighteningLevels=" + Arrays.toString(
-                mAmbientBrighteningLevels)
-                + ", mAmbientBrighteningPercentages=" + Arrays.toString(
-                mAmbientBrighteningPercentages)
-                + ", mAmbientDarkeningLevels=" + Arrays.toString(
-                mAmbientDarkeningLevels)
-                + ", mAmbientDarkeningPercentages=" + Arrays.toString(
-                mAmbientDarkeningPercentages)
+                + "mAmbientIdleHysteresis=" + mAmbientBrightnessIdleHysteresis
                 + "\n"
-                + "mAmbientBrighteningLevelsIdle=" + Arrays.toString(
-                mAmbientBrighteningLevelsIdle)
-                + ", mAmbientBrighteningPercentagesIdle=" + Arrays.toString(
-                mAmbientBrighteningPercentagesIdle)
-                + ", mAmbientDarkeningLevelsIdle=" + Arrays.toString(
-                mAmbientDarkeningLevelsIdle)
-                + ", mAmbientDarkeningPercentagesIdle=" + Arrays.toString(
-                mAmbientDarkeningPercentagesIdle)
-                + ", mScreenBrighteningLevelsIdle=" + Arrays.toString(
-                mScreenBrighteningLevelsIdle)
-                + ", mScreenBrighteningPercentagesIdle=" + Arrays.toString(
-                mScreenBrighteningPercentagesIdle)
-                + ", mScreenDarkeningLevelsIdle=" + Arrays.toString(
-                mScreenDarkeningLevelsIdle)
-                + ", mScreenDarkeningPercentagesIdle=" + Arrays.toString(
-                mScreenDarkeningPercentagesIdle)
+                + "mScreenBrightnessHysteresis=" + mScreenBrightnessHysteresis
+                + "\n"
+                + "mScreenBrightnessIdleHysteresis=" + mScreenBrightnessIdleHysteresis
                 + "\n"
                 + "mAmbientLightSensor=" + mAmbientLightSensor
                 + ", mScreenOffBrightnessSensor=" + mScreenOffBrightnessSensor
@@ -2139,7 +1768,7 @@
                 mAmbientLightSensor = SensorData.loadAmbientLightSensorConfig(config,
                         mContext.getResources());
                 mScreenOffBrightnessSensor = SensorData.loadScreenOffBrightnessSensorConfig(config);
-                mProximitySensor = SensorData.loadProxSensorConfig(config);
+                mProximitySensor = SensorData.loadProxSensorConfig(mFlags, config);
                 mTempSensor = SensorData.loadTempSensorConfig(mFlags, config);
                 loadAmbientHorizonFromDdc(config);
                 loadBrightnessChangeThresholds(config);
@@ -3137,281 +2766,15 @@
     }
 
     private void loadBrightnessChangeThresholds(DisplayConfiguration config) {
-        loadDisplayBrightnessThresholds(config);
-        loadAmbientBrightnessThresholds(config);
-        loadDisplayBrightnessThresholdsIdle(config);
-        loadAmbientBrightnessThresholdsIdle(config);
-    }
-
-    private void loadDisplayBrightnessThresholds(DisplayConfiguration config) {
-        BrightnessThresholds brighteningScreen = null;
-        BrightnessThresholds darkeningScreen = null;
-        if (config != null && config.getDisplayBrightnessChangeThresholds() != null) {
-            brighteningScreen =
-                    config.getDisplayBrightnessChangeThresholds().getBrighteningThresholds();
-            darkeningScreen =
-                    config.getDisplayBrightnessChangeThresholds().getDarkeningThresholds();
-
-        }
-
-        // Screen bright/darkening threshold levels for active mode
-        Pair<float[], float[]> screenBrighteningPair = getBrightnessLevelAndPercentage(
-                brighteningScreen,
-                com.android.internal.R.array.config_screenThresholdLevels,
-                com.android.internal.R.array.config_screenBrighteningThresholds,
-                DEFAULT_SCREEN_THRESHOLD_LEVELS, DEFAULT_SCREEN_BRIGHTENING_THRESHOLDS,
-                /* potentialOldBrightnessScale= */ true);
-
-        mScreenBrighteningLevels = screenBrighteningPair.first;
-        mScreenBrighteningPercentages = screenBrighteningPair.second;
-
-        Pair<float[], float[]> screenDarkeningPair = getBrightnessLevelAndPercentage(
-                darkeningScreen,
-                com.android.internal.R.array.config_screenThresholdLevels,
-                com.android.internal.R.array.config_screenDarkeningThresholds,
-                DEFAULT_SCREEN_THRESHOLD_LEVELS, DEFAULT_SCREEN_DARKENING_THRESHOLDS,
-                /* potentialOldBrightnessScale= */ true);
-        mScreenDarkeningLevels = screenDarkeningPair.first;
-        mScreenDarkeningPercentages = screenDarkeningPair.second;
-
-        // Screen bright/darkening threshold minimums for active mode
-        if (brighteningScreen != null && brighteningScreen.getMinimum() != null) {
-            mScreenBrighteningMinThreshold = brighteningScreen.getMinimum().floatValue();
-        }
-        if (darkeningScreen != null && darkeningScreen.getMinimum() != null) {
-            mScreenDarkeningMinThreshold = darkeningScreen.getMinimum().floatValue();
-        }
-    }
-
-    private void loadAmbientBrightnessThresholds(DisplayConfiguration config) {
-        // Ambient Brightness Threshold Levels
-        BrightnessThresholds brighteningAmbientLux = null;
-        BrightnessThresholds darkeningAmbientLux = null;
-        if (config != null && config.getAmbientBrightnessChangeThresholds() != null) {
-            brighteningAmbientLux =
-                    config.getAmbientBrightnessChangeThresholds().getBrighteningThresholds();
-            darkeningAmbientLux =
-                    config.getAmbientBrightnessChangeThresholds().getDarkeningThresholds();
-        }
-
-        // Ambient bright/darkening threshold levels for active mode
-        Pair<float[], float[]> ambientBrighteningPair = getBrightnessLevelAndPercentage(
-                brighteningAmbientLux,
-                com.android.internal.R.array.config_ambientThresholdLevels,
-                com.android.internal.R.array.config_ambientBrighteningThresholds,
-                DEFAULT_AMBIENT_THRESHOLD_LEVELS, DEFAULT_AMBIENT_BRIGHTENING_THRESHOLDS);
-        mAmbientBrighteningLevels = ambientBrighteningPair.first;
-        mAmbientBrighteningPercentages = ambientBrighteningPair.second;
-
-        Pair<float[], float[]> ambientDarkeningPair = getBrightnessLevelAndPercentage(
-                darkeningAmbientLux,
-                com.android.internal.R.array.config_ambientThresholdLevels,
-                com.android.internal.R.array.config_ambientDarkeningThresholds,
-                DEFAULT_AMBIENT_THRESHOLD_LEVELS, DEFAULT_AMBIENT_DARKENING_THRESHOLDS);
-        mAmbientDarkeningLevels = ambientDarkeningPair.first;
-        mAmbientDarkeningPercentages = ambientDarkeningPair.second;
-
-        // Ambient bright/darkening threshold minimums for active/idle mode
-        if (brighteningAmbientLux != null && brighteningAmbientLux.getMinimum() != null) {
-            mAmbientLuxBrighteningMinThreshold =
-                    brighteningAmbientLux.getMinimum().floatValue();
-        }
-
-        if (darkeningAmbientLux != null && darkeningAmbientLux.getMinimum() != null) {
-            mAmbientLuxDarkeningMinThreshold = darkeningAmbientLux.getMinimum().floatValue();
-        }
-    }
-
-    private void loadDisplayBrightnessThresholdsIdle(DisplayConfiguration config) {
-        BrightnessThresholds brighteningScreenIdle = null;
-        BrightnessThresholds darkeningScreenIdle = null;
-        if (config != null && config.getDisplayBrightnessChangeThresholdsIdle() != null) {
-            brighteningScreenIdle =
-                    config.getDisplayBrightnessChangeThresholdsIdle().getBrighteningThresholds();
-            darkeningScreenIdle =
-                    config.getDisplayBrightnessChangeThresholdsIdle().getDarkeningThresholds();
-        }
-
-        Pair<float[], float[]> screenBrighteningPair = getBrightnessLevelAndPercentage(
-                brighteningScreenIdle,
-                com.android.internal.R.array.config_screenThresholdLevels,
-                com.android.internal.R.array.config_screenBrighteningThresholds,
-                DEFAULT_SCREEN_THRESHOLD_LEVELS, DEFAULT_SCREEN_BRIGHTENING_THRESHOLDS,
-                /* potentialOldBrightnessScale= */ true);
-        mScreenBrighteningLevelsIdle = screenBrighteningPair.first;
-        mScreenBrighteningPercentagesIdle = screenBrighteningPair.second;
-
-        Pair<float[], float[]> screenDarkeningPair = getBrightnessLevelAndPercentage(
-                darkeningScreenIdle,
-                com.android.internal.R.array.config_screenThresholdLevels,
-                com.android.internal.R.array.config_screenDarkeningThresholds,
-                DEFAULT_SCREEN_THRESHOLD_LEVELS, DEFAULT_SCREEN_DARKENING_THRESHOLDS,
-                /* potentialOldBrightnessScale= */ true);
-        mScreenDarkeningLevelsIdle = screenDarkeningPair.first;
-        mScreenDarkeningPercentagesIdle = screenDarkeningPair.second;
-
-        if (brighteningScreenIdle != null
-                && brighteningScreenIdle.getMinimum() != null) {
-            mScreenBrighteningMinThresholdIdle =
-                    brighteningScreenIdle.getMinimum().floatValue();
-        }
-        if (darkeningScreenIdle != null && darkeningScreenIdle.getMinimum() != null) {
-            mScreenDarkeningMinThresholdIdle =
-                    darkeningScreenIdle.getMinimum().floatValue();
-        }
-    }
-
-    private void loadAmbientBrightnessThresholdsIdle(DisplayConfiguration config) {
-        BrightnessThresholds brighteningAmbientLuxIdle = null;
-        BrightnessThresholds darkeningAmbientLuxIdle = null;
-        if (config != null && config.getAmbientBrightnessChangeThresholdsIdle() != null) {
-            brighteningAmbientLuxIdle =
-                    config.getAmbientBrightnessChangeThresholdsIdle().getBrighteningThresholds();
-            darkeningAmbientLuxIdle =
-                    config.getAmbientBrightnessChangeThresholdsIdle().getDarkeningThresholds();
-        }
-
-        Pair<float[], float[]> ambientBrighteningPair = getBrightnessLevelAndPercentage(
-                brighteningAmbientLuxIdle,
-                com.android.internal.R.array.config_ambientThresholdLevels,
-                com.android.internal.R.array.config_ambientBrighteningThresholds,
-                DEFAULT_AMBIENT_THRESHOLD_LEVELS, DEFAULT_AMBIENT_BRIGHTENING_THRESHOLDS);
-        mAmbientBrighteningLevelsIdle = ambientBrighteningPair.first;
-        mAmbientBrighteningPercentagesIdle = ambientBrighteningPair.second;
-
-        Pair<float[], float[]> ambientDarkeningPair = getBrightnessLevelAndPercentage(
-                darkeningAmbientLuxIdle,
-                com.android.internal.R.array.config_ambientThresholdLevels,
-                com.android.internal.R.array.config_ambientDarkeningThresholds,
-                DEFAULT_AMBIENT_THRESHOLD_LEVELS, DEFAULT_AMBIENT_DARKENING_THRESHOLDS);
-        mAmbientDarkeningLevelsIdle = ambientDarkeningPair.first;
-        mAmbientDarkeningPercentagesIdle = ambientDarkeningPair.second;
-
-        if (brighteningAmbientLuxIdle != null
-                && brighteningAmbientLuxIdle.getMinimum() != null) {
-            mAmbientLuxBrighteningMinThresholdIdle =
-                    brighteningAmbientLuxIdle.getMinimum().floatValue();
-        }
-
-        if (darkeningAmbientLuxIdle != null && darkeningAmbientLuxIdle.getMinimum() != null) {
-            mAmbientLuxDarkeningMinThresholdIdle =
-                    darkeningAmbientLuxIdle.getMinimum().floatValue();
-        }
-    }
-
-    private Pair<float[], float[]> getBrightnessLevelAndPercentage(BrightnessThresholds thresholds,
-            int configFallbackThreshold, int configFallbackPercentage, float[] defaultLevels,
-            float[] defaultPercentage) {
-        return getBrightnessLevelAndPercentage(thresholds, configFallbackThreshold,
-                configFallbackPercentage, defaultLevels, defaultPercentage, false);
-    }
-
-    // Returns two float arrays, one of the brightness levels and one of the corresponding threshold
-    // percentages for brightness levels at or above the lux value.
-    // Historically, config.xml would have an array for brightness levels that was 1 shorter than
-    // the levels array. Now we prepend a 0 to this array so they can be treated the same in the
-    // rest of the framework. Values were also defined in different units (permille vs percent).
-    private Pair<float[], float[]> getBrightnessLevelAndPercentage(BrightnessThresholds thresholds,
-            int configFallbackThreshold, int configFallbackPermille,
-            float[] defaultLevels, float[] defaultPercentage,
-            boolean potentialOldBrightnessScale) {
-        if (thresholds != null
-                && thresholds.getBrightnessThresholdPoints() != null
-                && thresholds.getBrightnessThresholdPoints()
-                        .getBrightnessThresholdPoint().size() != 0) {
-
-            // The level and percentages arrays are equal length in the ddc (new system)
-            List<ThresholdPoint> points =
-                    thresholds.getBrightnessThresholdPoints().getBrightnessThresholdPoint();
-            final int size = points.size();
-
-            float[] thresholdLevels = new float[size];
-            float[] thresholdPercentages = new float[size];
-
-            int i = 0;
-            for (ThresholdPoint point : points) {
-                thresholdLevels[i] = point.getThreshold().floatValue();
-                thresholdPercentages[i] = point.getPercentage().floatValue();
-                i++;
-            }
-            return new Pair<>(thresholdLevels, thresholdPercentages);
-        } else {
-            // The level and percentages arrays are unequal length in config.xml (old system)
-            // We prefix the array with a 0 value to ensure they can be handled consistently
-            // with the new system.
-
-            // Load levels array
-            int[] configThresholdArray = mContext.getResources().getIntArray(
-                    configFallbackThreshold);
-            int configThresholdsSize;
-            if (configThresholdArray == null || configThresholdArray.length == 0) {
-                configThresholdsSize = 1;
-            } else {
-                configThresholdsSize = configThresholdArray.length + 1;
-            }
-
-
-            // Load percentage array
-            int[] configPermille = mContext.getResources().getIntArray(
-                    configFallbackPermille);
-
-            // Ensure lengths match up
-            boolean emptyArray = configPermille == null || configPermille.length == 0;
-            if (emptyArray && configThresholdsSize == 1) {
-                return new Pair<>(defaultLevels, defaultPercentage);
-            }
-            if (emptyArray || configPermille.length != configThresholdsSize) {
-                throw new IllegalArgumentException(
-                        "Brightness threshold arrays do not align in length");
-            }
-
-            // Calculate levels array
-            float[] configThresholdWithZeroPrefixed = new float[configThresholdsSize];
-            // Start at 1, so that 0 index value is 0.0f (default)
-            for (int i = 1; i < configThresholdsSize; i++) {
-                configThresholdWithZeroPrefixed[i] = (float) configThresholdArray[i - 1];
-            }
-            if (potentialOldBrightnessScale) {
-                configThresholdWithZeroPrefixed =
-                        constraintInRangeIfNeeded(configThresholdWithZeroPrefixed);
-            }
-
-            // Calculate percentages array
-            float[] configPercentage = new float[configThresholdsSize];
-            for (int i = 0; i < configPermille.length; i++) {
-                configPercentage[i] = configPermille[i] / 10.0f;
-            }            return new Pair<>(configThresholdWithZeroPrefixed, configPercentage);
-        }
-    }
-
-    /**
-     * This check is due to historical reasons, where screen thresholdLevels used to be
-     * integer values in the range of [0-255], but then was changed to be float values from [0,1].
-     * To accommodate both the possibilities, we first check if all the thresholdLevels are in
-     * [0,1], and if not, we divide all the levels with 255 to bring them down to the same scale.
-     */
-    private float[] constraintInRangeIfNeeded(float[] thresholdLevels) {
-        if (isAllInRange(thresholdLevels, /* minValueInclusive= */ 0.0f,
-                /* maxValueInclusive= */ 1.0f)) {
-            return thresholdLevels;
-        }
-
-        Slog.w(TAG, "Detected screen thresholdLevels on a deprecated brightness scale");
-        float[] thresholdLevelsScaled = new float[thresholdLevels.length];
-        for (int index = 0; thresholdLevels.length > index; ++index) {
-            thresholdLevelsScaled[index] = thresholdLevels[index] / 255.0f;
-        }
-        return thresholdLevelsScaled;
-    }
-
-    private boolean isAllInRange(float[] configArray, float minValueInclusive,
-            float maxValueInclusive) {
-        for (float v : configArray) {
-            if (v < minValueInclusive || v > maxValueInclusive) {
-                return false;
-            }
-        }
-        return true;
+        Resources res = mContext.getResources();
+        mScreenBrightnessHysteresis =
+                HysteresisLevels.loadDisplayBrightnessConfig(config, res);
+        mScreenBrightnessIdleHysteresis =
+                HysteresisLevels.loadDisplayBrightnessIdleConfig(config, res);
+        mAmbientBrightnessHysteresis =
+                HysteresisLevels.loadAmbientBrightnessConfig(config, res);
+        mAmbientBrightnessIdleHysteresis =
+                HysteresisLevels.loadAmbientBrightnessIdleConfig(config, res);
     }
 
     private boolean thermalStatusIsValid(ThermalStatus value) {
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 434985e..31092f2 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -150,6 +150,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.display.BrightnessSynchronizer;
+import com.android.internal.foldables.FoldGracePeriodProvider;
 import com.android.internal.foldables.FoldLockSettingAvailabilityProvider;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.ArrayUtils;
@@ -596,7 +597,7 @@
         mUiHandler = UiThread.getHandler();
         mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore);
         mLogicalDisplayMapper = new LogicalDisplayMapper(mContext,
-                foldSettingProvider,
+                foldSettingProvider, new FoldGracePeriodProvider(),
                 mDisplayDeviceRepo, new LogicalDisplayListener(), mSyncRoot, mHandler, mFlags);
         mDisplayModeDirector = new DisplayModeDirector(context, mHandler, mFlags);
         mBrightnessSynchronizer = new BrightnessSynchronizer(mContext,
@@ -756,6 +757,7 @@
             mContext.getSystemService(DeviceStateManager.class).registerCallback(
                     new HandlerExecutor(mHandler), new DeviceStateListener());
 
+            mLogicalDisplayMapper.onWindowManagerReady();
             scheduleTraversalLocked(false);
         }
     }
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index b21a89a..404c3ad 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -86,6 +86,7 @@
 import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy;
 import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
 import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
+import com.android.server.display.config.HysteresisLevels;
 import com.android.server.display.feature.DisplayManagerFlags;
 import com.android.server.display.layout.Layout;
 import com.android.server.display.state.DisplayStateController;
@@ -1050,76 +1051,20 @@
 
         if (defaultModeBrightnessMapper != null) {
             // Ambient Lux - Active Mode Brightness Thresholds
-            float[] ambientBrighteningThresholds =
-                    mDisplayDeviceConfig.getAmbientBrighteningPercentages();
-            float[] ambientDarkeningThresholds =
-                    mDisplayDeviceConfig.getAmbientDarkeningPercentages();
-            float[] ambientBrighteningLevels =
-                    mDisplayDeviceConfig.getAmbientBrighteningLevels();
-            float[] ambientDarkeningLevels =
-                    mDisplayDeviceConfig.getAmbientDarkeningLevels();
-            float ambientDarkeningMinThreshold =
-                    mDisplayDeviceConfig.getAmbientLuxDarkeningMinThreshold();
-            float ambientBrighteningMinThreshold =
-                    mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold();
-            HysteresisLevels ambientBrightnessThresholds = mInjector.getHysteresisLevels(
-                    ambientBrighteningThresholds, ambientDarkeningThresholds,
-                    ambientBrighteningLevels, ambientDarkeningLevels, ambientDarkeningMinThreshold,
-                    ambientBrighteningMinThreshold);
+            HysteresisLevels ambientBrightnessThresholds =
+                    mDisplayDeviceConfig.getAmbientBrightnessHysteresis();
 
             // Display - Active Mode Brightness Thresholds
-            float[] screenBrighteningThresholds =
-                    mDisplayDeviceConfig.getScreenBrighteningPercentages();
-            float[] screenDarkeningThresholds =
-                    mDisplayDeviceConfig.getScreenDarkeningPercentages();
-            float[] screenBrighteningLevels =
-                    mDisplayDeviceConfig.getScreenBrighteningLevels();
-            float[] screenDarkeningLevels =
-                    mDisplayDeviceConfig.getScreenDarkeningLevels();
-            float screenDarkeningMinThreshold =
-                    mDisplayDeviceConfig.getScreenDarkeningMinThreshold();
-            float screenBrighteningMinThreshold =
-                    mDisplayDeviceConfig.getScreenBrighteningMinThreshold();
-            HysteresisLevels screenBrightnessThresholds = mInjector.getHysteresisLevels(
-                    screenBrighteningThresholds, screenDarkeningThresholds,
-                    screenBrighteningLevels, screenDarkeningLevels, screenDarkeningMinThreshold,
-                    screenBrighteningMinThreshold, true);
+            HysteresisLevels screenBrightnessThresholds =
+                    mDisplayDeviceConfig.getScreenBrightnessHysteresis();
 
             // Ambient Lux - Idle Screen Brightness Thresholds
-            float ambientDarkeningMinThresholdIdle =
-                    mDisplayDeviceConfig.getAmbientLuxDarkeningMinThresholdIdle();
-            float ambientBrighteningMinThresholdIdle =
-                    mDisplayDeviceConfig.getAmbientLuxBrighteningMinThresholdIdle();
-            float[] ambientBrighteningThresholdsIdle =
-                    mDisplayDeviceConfig.getAmbientBrighteningPercentagesIdle();
-            float[] ambientDarkeningThresholdsIdle =
-                    mDisplayDeviceConfig.getAmbientDarkeningPercentagesIdle();
-            float[] ambientBrighteningLevelsIdle =
-                    mDisplayDeviceConfig.getAmbientBrighteningLevelsIdle();
-            float[] ambientDarkeningLevelsIdle =
-                    mDisplayDeviceConfig.getAmbientDarkeningLevelsIdle();
-            HysteresisLevels ambientBrightnessThresholdsIdle = mInjector.getHysteresisLevels(
-                    ambientBrighteningThresholdsIdle, ambientDarkeningThresholdsIdle,
-                    ambientBrighteningLevelsIdle, ambientDarkeningLevelsIdle,
-                    ambientDarkeningMinThresholdIdle, ambientBrighteningMinThresholdIdle);
+            HysteresisLevels ambientBrightnessThresholdsIdle =
+                    mDisplayDeviceConfig.getAmbientBrightnessIdleHysteresis();
 
             // Display - Idle Screen Brightness Thresholds
-            float screenDarkeningMinThresholdIdle =
-                    mDisplayDeviceConfig.getScreenDarkeningMinThresholdIdle();
-            float screenBrighteningMinThresholdIdle =
-                    mDisplayDeviceConfig.getScreenBrighteningMinThresholdIdle();
-            float[] screenBrighteningThresholdsIdle =
-                    mDisplayDeviceConfig.getScreenBrighteningPercentagesIdle();
-            float[] screenDarkeningThresholdsIdle =
-                    mDisplayDeviceConfig.getScreenDarkeningPercentagesIdle();
-            float[] screenBrighteningLevelsIdle =
-                    mDisplayDeviceConfig.getScreenBrighteningLevelsIdle();
-            float[] screenDarkeningLevelsIdle =
-                    mDisplayDeviceConfig.getScreenDarkeningLevelsIdle();
-            HysteresisLevels screenBrightnessThresholdsIdle = mInjector.getHysteresisLevels(
-                    screenBrighteningThresholdsIdle, screenDarkeningThresholdsIdle,
-                    screenBrighteningLevelsIdle, screenDarkeningLevelsIdle,
-                    screenDarkeningMinThresholdIdle, screenBrighteningMinThresholdIdle);
+            HysteresisLevels screenBrightnessThresholdsIdle =
+                    mDisplayDeviceConfig.getScreenBrightnessIdleHysteresis();
 
             long brighteningLightDebounce = mDisplayDeviceConfig
                     .getAutoBrightnessBrighteningLightDebounce();
@@ -3208,25 +3153,6 @@
                     AUTO_BRIGHTNESS_MODE_DEFAULT, displayWhiteBalanceController);
         }
 
-        HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
-                float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
-                float[] darkeningThresholdLevels, float minDarkeningThreshold,
-                float minBrighteningThreshold) {
-            return new HysteresisLevels(brighteningThresholdsPercentages,
-                    darkeningThresholdsPercentages, brighteningThresholdLevels,
-                    darkeningThresholdLevels, minDarkeningThreshold, minBrighteningThreshold);
-        }
-
-        HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
-                float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
-                float[] darkeningThresholdLevels, float minDarkeningThreshold,
-                float minBrighteningThreshold, boolean potentialOldBrightnessRange) {
-            return new HysteresisLevels(brighteningThresholdsPercentages,
-                    darkeningThresholdsPercentages, brighteningThresholdLevels,
-                    darkeningThresholdLevels, minDarkeningThreshold, minBrighteningThreshold,
-                    potentialOldBrightnessRange);
-        }
-
         ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController(
                 SensorManager sensorManager,
                 Sensor lightSensor,
diff --git a/services/core/java/com/android/server/display/HysteresisLevels.java b/services/core/java/com/android/server/display/HysteresisLevels.java
deleted file mode 100644
index 0521b8a..0000000
--- a/services/core/java/com/android/server/display/HysteresisLevels.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.display;
-
-import android.util.Slog;
-
-import com.android.server.display.utils.DebugUtils;
-
-import java.io.PrintWriter;
-import java.util.Arrays;
-
-/**
- * A helper class for handling access to illuminance hysteresis level values.
- */
-public class HysteresisLevels {
-    private static final String TAG = "HysteresisLevels";
-
-    // To enable these logs, run:
-    // 'adb shell setprop persist.log.tag.HysteresisLevels DEBUG && adb reboot'
-    private static final boolean DEBUG = DebugUtils.isDebuggable(TAG);
-
-    private final float[] mBrighteningThresholdsPercentages;
-    private final float[] mDarkeningThresholdsPercentages;
-    private final float[] mBrighteningThresholdLevels;
-    private final float[] mDarkeningThresholdLevels;
-    private final float mMinDarkening;
-    private final float mMinBrightening;
-
-    /**
-     * Creates a {@code HysteresisLevels} object with the given equal-length
-     * float arrays.
-     * @param brighteningThresholdsPercentages 0-100 of thresholds
-     * @param darkeningThresholdsPercentages 0-100 of thresholds
-     * @param brighteningThresholdLevels float array of brightness values in the relevant units
-     * @param minBrighteningThreshold the minimum value for which the brightening value needs to
-     *                                return.
-     * @param minDarkeningThreshold the minimum value for which the darkening value needs to return.
-     * @param potentialOldBrightnessRange whether or not the values used could be from the old
-     *                                    screen brightness range ie, between 1-255.
-    */
-    HysteresisLevels(float[] brighteningThresholdsPercentages,
-            float[] darkeningThresholdsPercentages,
-            float[] brighteningThresholdLevels, float[] darkeningThresholdLevels,
-            float minDarkeningThreshold, float minBrighteningThreshold,
-            boolean potentialOldBrightnessRange) {
-        if (brighteningThresholdsPercentages.length != brighteningThresholdLevels.length
-                || darkeningThresholdsPercentages.length != darkeningThresholdLevels.length) {
-            throw new IllegalArgumentException("Mismatch between hysteresis array lengths.");
-        }
-        mBrighteningThresholdsPercentages =
-                setArrayFormat(brighteningThresholdsPercentages, 100.0f);
-        mDarkeningThresholdsPercentages =
-                setArrayFormat(darkeningThresholdsPercentages, 100.0f);
-        mBrighteningThresholdLevels = setArrayFormat(brighteningThresholdLevels, 1.0f);
-        mDarkeningThresholdLevels = setArrayFormat(darkeningThresholdLevels, 1.0f);
-        mMinDarkening = minDarkeningThreshold;
-        mMinBrightening = minBrighteningThreshold;
-    }
-
-    HysteresisLevels(float[] brighteningThresholdsPercentages,
-            float[] darkeningThresholdsPercentages,
-            float[] brighteningThresholdLevels, float[] darkeningThresholdLevels,
-            float minDarkeningThreshold, float minBrighteningThreshold) {
-        this(brighteningThresholdsPercentages, darkeningThresholdsPercentages,
-                brighteningThresholdLevels, darkeningThresholdLevels, minDarkeningThreshold,
-                minBrighteningThreshold, false);
-    }
-
-    /**
-     * Return the brightening hysteresis threshold for the given value level.
-     */
-    public float getBrighteningThreshold(float value) {
-        final float brightConstant = getReferenceLevel(value,
-                mBrighteningThresholdLevels, mBrighteningThresholdsPercentages);
-
-        float brightThreshold = value * (1.0f + brightConstant);
-        if (DEBUG) {
-            Slog.d(TAG, "bright hysteresis constant=" + brightConstant + ", threshold="
-                    + brightThreshold + ", value=" + value);
-        }
-
-        brightThreshold = Math.max(brightThreshold, value + mMinBrightening);
-        return brightThreshold;
-    }
-
-    /**
-     * Return the darkening hysteresis threshold for the given value level.
-     */
-    public float getDarkeningThreshold(float value) {
-        final float darkConstant = getReferenceLevel(value,
-                mDarkeningThresholdLevels, mDarkeningThresholdsPercentages);
-        float darkThreshold = value * (1.0f - darkConstant);
-        if (DEBUG) {
-            Slog.d(TAG, "dark hysteresis constant=: " + darkConstant + ", threshold="
-                    + darkThreshold + ", value=" + value);
-        }
-        darkThreshold = Math.min(darkThreshold, value - mMinDarkening);
-        return Math.max(darkThreshold, 0.0f);
-    }
-
-    /**
-     * Return the hysteresis constant for the closest threshold value from the given array.
-     */
-    private float getReferenceLevel(float value, float[] thresholdLevels,
-            float[] thresholdPercentages) {
-        if (thresholdLevels == null || thresholdLevels.length == 0 || value < thresholdLevels[0]) {
-            return 0.0f;
-        }
-        int index = 0;
-        while (index < thresholdLevels.length - 1 && value >= thresholdLevels[index + 1]) {
-            index++;
-        }
-        return thresholdPercentages[index];
-    }
-
-    /**
-     * Return a float array where each i-th element equals {@code configArray[i]/divideFactor}.
-     */
-    private float[] setArrayFormat(float[] configArray, float divideFactor) {
-        float[] levelArray = new float[configArray.length];
-        for (int index = 0; levelArray.length > index; ++index) {
-            levelArray[index] = configArray[index] / divideFactor;
-        }
-        return levelArray;
-    }
-
-    void dump(PrintWriter pw) {
-        pw.println("HysteresisLevels");
-        pw.println("  mBrighteningThresholdLevels=" + Arrays.toString(mBrighteningThresholdLevels));
-        pw.println("  mBrighteningThresholdsPercentages="
-                + Arrays.toString(mBrighteningThresholdsPercentages));
-        pw.println("  mMinBrightening=" + mMinBrightening);
-        pw.println("  mDarkeningThresholdLevels=" + Arrays.toString(mDarkeningThresholdLevels));
-        pw.println("  mDarkeningThresholdsPercentages="
-                + Arrays.toString(mDarkeningThresholdsPercentages));
-        pw.println("  mMinDarkening=" + mMinDarkening);
-    }
-}
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 22e4bc5..189e366 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -482,7 +482,8 @@
             int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right;
             int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom;
 
-            if (mIsAnisotropyCorrectionEnabled && deviceInfo.xDpi > 0 && deviceInfo.yDpi > 0) {
+            if (mIsAnisotropyCorrectionEnabled && deviceInfo.type == Display.TYPE_EXTERNAL
+                        && deviceInfo.xDpi > 0 && deviceInfo.yDpi > 0) {
                 if (deviceInfo.xDpi > deviceInfo.yDpi * DisplayDevice.MAX_ANISOTROPY) {
                     maskedHeight = (int) (maskedHeight * deviceInfo.xDpi / deviceInfo.yDpi + 0.5);
                 } else if (deviceInfo.xDpi * DisplayDevice.MAX_ANISOTROPY < deviceInfo.yDpi) {
@@ -711,8 +712,8 @@
         var displayLogicalWidth = displayInfo.logicalWidth;
         var displayLogicalHeight = displayInfo.logicalHeight;
 
-        if (mIsAnisotropyCorrectionEnabled && displayDeviceInfo.xDpi > 0
-                    && displayDeviceInfo.yDpi > 0) {
+        if (mIsAnisotropyCorrectionEnabled && displayDeviceInfo.type == Display.TYPE_EXTERNAL
+                    && displayDeviceInfo.xDpi > 0 && displayDeviceInfo.yDpi > 0) {
             if (displayDeviceInfo.xDpi > displayDeviceInfo.yDpi * DisplayDevice.MAX_ANISOTROPY) {
                 var scalingFactor = displayDeviceInfo.yDpi / displayDeviceInfo.xDpi;
                 if (rotated) {
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index f727eac..bca53cf 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -40,10 +40,13 @@
 import android.view.DisplayInfo;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.foldables.FoldGracePeriodProvider;
+import com.android.server.LocalServices;
 import com.android.server.display.feature.DisplayManagerFlags;
 import com.android.server.display.layout.DisplayIdProducer;
 import com.android.server.display.layout.Layout;
 import com.android.server.display.utils.DebugUtils;
+import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.utils.FoldSettingProvider;
 
 import java.io.PrintWriter;
@@ -120,7 +123,7 @@
     /**
      * Sleep the device when transitioning into these device state.
      */
-    private final SparseBooleanArray mDeviceStatesOnWhichToSleep;
+    private final SparseBooleanArray mDeviceStatesOnWhichToSelectiveSleep;
 
     /**
      * Map of all logical displays indexed by logical display id.
@@ -153,6 +156,7 @@
     private final DisplayManagerService.SyncRoot mSyncRoot;
     private final LogicalDisplayMapperHandler mHandler;
     private final FoldSettingProvider mFoldSettingProvider;
+    private final FoldGracePeriodProvider mFoldGracePeriodProvider;
     private final PowerManager mPowerManager;
 
     /**
@@ -187,6 +191,7 @@
      * #updateLogicalDisplaysLocked} to establish which Virtual Devices own which Virtual Displays.
      */
     private final ArrayMap<String, Integer> mVirtualDeviceDisplayMapping = new ArrayMap<>();
+    private WindowManagerPolicy mWindowManagerPolicy;
 
     private int mNextNonDefaultGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
     private final DisplayIdProducer mIdProducer = (isDefault) ->
@@ -201,15 +206,18 @@
     private final DisplayManagerFlags mFlags;
 
     LogicalDisplayMapper(@NonNull Context context, FoldSettingProvider foldSettingProvider,
+            FoldGracePeriodProvider foldGracePeriodProvider,
             @NonNull DisplayDeviceRepository repo,
             @NonNull Listener listener, @NonNull DisplayManagerService.SyncRoot syncRoot,
             @NonNull Handler handler, DisplayManagerFlags flags) {
-        this(context, foldSettingProvider, repo, listener, syncRoot, handler,
+        this(context, foldSettingProvider, foldGracePeriodProvider, repo, listener, syncRoot,
+                handler,
                 new DeviceStateToLayoutMap((isDefault) -> isDefault ? DEFAULT_DISPLAY
                         : sNextNonDefaultDisplayId++, flags), flags);
     }
 
     LogicalDisplayMapper(@NonNull Context context, FoldSettingProvider foldSettingProvider,
+            FoldGracePeriodProvider foldGracePeriodProvider,
             @NonNull DisplayDeviceRepository repo,
             @NonNull Listener listener, @NonNull DisplayManagerService.SyncRoot syncRoot,
             @NonNull Handler handler, @NonNull DeviceStateToLayoutMap deviceStateToLayoutMap,
@@ -221,13 +229,15 @@
         mDisplayDeviceRepo = repo;
         mListener = listener;
         mFoldSettingProvider = foldSettingProvider;
+        mFoldGracePeriodProvider = foldGracePeriodProvider;
         mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
         mSupportsConcurrentInternalDisplays = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_supportsConcurrentInternalDisplays);
         mDeviceStatesOnWhichToWakeUp = toSparseBooleanArray(context.getResources().getIntArray(
                 com.android.internal.R.array.config_deviceStatesOnWhichToWakeUp));
-        mDeviceStatesOnWhichToSleep = toSparseBooleanArray(context.getResources().getIntArray(
-                com.android.internal.R.array.config_deviceStatesOnWhichToSleep));
+        mDeviceStatesOnWhichToSelectiveSleep = toSparseBooleanArray(
+                context.getResources().getIntArray(
+                        com.android.internal.R.array.config_deviceStatesOnWhichToSleep));
         mDisplayDeviceRepo.addListener(this);
         mDeviceStateToLayoutMap = deviceStateToLayoutMap;
         mFlags = flags;
@@ -267,6 +277,10 @@
         mListener.onTraversalRequested();
     }
 
+    public void onWindowManagerReady() {
+        mWindowManagerPolicy = LocalServices.getService(WindowManagerPolicy.class);
+    }
+
     public LogicalDisplay getDisplayLocked(int displayId) {
         return getDisplayLocked(displayId, /* includeDisabled= */ true);
     }
@@ -404,7 +418,7 @@
         ipw.println("mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
         ipw.println("mCurrentLayout=" + mCurrentLayout);
         ipw.println("mDeviceStatesOnWhichToWakeUp=" + mDeviceStatesOnWhichToWakeUp);
-        ipw.println("mDeviceStatesOnWhichToSleep=" + mDeviceStatesOnWhichToSleep);
+        ipw.println("mDeviceStatesOnWhichSelectiveSleep=" + mDeviceStatesOnWhichToSelectiveSleep);
         ipw.println("mInteractive=" + mInteractive);
         ipw.println("mBootCompleted=" + mBootCompleted);
 
@@ -569,8 +583,8 @@
     boolean shouldDeviceBePutToSleep(int pendingState, int currentState, boolean isInteractive,
             boolean isBootCompleted) {
         return currentState != DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER
-                && mDeviceStatesOnWhichToSleep.get(pendingState)
-                && !mDeviceStatesOnWhichToSleep.get(currentState)
+                && mDeviceStatesOnWhichToSelectiveSleep.get(pendingState)
+                && !mDeviceStatesOnWhichToSelectiveSleep.get(currentState)
                 && isInteractive
                 && isBootCompleted
                 && !mFoldSettingProvider.shouldStayAwakeOnFold();
@@ -611,9 +625,12 @@
         final boolean waitingToWakeDevice = mDeviceStatesOnWhichToWakeUp.get(mPendingDeviceState)
                 && !mDeviceStatesOnWhichToWakeUp.get(mDeviceState)
                 && !mInteractive && mBootCompleted;
-        final boolean waitingToSleepDevice = mDeviceStatesOnWhichToSleep.get(mPendingDeviceState)
-                && !mDeviceStatesOnWhichToSleep.get(mDeviceState)
-                && mInteractive && mBootCompleted;
+        // The device should only wait for sleep if #shouldStayAwakeOnFold method returns false.
+        // If not, device should be marked ready for transition immediately.
+        final boolean waitingToSleepDevice = mDeviceStatesOnWhichToSelectiveSleep.get(
+                mPendingDeviceState)
+                && !mDeviceStatesOnWhichToSelectiveSleep.get(mDeviceState)
+                && mInteractive && mBootCompleted && !shouldStayAwakeOnFold();
 
         final boolean displaysOff = areAllTransitioningDisplaysOffLocked();
         final boolean isReadyToTransition = displaysOff && !waitingToWakeDevice
@@ -1104,14 +1121,22 @@
             final int logicalDisplayId = displayLayout.getLogicalDisplayId();
 
             LogicalDisplay newDisplay = getDisplayLocked(logicalDisplayId);
+            boolean newDisplayCreated = false;
             if (newDisplay == null) {
                 newDisplay = createNewLogicalDisplayLocked(
                         null /*displayDevice*/, logicalDisplayId);
+                newDisplayCreated = true;
             }
 
             // Now swap the underlying display devices between the old display and the new display
             final LogicalDisplay oldDisplay = getDisplayLocked(device);
             if (newDisplay != oldDisplay) {
+                // Display is swapping, notify WindowManager, so it can prepare for
+                // the display switch
+                if (!newDisplayCreated && mWindowManagerPolicy != null) {
+                    mWindowManagerPolicy.onDisplaySwitchStart(newDisplay.getDisplayIdLocked());
+                }
+
                 newDisplay.swapDisplaysLocked(oldDisplay);
             }
             DisplayDeviceConfig config = device.getDisplayDeviceConfig();
@@ -1233,6 +1258,16 @@
         return retval;
     }
 
+    /**
+     * Returns true if the device would definitely have outer display ON/Stay Awake on fold based on
+     * the value of `Continue using app on fold` setting
+     */
+    private boolean shouldStayAwakeOnFold() {
+        return mFoldSettingProvider.shouldStayAwakeOnFold() || (
+                mFoldSettingProvider.shouldSelectiveStayAwakeOnFold()
+                        && mFoldGracePeriodProvider.isEnabled());
+    }
+
     private String displayEventToString(int msg) {
         switch(msg) {
             case LOGICAL_DISPLAY_EVENT_ADDED:
diff --git a/services/core/java/com/android/server/display/NormalBrightnessModeController.java b/services/core/java/com/android/server/display/NormalBrightnessModeController.java
index 135ebd8..e94cf00 100644
--- a/services/core/java/com/android/server/display/NormalBrightnessModeController.java
+++ b/services/core/java/com/android/server/display/NormalBrightnessModeController.java
@@ -79,10 +79,12 @@
             maxBrightnessPoints = mMaxBrightnessLimits.get(BrightnessLimitMapType.ADAPTIVE);
         }
 
-        if (maxBrightnessPoints == null) {
+        // AutoBrightnessController sends ambientLux values *only* when auto brightness enabled.
+        // Temporary disabling this Controller if auto brightness is off, to avoid capping
+        // brightness based on stale ambient lux. The issue is tracked here: b/322445088
+        if (mAutoBrightnessEnabled && maxBrightnessPoints == null) {
             maxBrightnessPoints = mMaxBrightnessLimits.get(BrightnessLimitMapType.DEFAULT);
         }
-
         if (maxBrightnessPoints != null) {
             for (Map.Entry<Float, Float> brightnessPoint : maxBrightnessPoints.entrySet()) {
                 float ambientBoundary = brightnessPoint.getKey();
diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessLowLuxModifier.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessLowLuxModifier.java
index 29b457f..a3dfe22 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessLowLuxModifier.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessLowLuxModifier.java
@@ -70,11 +70,10 @@
         mHandler = handler;
         mContentResolver = context.getContentResolver();
         mSettingsObserver = new SettingsObserver(mHandler);
+        mDisplayDeviceConfig = displayDeviceConfig;
         mHandler.post(() -> {
             start();
         });
-
-        mDisplayDeviceConfig = displayDeviceConfig;
     }
 
     /**
diff --git a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
index 01a8d360a..f1cb66c 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
@@ -24,6 +24,7 @@
 import android.view.SurfaceControlHdrLayerInfoListener;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.display.AutomaticBrightnessController;
 import com.android.server.display.config.HdrBrightnessData;
 
 import java.io.PrintWriter;
@@ -56,6 +57,8 @@
     private float mTransitionRate = -1f;
     private float mDesiredTransitionRate = -1f;
 
+    private boolean mAutoBrightnessEnabled = false;
+
     public HdrClamper(BrightnessClamperController.ClamperChangeListener clamperChangeListener,
             Handler handler) {
         this(clamperChangeListener, handler, new Injector());
@@ -122,6 +125,18 @@
         recalculateBrightnessCap(data, mAmbientLux, mHdrVisible);
     }
 
+    /**
+     * Sets state of auto brightness to temporary disabling this Clamper if auto brightness is off.
+     * The issue is tracked here: b/322445088
+     */
+    public void setAutoBrightnessState(int state) {
+        boolean isEnabled = state == AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED;
+        if (isEnabled != mAutoBrightnessEnabled) {
+            mAutoBrightnessEnabled = isEnabled;
+            recalculateBrightnessCap(mHdrBrightnessData, mAmbientLux, mHdrVisible);
+        }
+    }
+
     /** Clean up all resources */
     @SuppressLint("AndroidFrameworkRequiresPermission")
     public void stop() {
@@ -145,6 +160,7 @@
                 : mHdrBrightnessData.toString()));
         pw.println("  mHdrListener registered=" + (mRegisteredDisplayToken != null));
         pw.println("  mAmbientLux=" + mAmbientLux);
+        pw.println("  mAutoBrightnessEnabled=" + mAutoBrightnessEnabled);
     }
 
     private void reset() {
@@ -163,7 +179,10 @@
 
     private void recalculateBrightnessCap(HdrBrightnessData data, float ambientLux,
             boolean hdrVisible) {
-        if (data == null || !hdrVisible) {
+        // AutoBrightnessController sends ambientLux values *only* when auto brightness enabled.
+        // Temporary disabling this Clamper if auto brightness is off, to avoid capping
+        // brightness based on stale ambient lux. The issue is tracked here: b/322445088
+        if (data == null || !hdrVisible || !mAutoBrightnessEnabled) {
             reset();
             return;
         }
diff --git a/services/core/java/com/android/server/display/config/HysteresisLevels.java b/services/core/java/com/android/server/display/config/HysteresisLevels.java
new file mode 100644
index 0000000..e659d88
--- /dev/null
+++ b/services/core/java/com/android/server/display/config/HysteresisLevels.java
@@ -0,0 +1,463 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.config;
+
+import android.annotation.ArrayRes;
+import android.annotation.Nullable;
+import android.content.res.Resources;
+import android.util.Pair;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.display.utils.DebugUtils;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A helper class for handling access to illuminance hysteresis level values.
+ */
+public class HysteresisLevels {
+    private static final String TAG = "HysteresisLevels";
+
+    private static final float[] DEFAULT_AMBIENT_BRIGHTENING_THRESHOLDS = new float[]{100f};
+    private static final float[] DEFAULT_AMBIENT_DARKENING_THRESHOLDS = new float[]{200f};
+    private static final float[] DEFAULT_AMBIENT_THRESHOLD_LEVELS = new float[]{0f};
+    private static final float[] DEFAULT_SCREEN_THRESHOLD_LEVELS = new float[]{0f};
+    private static final float[] DEFAULT_SCREEN_BRIGHTENING_THRESHOLDS = new float[]{100f};
+    private static final float[] DEFAULT_SCREEN_DARKENING_THRESHOLDS = new float[]{200f};
+
+    // To enable these logs, run:
+    // 'adb shell setprop persist.log.tag.HysteresisLevels DEBUG && adb reboot'
+    private static final boolean DEBUG = DebugUtils.isDebuggable(TAG);
+
+    /**
+     * The array that describes the brightness threshold percentage change
+     * at each brightness level described in mBrighteningThresholdLevels.
+     */
+    private final float[] mBrighteningThresholdsPercentages;
+
+    /**
+     * The array that describes the brightness threshold percentage change
+     * at each brightness level described in mDarkeningThresholdLevels.
+     */
+    private final float[] mDarkeningThresholdsPercentages;
+
+    /**
+     * The array that describes the range of brightness that each threshold percentage applies to
+     *
+     * The (zero-based) index is calculated as follows
+     * value = current brightness value
+     * level = mBrighteningThresholdLevels
+     *
+     * condition                       return
+     * value < mBrighteningThresholdLevels[0]                = 0.0f
+     * level[n] <= value < level[n+1]  = mBrighteningThresholdsPercentages[n]
+     * level[MAX] <= value             = mBrighteningThresholdsPercentages[MAX]
+     */
+    private final float[] mBrighteningThresholdLevels;
+
+    /**
+     * The array that describes the range of brightness that each threshold percentage applies to
+     *
+     * The (zero-based) index is calculated as follows
+     * value = current brightness value
+     * level = mDarkeningThresholdLevels
+     *
+     * condition                       return
+     * value < level[0]                = 0.0f
+     * level[n] <= value < level[n+1]  = mDarkeningThresholdsPercentages[n]
+     * level[MAX] <= value             = mDarkeningThresholdsPercentages[MAX]
+     */
+    private final float[] mDarkeningThresholdLevels;
+
+    /**
+     * The minimum value decrease for darkening event
+     */
+    private final float mMinDarkening;
+
+    /**
+     * The minimum value increase for brightening event.
+     */
+    private final float mMinBrightening;
+
+    /**
+     * Creates a {@code HysteresisLevels} object with the given equal-length
+     * float arrays.
+     *
+     * @param brighteningThresholdsPercentages 0-100 of thresholds
+     * @param darkeningThresholdsPercentages   0-100 of thresholds
+     * @param brighteningThresholdLevels       float array of brightness values in the relevant
+     *                                         units
+     * @param minBrighteningThreshold          the minimum value for which the brightening value
+     *                                         needs to
+     *                                         return.
+     * @param minDarkeningThreshold            the minimum value for which the darkening value needs
+     *                                         to return.
+     */
+    @VisibleForTesting
+    public HysteresisLevels(float[] brighteningThresholdsPercentages,
+            float[] darkeningThresholdsPercentages,
+            float[] brighteningThresholdLevels, float[] darkeningThresholdLevels,
+            float minDarkeningThreshold, float minBrighteningThreshold) {
+        if (brighteningThresholdsPercentages.length != brighteningThresholdLevels.length
+                || darkeningThresholdsPercentages.length != darkeningThresholdLevels.length) {
+            throw new IllegalArgumentException("Mismatch between hysteresis array lengths.");
+        }
+        mBrighteningThresholdsPercentages =
+                setArrayFormat(brighteningThresholdsPercentages, 100.0f);
+        mDarkeningThresholdsPercentages =
+                setArrayFormat(darkeningThresholdsPercentages, 100.0f);
+        mBrighteningThresholdLevels = setArrayFormat(brighteningThresholdLevels, 1.0f);
+        mDarkeningThresholdLevels = setArrayFormat(darkeningThresholdLevels, 1.0f);
+        mMinDarkening = minDarkeningThreshold;
+        mMinBrightening = minBrighteningThreshold;
+    }
+
+    /**
+     * Return the brightening hysteresis threshold for the given value level.
+     */
+    public float getBrighteningThreshold(float value) {
+        final float brightConstant = getReferenceLevel(value,
+                mBrighteningThresholdLevels, mBrighteningThresholdsPercentages);
+
+        float brightThreshold = value * (1.0f + brightConstant);
+        if (DEBUG) {
+            Slog.d(TAG, "bright hysteresis constant=" + brightConstant + ", threshold="
+                    + brightThreshold + ", value=" + value);
+        }
+
+        brightThreshold = Math.max(brightThreshold, value + mMinBrightening);
+        return brightThreshold;
+    }
+
+    /**
+     * Return the darkening hysteresis threshold for the given value level.
+     */
+    public float getDarkeningThreshold(float value) {
+        final float darkConstant = getReferenceLevel(value,
+                mDarkeningThresholdLevels, mDarkeningThresholdsPercentages);
+        float darkThreshold = value * (1.0f - darkConstant);
+        if (DEBUG) {
+            Slog.d(TAG, "dark hysteresis constant=: " + darkConstant + ", threshold="
+                    + darkThreshold + ", value=" + value);
+        }
+        darkThreshold = Math.min(darkThreshold, value - mMinDarkening);
+        return Math.max(darkThreshold, 0.0f);
+    }
+
+    @VisibleForTesting
+    public float[] getBrighteningThresholdsPercentages() {
+        return mBrighteningThresholdsPercentages;
+    }
+
+    @VisibleForTesting
+    public float[] getDarkeningThresholdsPercentages() {
+        return mDarkeningThresholdsPercentages;
+    }
+
+    @VisibleForTesting
+    public float[] getBrighteningThresholdLevels() {
+        return mBrighteningThresholdLevels;
+    }
+
+    @VisibleForTesting
+    public float[] getDarkeningThresholdLevels() {
+        return mDarkeningThresholdLevels;
+    }
+
+    @VisibleForTesting
+    public float getMinDarkening() {
+        return mMinDarkening;
+    }
+
+    @VisibleForTesting
+    public float getMinBrightening() {
+        return mMinBrightening;
+    }
+
+    /**
+     * Return the hysteresis constant for the closest threshold value from the given array.
+     */
+    private float getReferenceLevel(float value, float[] thresholdLevels,
+            float[] thresholdPercentages) {
+        if (thresholdLevels == null || thresholdLevels.length == 0 || value < thresholdLevels[0]) {
+            return 0.0f;
+        }
+        int index = 0;
+        while (index < thresholdLevels.length - 1 && value >= thresholdLevels[index + 1]) {
+            index++;
+        }
+        return thresholdPercentages[index];
+    }
+
+    /**
+     * Return a float array where each i-th element equals {@code configArray[i]/divideFactor}.
+     */
+    private float[] setArrayFormat(float[] configArray, float divideFactor) {
+        float[] levelArray = new float[configArray.length];
+        for (int index = 0; levelArray.length > index; ++index) {
+            levelArray[index] = configArray[index] / divideFactor;
+        }
+        return levelArray;
+    }
+
+    @Override
+    public String toString() {
+        return "HysteresisLevels {"
+                + "\n"
+                + "    mBrighteningThresholdLevels=" + Arrays.toString(mBrighteningThresholdLevels)
+                + ",\n"
+                + "    mBrighteningThresholdsPercentages="
+                + Arrays.toString(mBrighteningThresholdsPercentages)
+                + ",\n"
+                + "    mMinBrightening=" + mMinBrightening
+                + ",\n"
+                + "    mDarkeningThresholdLevels=" + Arrays.toString(mDarkeningThresholdLevels)
+                + ",\n"
+                + "    mDarkeningThresholdsPercentages="
+                + Arrays.toString(mDarkeningThresholdsPercentages)
+                + ",\n"
+                + "    mMinDarkening=" + mMinDarkening
+                + "\n"
+                + "}";
+    }
+
+    /**
+     * Creates hysteresis levels for Active Ambient Lux
+     */
+    public static HysteresisLevels loadAmbientBrightnessConfig(
+            @Nullable DisplayConfiguration config, @Nullable Resources resources) {
+        return createHysteresisLevels(
+                config == null ? null : config.getAmbientBrightnessChangeThresholds(),
+                com.android.internal.R.array.config_ambientThresholdLevels,
+                com.android.internal.R.array.config_ambientBrighteningThresholds,
+                com.android.internal.R.array.config_ambientDarkeningThresholds,
+                DEFAULT_AMBIENT_THRESHOLD_LEVELS,
+                DEFAULT_AMBIENT_BRIGHTENING_THRESHOLDS,
+                DEFAULT_AMBIENT_DARKENING_THRESHOLDS,
+                resources, /* potentialOldBrightnessScale= */ false);
+    }
+
+    /**
+     * Creates hysteresis levels for Active Screen Brightness
+     */
+    public static HysteresisLevels loadDisplayBrightnessConfig(
+            @Nullable DisplayConfiguration config, @Nullable Resources resources) {
+        return createHysteresisLevels(
+                config == null ? null : config.getDisplayBrightnessChangeThresholds(),
+                com.android.internal.R.array.config_screenThresholdLevels,
+                com.android.internal.R.array.config_screenBrighteningThresholds,
+                com.android.internal.R.array.config_screenDarkeningThresholds,
+                DEFAULT_SCREEN_THRESHOLD_LEVELS,
+                DEFAULT_SCREEN_BRIGHTENING_THRESHOLDS,
+                DEFAULT_SCREEN_DARKENING_THRESHOLDS,
+                resources, /* potentialOldBrightnessScale= */ true);
+    }
+
+    /**
+     * Creates hysteresis levels for Idle Ambient Lux
+     */
+    public static HysteresisLevels loadAmbientBrightnessIdleConfig(
+            @Nullable DisplayConfiguration config, @Nullable Resources resources) {
+        return createHysteresisLevels(
+                config == null ? null : config.getAmbientBrightnessChangeThresholdsIdle(),
+                com.android.internal.R.array.config_ambientThresholdLevels,
+                com.android.internal.R.array.config_ambientBrighteningThresholds,
+                com.android.internal.R.array.config_ambientDarkeningThresholds,
+                DEFAULT_AMBIENT_THRESHOLD_LEVELS,
+                DEFAULT_AMBIENT_BRIGHTENING_THRESHOLDS,
+                DEFAULT_AMBIENT_DARKENING_THRESHOLDS,
+                resources, /* potentialOldBrightnessScale= */ false);
+    }
+
+    /**
+     * Creates hysteresis levels for Idle Screen Brightness
+     */
+    public static HysteresisLevels loadDisplayBrightnessIdleConfig(
+            @Nullable DisplayConfiguration config, @Nullable Resources resources) {
+        return createHysteresisLevels(
+                config == null ? null : config.getDisplayBrightnessChangeThresholdsIdle(),
+                com.android.internal.R.array.config_screenThresholdLevels,
+                com.android.internal.R.array.config_screenBrighteningThresholds,
+                com.android.internal.R.array.config_screenDarkeningThresholds,
+                DEFAULT_SCREEN_THRESHOLD_LEVELS,
+                DEFAULT_SCREEN_BRIGHTENING_THRESHOLDS,
+                DEFAULT_SCREEN_DARKENING_THRESHOLDS,
+                resources, /* potentialOldBrightnessScale= */ true);
+    }
+
+
+    private static HysteresisLevels createHysteresisLevels(
+            @Nullable Thresholds thresholds,
+            @ArrayRes int configLevels,
+            @ArrayRes int configBrighteningThresholds,
+            @ArrayRes int configDarkeningThresholds,
+            float[] defaultLevels,
+            float[] defaultBrighteningThresholds,
+            float[] defaultDarkeningThresholds,
+            @Nullable Resources resources,
+            boolean potentialOldBrightnessScale
+    ) {
+        BrightnessThresholds brighteningThresholds =
+                thresholds == null ? null : thresholds.getBrighteningThresholds();
+        BrightnessThresholds darkeningThresholds =
+                thresholds == null ? null : thresholds.getDarkeningThresholds();
+
+        Pair<float[], float[]> brighteningPair = getBrightnessLevelAndPercentage(
+                brighteningThresholds,
+                configLevels, configBrighteningThresholds,
+                defaultLevels, defaultBrighteningThresholds,
+                potentialOldBrightnessScale, resources);
+
+        Pair<float[], float[]> darkeningPair = getBrightnessLevelAndPercentage(
+                darkeningThresholds,
+                configLevels, configDarkeningThresholds,
+                defaultLevels, defaultDarkeningThresholds,
+                potentialOldBrightnessScale, resources);
+
+        float brighteningMinThreshold =
+                brighteningThresholds != null && brighteningThresholds.getMinimum() != null
+                        ? brighteningThresholds.getMinimum().floatValue() : 0f;
+        float darkeningMinThreshold =
+                darkeningThresholds != null && darkeningThresholds.getMinimum() != null
+                        ? darkeningThresholds.getMinimum().floatValue() : 0f;
+
+        return new HysteresisLevels(
+                brighteningPair.second,
+                darkeningPair.second,
+                brighteningPair.first,
+                darkeningPair.first,
+                darkeningMinThreshold,
+                brighteningMinThreshold
+        );
+    }
+
+    // Returns two float arrays, one of the brightness levels and one of the corresponding threshold
+    // percentages for brightness levels at or above the lux value.
+    // Historically, config.xml would have an array for brightness levels that was 1 shorter than
+    // the levels array. Now we prepend a 0 to this array so they can be treated the same in the
+    // rest of the framework. Values were also defined in different units (permille vs percent).
+    private static Pair<float[], float[]> getBrightnessLevelAndPercentage(
+            @Nullable BrightnessThresholds thresholds,
+            int configFallbackThreshold, int configFallbackPermille,
+            float[] defaultLevels, float[] defaultPercentage, boolean potentialOldBrightnessScale,
+            @Nullable Resources resources) {
+        if (thresholds != null
+                && thresholds.getBrightnessThresholdPoints() != null
+                && !thresholds.getBrightnessThresholdPoints().getBrightnessThresholdPoint()
+                .isEmpty()) {
+
+            // The level and percentages arrays are equal length in the ddc (new system)
+            List<ThresholdPoint> points =
+                    thresholds.getBrightnessThresholdPoints().getBrightnessThresholdPoint();
+            final int size = points.size();
+
+            float[] thresholdLevels = new float[size];
+            float[] thresholdPercentages = new float[size];
+
+            int i = 0;
+            for (ThresholdPoint point : points) {
+                thresholdLevels[i] = point.getThreshold().floatValue();
+                thresholdPercentages[i] = point.getPercentage().floatValue();
+                i++;
+            }
+            return new Pair<>(thresholdLevels, thresholdPercentages);
+        } else if (resources != null) {
+            // The level and percentages arrays are unequal length in config.xml (old system)
+            // We prefix the array with a 0 value to ensure they can be handled consistently
+            // with the new system.
+
+            // Load levels array
+            int[] configThresholdArray = resources.getIntArray(configFallbackThreshold);
+            int configThresholdsSize;
+            // null check is not needed here, however it test we are mocking resources that might
+            // return null
+            if (configThresholdArray == null || configThresholdArray.length == 0) {
+                configThresholdsSize = 1;
+            } else {
+                configThresholdsSize = configThresholdArray.length + 1;
+            }
+
+            // Load percentage array
+            int[] configPermille = resources.getIntArray(configFallbackPermille);
+
+            // Ensure lengths match up
+            // null check is not needed here, however it test we are mocking resources that might
+            // return null
+            boolean emptyArray = configPermille == null || configPermille.length == 0;
+            if (emptyArray && configThresholdsSize == 1) {
+                return new Pair<>(defaultLevels, defaultPercentage);
+            }
+            if (emptyArray || configPermille.length != configThresholdsSize) {
+                throw new IllegalArgumentException(
+                        "Brightness threshold arrays do not align in length");
+            }
+
+            // Calculate levels array
+            float[] configThresholdWithZeroPrefixed = new float[configThresholdsSize];
+            // Start at 1, so that 0 index value is 0.0f (default)
+            for (int i = 1; i < configThresholdsSize; i++) {
+                configThresholdWithZeroPrefixed[i] = (float) configThresholdArray[i - 1];
+            }
+            if (potentialOldBrightnessScale) {
+                configThresholdWithZeroPrefixed =
+                        constraintInRangeIfNeeded(configThresholdWithZeroPrefixed);
+            }
+
+            // Calculate percentages array
+            float[] configPercentage = new float[configThresholdsSize];
+            for (int i = 0; i < configPermille.length; i++) {
+                configPercentage[i] = configPermille[i] / 10.0f;
+            }
+            return new Pair<>(configThresholdWithZeroPrefixed, configPercentage);
+        } else {
+            return new Pair<>(defaultLevels, defaultPercentage);
+        }
+    }
+
+    /**
+     * This check is due to historical reasons, where screen thresholdLevels used to be
+     * integer values in the range of [0-255], but then was changed to be float values from [0,1].
+     * To accommodate both the possibilities, we first check if all the thresholdLevels are in
+     * [0,1], and if not, we divide all the levels with 255 to bring them down to the same scale.
+     */
+    private static float[] constraintInRangeIfNeeded(float[] thresholdLevels) {
+        if (isAllInRange(thresholdLevels, /* minValueInclusive= */ 0.0f,
+                /* maxValueInclusive= */ 1.0f)) {
+            return thresholdLevels;
+        }
+
+        Slog.w(TAG, "Detected screen thresholdLevels on a deprecated brightness scale");
+        float[] thresholdLevelsScaled = new float[thresholdLevels.length];
+        for (int index = 0; thresholdLevels.length > index; ++index) {
+            thresholdLevelsScaled[index] = thresholdLevels[index] / 255.0f;
+        }
+        return thresholdLevelsScaled;
+    }
+
+    private static boolean isAllInRange(float[] configArray, float minValueInclusive,
+            float maxValueInclusive) {
+        for (float v : configArray) {
+            if (v < minValueInclusive || v > maxValueInclusive) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+}
diff --git a/services/core/java/com/android/server/display/config/SensorData.java b/services/core/java/com/android/server/display/config/SensorData.java
index 8e716f8..6ad13c3 100644
--- a/services/core/java/com/android/server/display/config/SensorData.java
+++ b/services/core/java/com/android/server/display/config/SensorData.java
@@ -129,21 +129,46 @@
      * Loads proximity sensor data from DisplayConfiguration
      */
     @Nullable
-    public static SensorData loadProxSensorConfig(DisplayConfiguration config) {
-        SensorDetails sensorDetails = config.getProxSensor();
-        if (sensorDetails != null) {
-            String name = sensorDetails.getName();
-            String type = sensorDetails.getType();
-            if ("".equals(name) && "".equals(type)) {
+    public static SensorData loadProxSensorConfig(
+            DisplayManagerFlags flags, DisplayConfiguration config) {
+        SensorData DEFAULT_SENSOR = new SensorData();
+        List<SensorDetails> sensorDetailsList = config.getProxSensor();
+        if (sensorDetailsList.isEmpty()) {
+            return DEFAULT_SENSOR;
+        }
+
+        SensorData selectedSensor = DEFAULT_SENSOR;
+        // Prioritize flagged sensors.
+        for (SensorDetails sensorDetails : sensorDetailsList) {
+            String flagStr = sensorDetails.getFeatureFlag();
+            if (flags.isUseFusionProxSensorEnabled() &&
+                flags.getUseFusionProxSensorFlagName().equals(flagStr)) {
+                selectedSensor = loadSensorData(sensorDetails);
+                break;
+            }
+        }
+
+        // Check for normal un-flagged sensor if a flagged one wasn't found.
+        if (DEFAULT_SENSOR == selectedSensor) {
+            for (SensorDetails sensorDetails : sensorDetailsList) {
+                if (sensorDetails.getFeatureFlag() != null) {
+                    continue;
+                }
+                selectedSensor = loadSensorData(sensorDetails);
+                break;
+            }
+        }
+
+        // Check if we shouldn't use a sensor at all.
+        if (DEFAULT_SENSOR != selectedSensor) {
+            if ("".equals(selectedSensor.name) && "".equals(selectedSensor.type)) {
                 // <proxSensor> with empty values to the config means no sensor should be used.
                 // See also {@link com.android.server.display.utils.SensorUtils}
-                return null;
-            } else {
-                return loadSensorData(sensorDetails);
+                selectedSensor = null;
             }
-        } else {
-            return new SensorData();
         }
+
+        return selectedSensor;
     }
 
     /**
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/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index 81f824e..50b1464 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -144,12 +144,15 @@
             Flags::idleScreenRefreshRateTimeout
     );
 
-
     private final FlagState mRefactorDisplayPowerController = new FlagState(
             Flags.FLAG_REFACTOR_DISPLAY_POWER_CONTROLLER,
             Flags::refactorDisplayPowerController
     );
 
+    private final FlagState mUseFusionProxSensor = new FlagState(
+            Flags.FLAG_USE_FUSION_PROX_SENSOR,
+            Flags::useFusionProxSensor
+    );
 
     /**
      * @return {@code true} if 'port' is allowed in display layout configuration file.
@@ -301,6 +304,14 @@
         return mRefactorDisplayPowerController.isEnabled();
     }
 
+    public boolean isUseFusionProxSensorEnabled() {
+        return mUseFusionProxSensor.isEnabled();
+    }
+
+    public String getUseFusionProxSensorFlagName() {
+        return mUseFusionProxSensor.getName();
+    }
+
     /**
      * dumps all flagstates
      * @param pw printWriter
@@ -331,6 +342,7 @@
         pw.println(" " + mIdleScreenRefreshRateTimeout);
         pw.println(" " + mRefactorDisplayPowerController);
         pw.println(" " + mResolutionBackupRestore);
+        pw.println(" " + mUseFusionProxSensor);
     }
 
     private static class FlagState {
@@ -346,6 +358,10 @@
             mFlagFunction = flagFunction;
         }
 
+        private String getName() {
+            return mName;
+        }
+
         private boolean isEnabled() {
             if (mEnabledSet) {
                 if (DEBUG) {
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 49a8553..c68ef9b 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.
 
@@ -235,3 +236,11 @@
     bug: "310026579"
     is_fixed_read_only: true
 }
+
+flag {
+    name: "use_fusion_prox_sensor"
+    namespace: "display_manager"
+    description: "Feature flag to control usage of a Fusion Proximity sensor if configued."
+    bug: "306203895"
+    is_fixed_read_only: true
+}
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 14e964b..98978f0 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/compaction.aconfig b/services/core/java/com/android/server/flags/compaction.aconfig
index 58cc560..067a1c9 100644
--- a/services/core/java/com/android/server/flags/compaction.aconfig
+++ b/services/core/java/com/android/server/flags/compaction.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.flags"
+container: "system"
 
 flag {
     name: "disable_system_compaction"
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/flags/services.aconfig b/services/core/java/com/android/server/flags/services.aconfig
index 10b5eff..8e0eb05 100644
--- a/services/core/java/com/android/server/flags/services.aconfig
+++ b/services/core/java/com/android/server/flags/services.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.flags"
+container: "system"
 
 flag {
      namespace: "wear_frameworks"
diff --git a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
index 7b844a0..f383679 100644
--- a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
+++ b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
@@ -165,7 +165,11 @@
 
         @Override
         public void onBootPhase(int phase) {
-            if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+            final int latestFontLoadBootPhase =
+                    (Flags.completeFontLoadInSystemServicesReady())
+                            ? SystemService.PHASE_SYSTEM_SERVICES_READY
+                            : SystemService.PHASE_ACTIVITY_MANAGER_READY;
+            if (phase == latestFontLoadBootPhase) {
                 // Wait for FontManagerService to start since it will be needed after this point.
                 mServiceStarted.join();
             }
diff --git a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
index 1715254..ea240c7 100644
--- a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
+++ b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java
@@ -196,8 +196,12 @@
                 File signatureFile = new File(dir, FONT_SIGNATURE_FILE);
                 if (!signatureFile.exists()) {
                     Slog.i(TAG, "The signature file is missing.");
-                    FileUtils.deleteContentsAndDir(dir);
-                    continue;
+                    if (com.android.text.flags.Flags.fixFontUpdateFailure()) {
+                        return;
+                    } else {
+                        FileUtils.deleteContentsAndDir(dir);
+                        continue;
+                    }
                 }
                 byte[] signature;
                 try {
@@ -222,10 +226,42 @@
 
                 FontFileInfo fontFileInfo = validateFontFile(fontFile, signature);
                 if (fontConfig == null) {
-                    fontConfig = getSystemFontConfig();
+                    if (com.android.text.flags.Flags.fixFontUpdateFailure()) {
+                        // Use preinstalled font config for checking revision number.
+                        fontConfig = mConfigSupplier.apply(Collections.emptyMap());
+                    } else {
+                        fontConfig = getSystemFontConfig();
+                    }
                 }
                 addFileToMapIfSameOrNewer(fontFileInfo, fontConfig, true /* deleteOldFile */);
             }
+
+            if (com.android.text.flags.Flags.fixFontUpdateFailure()) {
+                // Treat as error if post script name of font family was not installed.
+                for (int i = 0; i < config.fontFamilies.size(); ++i) {
+                    FontUpdateRequest.Family family = config.fontFamilies.get(i);
+                    for (int j = 0; j < family.getFonts().size(); ++j) {
+                        FontUpdateRequest.Font font = family.getFonts().get(j);
+                        if (mFontFileInfoMap.containsKey(font.getPostScriptName())) {
+                            continue;
+                        }
+
+                        if (fontConfig == null) {
+                            fontConfig = mConfigSupplier.apply(Collections.emptyMap());
+                        }
+
+                        if (getFontByPostScriptName(font.getPostScriptName(), fontConfig) != null) {
+                            continue;
+                        }
+
+                        Slog.e(TAG, "Unknown font that has PostScript name "
+                                + font.getPostScriptName() + " is requested in FontFamily "
+                                + family.getName());
+                        return;
+                    }
+                }
+            }
+
             success = true;
         } catch (Throwable t) {
             // If something happened during loading system fonts, clear all contents in finally
@@ -237,6 +273,9 @@
                 mFontFileInfoMap.clear();
                 mLastModifiedMillis = 0;
                 FileUtils.deleteContents(mFilesDir);
+                if (com.android.text.flags.Flags.fixFontUpdateFailure()) {
+                    mConfigFile.delete();
+                }
             }
         }
     }
@@ -485,8 +524,7 @@
         return shouldAddToMap;
     }
 
-    private long getPreinstalledFontRevision(FontFileInfo info, FontConfig fontConfig) {
-        String psName = info.getPostScriptName();
+    private FontConfig.Font getFontByPostScriptName(String psName, FontConfig fontConfig) {
         FontConfig.Font targetFont = null;
         for (int i = 0; i < fontConfig.getFontFamilies().size(); i++) {
             FontConfig.FontFamily family = fontConfig.getFontFamilies().get(i);
@@ -511,6 +549,13 @@
                 }
             }
         }
+        return targetFont;
+    }
+
+    private long getPreinstalledFontRevision(FontFileInfo info, FontConfig fontConfig) {
+        String psName = info.getPostScriptName();
+        FontConfig.Font targetFont = getFontByPostScriptName(psName, fontConfig);
+
         if (targetFont == null) {
             return -1;
         }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index a79fb88..f6dfc9e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -528,15 +528,17 @@
      */
     @ServiceThreadOnly
     void pollDevices(DevicePollingCallback callback, int sourceAddress, int pickStrategy,
-            int retryCount) {
+            int retryCount, long pollingMessageInterval) {
         assertRunOnServiceThread();
 
         // Extract polling candidates. No need to poll against local devices.
         List<Integer> pollingCandidates = pickPollCandidates(pickStrategy);
         ArrayList<Integer> allocated = new ArrayList<>();
+        // pollStarted indication to avoid polling delay for the first message
         mControlHandler.postDelayed(
-                () -> runDevicePolling(
-                        sourceAddress, pollingCandidates, retryCount, callback, allocated),
+                ()
+                        -> runDevicePolling(sourceAddress, pollingCandidates, retryCount, callback,
+                                allocated, pollingMessageInterval, /**pollStarted**/ false),
                 mPollDevicesDelay);
     }
 
@@ -576,9 +578,10 @@
     }
 
     @ServiceThreadOnly
-    private void runDevicePolling(final int sourceAddress,
-            final List<Integer> candidates, final int retryCount,
-            final DevicePollingCallback callback, final List<Integer> allocated) {
+    private void runDevicePolling(final int sourceAddress, final List<Integer> candidates,
+            final int retryCount, final DevicePollingCallback callback,
+            final List<Integer> allocated, final long pollingMessageInterval,
+            final boolean pollStarted) {
         assertRunOnServiceThread();
         if (candidates.isEmpty()) {
             if (callback != null) {
@@ -587,11 +590,10 @@
             }
             return;
         }
-
         final Integer candidate = candidates.remove(0);
         // Proceed polling action for the next address once polling action for the
         // previous address is done.
-        runOnIoThread(new Runnable() {
+        mIoHandler.postDelayed(new Runnable() {
             @Override
             public void run() {
                 if (sendPollMessage(sourceAddress, candidate, retryCount)) {
@@ -600,12 +602,12 @@
                 runOnServiceThread(new Runnable() {
                     @Override
                     public void run() {
-                        runDevicePolling(sourceAddress, candidates, retryCount, callback,
-                                allocated);
+                        runDevicePolling(sourceAddress, candidates, retryCount, callback, allocated,
+                                pollingMessageInterval, /**pollStarted**/ true);
                     }
                 });
             }
-        });
+        }, pollStarted ? pollingMessageInterval : 0);
     }
 
     @IoThreadOnly
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java b/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
index 5db114b..234d6d3 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java
@@ -229,7 +229,13 @@
 
     protected final void pollDevices(DevicePollingCallback callback, int pickStrategy,
             int retryCount) {
-        mService.pollDevices(callback, getSourceAddress(), pickStrategy, retryCount);
+        pollDevices(callback, pickStrategy, retryCount, 0);
+    }
+
+    protected final void pollDevices(DevicePollingCallback callback, int pickStrategy,
+            int retryCount, long pollingMessageInterval) {
+        mService.pollDevices(
+                callback, getSourceAddress(), pickStrategy, retryCount, pollingMessageInterval);
     }
 
     /**
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index 731c78e..d21fc85 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -29,6 +29,7 @@
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.SystemProperties;
+import android.os.UserHandle;
 import android.sysprop.HdmiProperties;
 import android.util.Slog;
 
@@ -53,6 +54,16 @@
     @VisibleForTesting
     static final long STANDBY_AFTER_HOTPLUG_OUT_DELAY_MS = 30_000;
 
+    // How long to wait on active source lost before possibly going to Standby.
+    @VisibleForTesting
+    static final long STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS = 30_000;
+
+    // How long to wait after losing active source, before launching the pop-up that allows the user
+    // to keep the device as the current active source.
+    // We do this to prevent an unnecessary pop-up from being displayed when we lose and regain
+    // active source within this timeout.
+    static final long POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS = 5_000;
+
     // Used to keep the device awake while it is the active source. For devices that
     // cannot wake up via CEC commands, this address the inconvenience of having to
     // turn them on. True by default, and can be disabled (i.e. device can go to sleep
@@ -64,6 +75,14 @@
     // Handler for queueing a delayed Standby runnable after hotplug out.
     private Handler mDelayedStandbyHandler;
 
+    // Handler for queueing a delayed Standby runnable after active source lost and after the pop-up
+    // on active source lost was displayed.
+    Handler mDelayedStandbyOnActiveSourceLostHandler;
+
+    // Handler for queueing a delayed runnable that triggers a pop-up notification on active source
+    // lost.
+    private Handler mDelayedPopupOnActiveSourceLostHandler;
+
     // Determines what action should be taken upon receiving Routing Control messages.
     @VisibleForTesting
     protected HdmiProperties.playback_device_action_on_routing_control_values
@@ -75,6 +94,8 @@
         super(service, HdmiDeviceInfo.DEVICE_PLAYBACK);
 
         mDelayedStandbyHandler = new Handler(service.getServiceLooper());
+        mDelayedStandbyOnActiveSourceLostHandler = new Handler(service.getServiceLooper());
+        mDelayedPopupOnActiveSourceLostHandler = new Handler(service.getServiceLooper());
         mStandbyHandler = new HdmiCecStandbyModeHandler(service, this);
     }
 
@@ -239,6 +260,28 @@
         }
     }
 
+    private class DelayedStandbyOnActiveSourceLostRunnable implements Runnable {
+        @Override
+        public void run() {
+            if (mService.getPowerManagerInternal().wasDeviceIdleFor(
+                    STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS)) {
+                mService.standby();
+            } else {
+                mService.setAndBroadcastActiveSource(mService.getPhysicalAddress(),
+                        getDeviceInfo().getDeviceType(), Constants.ADDR_TV,
+                        "DelayedActiveSourceLostStandbyRunnable");
+            }
+        }
+    }
+
+    @ServiceThreadOnly
+    void dismissUiOnActiveSourceStatusRecovered() {
+        assertRunOnServiceThread();
+        Intent intent = new Intent(HdmiControlManager.ACTION_ON_ACTIVE_SOURCE_RECOVERED_DISMISS_UI);
+        mService.getContext().sendBroadcastAsUser(intent, UserHandle.ALL,
+                HdmiControlService.PERMISSION);
+    }
+
     @Override
     @ServiceThreadOnly
     protected void onStandby(boolean initiatedByCec, int standbyAction,
@@ -387,13 +430,47 @@
         switch (mService.getHdmiCecConfig().getStringValue(
                     HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST)) {
             case HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW:
-                mService.standby();
+                mDelayedPopupOnActiveSourceLostHandler.removeCallbacksAndMessages(null);
+                mDelayedPopupOnActiveSourceLostHandler.postDelayed(
+                        new Runnable() {
+                            @Override
+                            public void run() {
+                                if (!isActiveSource()) {
+                                    startHdmiCecActiveSourceLostActivity();
+                                    mDelayedStandbyOnActiveSourceLostHandler
+                                            .removeCallbacksAndMessages(null);
+                                    mDelayedStandbyOnActiveSourceLostHandler.postDelayed(
+                                            new DelayedStandbyOnActiveSourceLostRunnable(),
+                                            STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
+                                }
+                            }
+                        }, POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
                 return;
             case HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE:
                 return;
         }
     }
 
+    @VisibleForTesting
+    @ServiceThreadOnly
+    void startHdmiCecActiveSourceLostActivity() {
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            Context context = mService.getContext();
+            Intent intent = new Intent();
+            intent.setComponent(
+                    ComponentName.unflattenFromString(context.getResources().getString(
+                            com.android.internal.R.string.config_hdmiCecActiveSourceLostActivity
+                    )));
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            context.startActivityAsUser(intent, context.getUser());
+        } catch (ActivityNotFoundException e) {
+            Slog.e(TAG, "Unable to start HdmiCecActiveSourceLostActivity");
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     @ServiceThreadOnly
     @Constants.HandleMessageResult
     protected int handleUserControlPressed(HdmiCecMessage message) {
@@ -557,6 +634,7 @@
             setActiveSource(physicalAddress,
                     "HdmiCecLocalDevicePlayback#handleRoutingChangeAndInformation()");
         }
+        dismissUiOnActiveSourceStatusRecovered();
         switch (mPlaybackDeviceActionOnRoutingControl) {
             case WAKE_UP_AND_SEND_ACTIVE_SOURCE:
                 setAndBroadcastActiveSource(message, physicalAddress,
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index d0532b99..54e1217 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -1823,10 +1823,10 @@
      */
     @ServiceThreadOnly
     void pollDevices(DevicePollingCallback callback, int sourceAddress, int pickStrategy,
-            int retryCount) {
+            int retryCount, long pollingMessageInterval) {
         assertRunOnServiceThread();
         mCecController.pollDevices(callback, sourceAddress, checkPollStrategy(pickStrategy),
-                retryCount);
+                retryCount, pollingMessageInterval);
     }
 
     private int checkPollStrategy(int pickStrategy) {
@@ -4205,10 +4205,12 @@
         // playback will claim active source. Otherwise audio system will.
         if (deviceType == HdmiDeviceInfo.DEVICE_PLAYBACK) {
             HdmiCecLocalDevicePlayback playback = playback();
+            playback.dismissUiOnActiveSourceStatusRecovered();
             playback.setActiveSource(playback.getDeviceInfo().getLogicalAddress(), physicalAddress,
                     caller);
             playback.wakeUpIfActiveSource();
             playback.maySendActiveSource(source);
+            playback.mDelayedStandbyOnActiveSourceLostHandler.removeCallbacksAndMessages(null);
         }
 
         if (deviceType == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
diff --git a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
index da40ce59..30842b2 100644
--- a/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
+++ b/services/core/java/com/android/server/hdmi/HotplugDetectionAction.java
@@ -38,8 +38,10 @@
 final class HotplugDetectionAction extends HdmiCecFeatureAction {
     private static final String TAG = "HotPlugDetectionAction";
 
-    public static final int POLLING_INTERVAL_MS_FOR_TV = 5000;
-    public static final int POLLING_INTERVAL_MS_FOR_PLAYBACK = 60000;
+    public static final long POLLING_MESSAGE_INTERVAL_MS_FOR_TV = 0;
+    public static final long POLLING_MESSAGE_INTERVAL_MS_FOR_PLAYBACK = 500;
+    public static final int POLLING_BATCH_INTERVAL_MS_FOR_TV = 5000;
+    public static final int POLLING_BATCH_INTERVAL_MS_FOR_PLAYBACK = 60000;
     public static final int TIMEOUT_COUNT = 3;
     private static final int AVR_COUNT_MAX = 3;
 
@@ -69,8 +71,9 @@
         super(source);
     }
 
-    private int getPollingInterval() {
-        return mIsTvDevice ? POLLING_INTERVAL_MS_FOR_TV : POLLING_INTERVAL_MS_FOR_PLAYBACK;
+    private int getPollingBatchInterval() {
+        return mIsTvDevice ? POLLING_BATCH_INTERVAL_MS_FOR_TV
+                           : POLLING_BATCH_INTERVAL_MS_FOR_PLAYBACK;
     }
 
     @Override
@@ -83,7 +86,7 @@
         // Start timer without polling.
         // The first check for all devices will be initiated 15 seconds later for TV panels and 60
         // seconds later for playback devices.
-        addTimer(mState, getPollingInterval());
+        addTimer(mState, getPollingBatchInterval());
         return true;
     }
 
@@ -107,11 +110,11 @@
                 } else if (tv().isSystemAudioActivated()) {
                     pollAudioSystem();
                 }
-                addTimer(mState, POLLING_INTERVAL_MS_FOR_TV);
+                addTimer(mState, POLLING_BATCH_INTERVAL_MS_FOR_TV);
                 return;
             }
             pollAllDevices();
-            addTimer(mState, POLLING_INTERVAL_MS_FOR_PLAYBACK);
+            addTimer(mState, POLLING_BATCH_INTERVAL_MS_FOR_PLAYBACK);
         }
     }
 
@@ -127,19 +130,24 @@
         mState = STATE_WAIT_FOR_NEXT_POLLING;
         pollAllDevices();
 
-        addTimer(mState, getPollingInterval());
+        addTimer(mState, getPollingBatchInterval());
     }
 
     private void pollAllDevices() {
         Slog.v(TAG, "Poll all devices.");
 
-        pollDevices(new DevicePollingCallback() {
-            @Override
-            public void onPollingFinished(List<Integer> ackedAddress) {
-                checkHotplug(ackedAddress, false);
-            }
-        }, Constants.POLL_ITERATION_IN_ORDER
-                | Constants.POLL_STRATEGY_REMOTES_DEVICES, HdmiConfig.HOTPLUG_DETECTION_RETRY);
+        pollDevices(
+                new DevicePollingCallback() {
+                    @Override
+                    public void onPollingFinished(List<Integer> ackedAddress) {
+                        checkHotplug(ackedAddress, false);
+                        Slog.v(TAG, "Finish poll all devices.");
+                    }
+                },
+                Constants.POLL_ITERATION_IN_ORDER | Constants.POLL_STRATEGY_REMOTES_DEVICES,
+                HdmiConfig.HOTPLUG_DETECTION_RETRY,
+                mIsTvDevice ? POLLING_MESSAGE_INTERVAL_MS_FOR_TV
+                            : POLLING_MESSAGE_INTERVAL_MS_FOR_PLAYBACK);
     }
 
     private void pollAudioSystem() {
diff --git a/services/core/java/com/android/server/input/AmbientKeyboardBacklightController.java b/services/core/java/com/android/server/input/AmbientKeyboardBacklightController.java
index ce86849..569322c 100644
--- a/services/core/java/com/android/server/input/AmbientKeyboardBacklightController.java
+++ b/services/core/java/com/android/server/input/AmbientKeyboardBacklightController.java
@@ -234,6 +234,9 @@
         DisplayManagerInternal displayManagerInternal = LocalServices.getService(
                 DisplayManagerInternal.class);
         DisplayInfo displayInfo = displayManagerInternal.getDisplayInfo(Display.DEFAULT_DISPLAY);
+        if (displayInfo == null) {
+            return;
+        }
         synchronized (sAmbientControllerLock) {
             if (Objects.equals(mCurrentDefaultDisplayUniqueId, displayInfo.uniqueId)) {
                 return;
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index c80f988..5931744 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -107,7 +107,7 @@
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.security.AndroidKeyStoreMaintenance;
-import android.security.Authorization;
+import android.security.KeyStoreAuthorization;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
 import android.security.keystore.recovery.KeyChainProtectionParams;
@@ -293,6 +293,7 @@
     private final SyntheticPasswordManager mSpManager;
 
     private final KeyStore mKeyStore;
+    private final KeyStoreAuthorization mKeyStoreAuthorization;
     private final RecoverableKeyStoreManager mRecoverableKeyStoreManager;
     private final UnifiedProfilePasswordCache mUnifiedProfilePasswordCache;
 
@@ -627,6 +628,10 @@
             }
         }
 
+        public KeyStoreAuthorization getKeyStoreAuthorization() {
+            return KeyStoreAuthorization.getInstance();
+        }
+
         public @NonNull UnifiedProfilePasswordCache getUnifiedProfilePasswordCache(KeyStore ks) {
             return new UnifiedProfilePasswordCache(ks);
         }
@@ -650,6 +655,7 @@
         mInjector = injector;
         mContext = injector.getContext();
         mKeyStore = injector.getKeyStore();
+        mKeyStoreAuthorization = injector.getKeyStoreAuthorization();
         mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager();
         mHandler = injector.getHandler(injector.getServiceThread());
         mStrongAuth = injector.getStrongAuth();
@@ -1460,7 +1466,7 @@
     }
 
     private void unlockKeystore(int userId, SyntheticPassword sp) {
-        Authorization.onDeviceUnlocked(userId, sp.deriveKeyStorePassword());
+        mKeyStoreAuthorization.onDeviceUnlocked(userId, sp.deriveKeyStorePassword());
     }
 
     @VisibleForTesting /** Note: this method is overridden in unit tests */
diff --git a/services/core/java/com/android/server/media/AudioManagerRouteController.java b/services/core/java/com/android/server/media/AudioManagerRouteController.java
index e7f717a..f27ade4 100644
--- a/services/core/java/com/android/server/media/AudioManagerRouteController.java
+++ b/services/core/java/com/android/server/media/AudioManagerRouteController.java
@@ -136,7 +136,7 @@
 
         mBluetoothRouteController =
                 new BluetoothDeviceRoutesManager(
-                        mContext, btAdapter, this::rebuildAvailableRoutesAndNotify);
+                        mContext, mHandler, btAdapter, this::rebuildAvailableRoutesAndNotify);
         // Just build routes but don't notify. The caller may not expect the listener to be invoked
         // before this constructor has finished executing.
         rebuildAvailableRoutes();
@@ -204,23 +204,24 @@
             Slog.w(TAG, "transferTo: Ignoring transfer request to unknown route id : " + routeId);
             return;
         }
-        // TODO: b/329929065 - Push audio manager and bluetooth operations to the handler, so that
-        // they don't run on a binder thread, so as to prevent possible deadlocks (these operations
-        // may need system_server binder threads to complete).
-        if (mediaRoute2InfoHolder.mCorrespondsToInactiveBluetoothRoute) {
-            // By default, the last connected device is the active route so we don't need to apply a
-            // routing audio policy.
-            mBluetoothRouteController.activateBluetoothDeviceWithAddress(
-                    mediaRoute2InfoHolder.mMediaRoute2Info.getAddress());
-            mAudioManager.removePreferredDeviceForStrategy(mStrategyForMedia);
-        } else {
-            AudioDeviceAttributes attr =
-                    new AudioDeviceAttributes(
-                            AudioDeviceAttributes.ROLE_OUTPUT,
-                            mediaRoute2InfoHolder.mAudioDeviceInfoType,
-                            /* address= */ ""); // This is not a BT device, hence no address needed.
-            mAudioManager.setPreferredDeviceForStrategy(mStrategyForMedia, attr);
-        }
+        Runnable transferAction = getTransferActionForRoute(mediaRoute2InfoHolder);
+        Runnable guardedTransferAction =
+                () -> {
+                    try {
+                        transferAction.run();
+                    } catch (Throwable throwable) {
+                        // We swallow the exception to avoid crashing system_server, since this
+                        // doesn't run on a binder thread.
+                        Slog.e(
+                                TAG,
+                                "Unexpected exception while transferring to route id: " + routeId,
+                                throwable);
+                        mHandler.post(this::rebuildAvailableRoutesAndNotify);
+                    }
+                };
+        // We post the transfer operation to the handler to avoid making these calls on a binder
+        // thread. See class javadoc for details.
+        mHandler.post(guardedTransferAction);
     }
 
     @RequiresPermission(
@@ -236,6 +237,28 @@
         return true;
     }
 
+    private Runnable getTransferActionForRoute(MediaRoute2InfoHolder mediaRoute2InfoHolder) {
+        if (mediaRoute2InfoHolder.mCorrespondsToInactiveBluetoothRoute) {
+            String deviceAddress = mediaRoute2InfoHolder.mMediaRoute2Info.getAddress();
+            return () -> {
+                // By default, the last connected device is the active route so we don't
+                // need to apply a routing audio policy.
+                mBluetoothRouteController.activateBluetoothDeviceWithAddress(deviceAddress);
+                mAudioManager.removePreferredDeviceForStrategy(mStrategyForMedia);
+            };
+
+        } else {
+            AudioDeviceAttributes deviceAttributes =
+                    new AudioDeviceAttributes(
+                            AudioDeviceAttributes.ROLE_OUTPUT,
+                            mediaRoute2InfoHolder.mAudioDeviceInfoType,
+                            /* address= */ ""); // This is not a BT device, hence no address needed.
+            return () ->
+                    mAudioManager.setPreferredDeviceForStrategy(
+                            mStrategyForMedia, deviceAttributes);
+        }
+    }
+
     @RequiresPermission(
             anyOf = {
                 Manifest.permission.MODIFY_AUDIO_ROUTING,
diff --git a/services/core/java/com/android/server/media/BluetoothDeviceRoutesManager.java b/services/core/java/com/android/server/media/BluetoothDeviceRoutesManager.java
index b881ef6..8b65ea3 100644
--- a/services/core/java/com/android/server/media/BluetoothDeviceRoutesManager.java
+++ b/services/core/java/com/android/server/media/BluetoothDeviceRoutesManager.java
@@ -31,6 +31,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.media.MediaRoute2Info;
+import android.os.Handler;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
@@ -77,26 +78,35 @@
 
     @NonNull
     private final Context mContext;
-    @NonNull
-    private final BluetoothAdapter mBluetoothAdapter;
+    @NonNull private final Handler mHandler;
+    @NonNull private final BluetoothAdapter mBluetoothAdapter;
     @NonNull
     private final BluetoothRouteController.BluetoothRoutesUpdatedListener mListener;
     @NonNull
     private final BluetoothProfileMonitor mBluetoothProfileMonitor;
 
-    BluetoothDeviceRoutesManager(@NonNull Context context,
+    BluetoothDeviceRoutesManager(
+            @NonNull Context context,
+            @NonNull Handler handler,
             @NonNull BluetoothAdapter bluetoothAdapter,
             @NonNull BluetoothRouteController.BluetoothRoutesUpdatedListener listener) {
-        this(context, bluetoothAdapter,
-                new BluetoothProfileMonitor(context, bluetoothAdapter), listener);
+        this(
+                context,
+                handler,
+                bluetoothAdapter,
+                new BluetoothProfileMonitor(context, bluetoothAdapter),
+                listener);
     }
 
     @VisibleForTesting
-    BluetoothDeviceRoutesManager(@NonNull Context context,
+    BluetoothDeviceRoutesManager(
+            @NonNull Context context,
+            @NonNull Handler handler,
             @NonNull BluetoothAdapter bluetoothAdapter,
             @NonNull BluetoothProfileMonitor bluetoothProfileMonitor,
             @NonNull BluetoothRouteController.BluetoothRoutesUpdatedListener listener) {
         mContext = Objects.requireNonNull(context);
+        mHandler = handler;
         mBluetoothAdapter = Objects.requireNonNull(bluetoothAdapter);
         mBluetoothProfileMonitor = Objects.requireNonNull(bluetoothProfileMonitor);
         mListener = Objects.requireNonNull(listener);
@@ -298,6 +308,26 @@
         };
     }
 
+    private void handleBluetoothAdapterStateChange(int state) {
+        if (state == BluetoothAdapter.STATE_OFF || state == BluetoothAdapter.STATE_TURNING_OFF) {
+            synchronized (BluetoothDeviceRoutesManager.this) {
+                mBluetoothRoutes.clear();
+            }
+            notifyBluetoothRoutesUpdated();
+        } else if (state == BluetoothAdapter.STATE_ON) {
+            updateBluetoothRoutes();
+
+            boolean shouldCallListener;
+            synchronized (BluetoothDeviceRoutesManager.this) {
+                shouldCallListener = !mBluetoothRoutes.isEmpty();
+            }
+
+            if (shouldCallListener) {
+                notifyBluetoothRoutesUpdated();
+            }
+        }
+    }
+
     private static class BluetoothRouteInfo {
         private BluetoothDevice mBtDevice;
         private MediaRoute2Info mRoute;
@@ -308,23 +338,10 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
-            if (state == BluetoothAdapter.STATE_OFF
-                    || state == BluetoothAdapter.STATE_TURNING_OFF) {
-                synchronized (BluetoothDeviceRoutesManager.this) {
-                    mBluetoothRoutes.clear();
-                }
-                notifyBluetoothRoutesUpdated();
-            } else if (state == BluetoothAdapter.STATE_ON) {
-                updateBluetoothRoutes();
-
-                boolean shouldCallListener;
-                synchronized (BluetoothDeviceRoutesManager.this) {
-                    shouldCallListener = !mBluetoothRoutes.isEmpty();
-                }
-
-                if (shouldCallListener) {
-                    notifyBluetoothRoutesUpdated();
-                }
+            if (Flags.enableMr2ServiceNonMainBgThread()) {
+                mHandler.post(() -> handleBluetoothAdapterStateChange(state));
+            } else {
+                handleBluetoothAdapterStateChange(state);
             }
         }
     }
@@ -337,8 +354,16 @@
                 case BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED:
                 case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED:
                 case BluetoothDevice.ACTION_ALIAS_CHANGED:
-                    updateBluetoothRoutes();
-                    notifyBluetoothRoutesUpdated();
+                    if (Flags.enableMr2ServiceNonMainBgThread()) {
+                        mHandler.post(
+                                () -> {
+                                    updateBluetoothRoutes();
+                                    notifyBluetoothRoutesUpdated();
+                                });
+                    } else {
+                        updateBluetoothRoutes();
+                        notifyBluetoothRoutesUpdated();
+                    }
             }
         }
     }
diff --git a/services/core/java/com/android/server/media/MediaKeyDispatcher.java b/services/core/java/com/android/server/media/MediaKeyDispatcher.java
index 66cafab..e4f2ec3 100644
--- a/services/core/java/com/android/server/media/MediaKeyDispatcher.java
+++ b/services/core/java/com/android/server/media/MediaKeyDispatcher.java
@@ -44,7 +44,6 @@
  * Note: When instantiating this class, {@link MediaSessionService} will only use the constructor
  * without any parameters.
  */
-// TODO: Move this class to apex/media/
 public abstract class MediaKeyDispatcher {
     @IntDef(flag = true, value = {
             KEY_EVENT_SINGLE_TAP,
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
index 67d3fe9..db83d4b 100644
--- a/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderServiceProxy.java
@@ -232,7 +232,9 @@
         if (!mRunning) {
             return false;
         }
-        if (!getSessionInfos().isEmpty() || mIsManagerScanning) {
+        boolean bindDueToManagerScan =
+                mIsManagerScanning && Flags.enablePreventionOfManagerScansWhenNoAppsScan();
+        if (!getSessionInfos().isEmpty() || bindDueToManagerScan) {
             // We bind if any manager is scanning (regardless of whether an app is scanning) to give
             // the opportunity for providers to publish routing sessions that were established
             // directly between the app and the provider (typically via AndroidX MediaRouter). See
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index ec15ff3..e50189b 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -114,6 +114,7 @@
             };
 
     private final Context mContext;
+    private final Looper mLooper;
     private final UserManagerInternal mUserManagerInternal;
     private final Object mLock = new Object();
     private final AppOpsManager mAppOpsManager;
@@ -178,8 +179,9 @@
                 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
                 Manifest.permission.WATCH_APPOPS
             })
-    /* package */ MediaRouter2ServiceImpl(Context context) {
+    /* package */ MediaRouter2ServiceImpl(@NonNull Context context, @NonNull Looper looper) {
         mContext = context;
+        mLooper = looper;
         mActivityManager = mContext.getSystemService(ActivityManager.class);
         mActivityManager.addOnUidImportanceListener(mOnUidImportanceListener,
                 REQUIRED_PACKAGE_IMPORTANCE_FOR_SCANNING);
@@ -187,12 +189,10 @@
         mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
         mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
 
-        if (!Flags.disableScreenOffBroadcastReceiver()) {
-            IntentFilter screenOnOffIntentFilter = new IntentFilter();
-            screenOnOffIntentFilter.addAction(ACTION_SCREEN_ON);
-            screenOnOffIntentFilter.addAction(ACTION_SCREEN_OFF);
-            mContext.registerReceiver(mScreenOnOffReceiver, screenOnOffIntentFilter);
-        }
+        IntentFilter screenOnOffIntentFilter = new IntentFilter();
+        screenOnOffIntentFilter.addAction(ACTION_SCREEN_ON);
+        screenOnOffIntentFilter.addAction(ACTION_SCREEN_OFF);
+        mContext.registerReceiver(mScreenOnOffReceiver, screenOnOffIntentFilter);
 
         // Passing null package name to listen to all events.
         mAppOpsManager.startWatchingMode(
@@ -1891,7 +1891,7 @@
     private UserRecord getOrCreateUserRecordLocked(int userId) {
         UserRecord userRecord = mUserRecords.get(userId);
         if (userRecord == null) {
-            userRecord = new UserRecord(userId);
+            userRecord = new UserRecord(userId, mLooper);
             mUserRecords.put(userId, userRecord);
             userRecord.init();
             if (isUserActiveLocked(userId)) {
@@ -1962,9 +1962,13 @@
         Set<String> mActivelyScanningPackages = Set.of();
         final UserHandler mHandler;
 
-        UserRecord(int userId) {
+        UserRecord(int userId, @NonNull Looper looper) {
             mUserId = userId;
-            mHandler = new UserHandler(MediaRouter2ServiceImpl.this, this);
+            mHandler =
+                    new UserHandler(
+                            /* service= */ MediaRouter2ServiceImpl.this,
+                            /* userRecord= */ this,
+                            looper);
         }
 
         void init() {
@@ -2365,12 +2369,16 @@
         private boolean mRunning;
 
         // TODO: (In Android S+) Pull out SystemMediaRoute2Provider out of UserHandler.
-        UserHandler(@NonNull MediaRouter2ServiceImpl service, @NonNull UserRecord userRecord) {
-            super(Looper.getMainLooper(), null, true);
+        UserHandler(
+                @NonNull MediaRouter2ServiceImpl service,
+                @NonNull UserRecord userRecord,
+                @NonNull Looper looper) {
+            super(looper, /* callback= */ null, /* async= */ true);
             mServiceRef = new WeakReference<>(service);
             mUserRecord = userRecord;
-            mSystemProvider = new SystemMediaRoute2Provider(service.mContext,
-                    UserHandle.of(userRecord.mUserId));
+            mSystemProvider =
+                    new SystemMediaRoute2Provider(
+                            service.mContext, UserHandle.of(userRecord.mUserId), looper);
             mRouteProviders.add(mSystemProvider);
             mWatcher = new MediaRoute2ProviderWatcher(service.mContext, this,
                     this, mUserRecord.mUserId);
@@ -3425,9 +3433,7 @@
         @NonNull
         private static List<RouterRecord> getIndividuallyActiveRouters(
                 MediaRouter2ServiceImpl service, List<RouterRecord> allRouterRecords) {
-            if (!Flags.disableScreenOffBroadcastReceiver()
-                    && !service.mPowerManager.isInteractive()
-                    && !Flags.enableScreenOffScanning()) {
+            if (!service.mPowerManager.isInteractive() && !Flags.enableScreenOffScanning()) {
                 return Collections.emptyList();
             }
 
@@ -3443,9 +3449,7 @@
 
         private static boolean areManagersScanning(
                 MediaRouter2ServiceImpl service, List<ManagerRecord> managerRecords) {
-            if (!Flags.disableScreenOffBroadcastReceiver()
-                    && !service.mPowerManager.isInteractive()
-                    && !Flags.enableScreenOffScanning()) {
+            if (!service.mPowerManager.isInteractive() && !Flags.enableScreenOffScanning()) {
                 return false;
             }
 
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 76b8db6..1a129cb 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -53,6 +53,7 @@
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
@@ -70,6 +71,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.DumpUtils;
+import com.android.media.flags.Flags;
 import com.android.server.LocalServices;
 import com.android.server.Watchdog;
 import com.android.server.pm.UserManagerInternal;
@@ -94,6 +96,7 @@
         implements Watchdog.Monitor {
     private static final String TAG = "MediaRouterService";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final String WORKER_THREAD_NAME = "MediaRouterServiceThread";
 
     /**
      * Timeout in milliseconds for a selected route to transition from a disconnected state to a
@@ -110,6 +113,7 @@
     private static final long CONNECTED_TIMEOUT = 60000;
 
     private final Context mContext;
+    private final Looper mLooper;
 
     // State guarded by mLock.
     private final Object mLock = new Object();
@@ -125,7 +129,7 @@
 
     private final IAudioService mAudioService;
     private final AudioPlayerStateMonitor mAudioPlayerStateMonitor;
-    private final Handler mHandler = new Handler();
+    private final Handler mHandler;
     private final IntArray mActivePlayerMinPriorityQueue = new IntArray();
     private final IntArray mActivePlayerUidMinPriorityQueue = new IntArray();
 
@@ -141,7 +145,15 @@
 
     @RequiresPermission(Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS)
     public MediaRouterService(Context context) {
-        mService2 = new MediaRouter2ServiceImpl(context);
+        if (Flags.enableMr2ServiceNonMainBgThread()) {
+            HandlerThread handlerThread = new HandlerThread(WORKER_THREAD_NAME);
+            handlerThread.start();
+            mLooper = handlerThread.getLooper();
+        } else {
+            mLooper = Looper.myLooper();
+        }
+        mHandler = new Handler(mLooper);
+        mService2 = new MediaRouter2ServiceImpl(context, mLooper);
         mContext = context;
         Watchdog.getInstance().addMonitor(this);
         Resources res = context.getResources();
@@ -1104,7 +1116,7 @@
 
         public UserRecord(int userId) {
             mUserId = userId;
-            mHandler = new UserHandler(MediaRouterService.this, this);
+            mHandler = new UserHandler(MediaRouterService.this, this, mLooper);
         }
 
         public void dump(final PrintWriter pw, String prefix) {
@@ -1212,8 +1224,8 @@
         private long mConnectionTimeoutStartTime;
         private boolean mClientStateUpdateScheduled;
 
-        public UserHandler(MediaRouterService service, UserRecord userRecord) {
-            super(Looper.getMainLooper(), null, true);
+        private UserHandler(MediaRouterService service, UserRecord userRecord, Looper looper) {
+            super(looper, null, true);
             mService = service;
             mUserRecord = userRecord;
             mWatcher = new RemoteDisplayProviderWatcher(service.mContext, this,
diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
index 67bc61c..8df38a8 100644
--- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
+++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java
@@ -86,12 +86,11 @@
     @GuardedBy("mTransferLock")
     @Nullable private volatile SessionCreationRequest mPendingTransferRequest;
 
-    SystemMediaRoute2Provider(Context context, UserHandle user) {
+    SystemMediaRoute2Provider(Context context, UserHandle user, Looper looper) {
         super(COMPONENT_NAME);
         mIsSystemRouteProvider = true;
         mContext = context;
         mUser = user;
-        Looper looper = Looper.getMainLooper();
         mHandler = new Handler(looper);
 
         mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
@@ -654,9 +653,11 @@
                 return;
             }
 
-            // TODO: b/310145678 - Post this to mHandler once mHandler does not run on the main
-            // thread.
-            updateVolume();
+            if (Flags.enableMr2ServiceNonMainBgThread()) {
+                mHandler.post(SystemMediaRoute2Provider.this::updateVolume);
+            } else {
+                updateVolume();
+            }
         }
     }
 }
diff --git a/services/core/java/com/android/server/media/TEST_MAPPING b/services/core/java/com/android/server/media/TEST_MAPPING
index b3e5b9e..43e2afd 100644
--- a/services/core/java/com/android/server/media/TEST_MAPPING
+++ b/services/core/java/com/android/server/media/TEST_MAPPING
@@ -2,9 +2,7 @@
   "presubmit": [
     {
       "name": "CtsMediaBetterTogetherTestCases"
-    }
-  ],
-  "postsubmit": [
+    },
     {
       "name": "MediaRouterServiceTests"
     }
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/flags.aconfig b/services/core/java/com/android/server/net/flags.aconfig
index 419665a..d9491de 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"
diff --git a/services/core/java/com/android/server/notification/Android.bp b/services/core/java/com/android/server/notification/Android.bp
index 9be4358..d757470 100644
--- a/services/core/java/com/android/server/notification/Android.bp
+++ b/services/core/java/com/android/server/notification/Android.bp
@@ -10,6 +10,7 @@
 aconfig_declarations {
     name: "notification_flags",
     package: "com.android.server.notification",
+    container: "system",
     srcs: [
         "flags.aconfig",
     ],
diff --git a/services/core/java/com/android/server/notification/NotificationChannelExtractor.java b/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
index 2f60e42..bd73cb6 100644
--- a/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationChannelExtractor.java
@@ -15,8 +15,16 @@
 */
 package com.android.server.notification;
 
+import static android.app.Flags.restrictAudioAttributesAlarm;
+import static android.app.Flags.restrictAudioAttributesCall;
+import static android.app.Flags.restrictAudioAttributesMedia;
+import static android.app.Notification.CATEGORY_ALARM;
+import static android.media.AudioAttributes.USAGE_NOTIFICATION;
+
+import android.app.Notification;
 import android.app.NotificationChannel;
 import android.content.Context;
+import android.media.AudioAttributes;
 import android.util.Slog;
 
 /**
@@ -50,6 +58,36 @@
                 record.getSbn().getShortcutId(), true, false);
         record.updateNotificationChannel(updatedChannel);
 
+        if (restrictAudioAttributesCall() || restrictAudioAttributesAlarm()
+                || restrictAudioAttributesMedia()) {
+            AudioAttributes attributes = record.getChannel().getAudioAttributes();
+            boolean updateAttributes =  false;
+            if (restrictAudioAttributesCall()
+                    && !record.getNotification().isStyle(Notification.CallStyle.class)
+                    && attributes.getUsage() == AudioAttributes.USAGE_NOTIFICATION_RINGTONE) {
+                updateAttributes = true;
+            }
+            if (restrictAudioAttributesAlarm()
+                    && record.getNotification().category != CATEGORY_ALARM
+                    && attributes.getUsage() == AudioAttributes.USAGE_ALARM) {
+                updateAttributes = true;
+            }
+
+            if (restrictAudioAttributesMedia()
+                    && (attributes.getUsage() == AudioAttributes.USAGE_UNKNOWN
+                    || attributes.getUsage() == AudioAttributes.USAGE_MEDIA)) {
+                updateAttributes = true;
+            }
+
+            if (updateAttributes) {
+                NotificationChannel clone = record.getChannel().copy();
+                clone.setSound(clone.getSound(), new AudioAttributes.Builder(attributes)
+                        .setUsage(USAGE_NOTIFICATION)
+                        .build());
+                record.updateNotificationChannel(clone);
+            }
+        }
+
         return null;
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 493c4a0..956e10c 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -22,6 +22,8 @@
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
 import static android.app.ActivityManagerInternal.ServiceNotificationPolicy.NOT_FOREGROUND_SERVICE;
 import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR;
+import static android.app.Flags.lifetimeExtensionRefactor;
 import static android.app.Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
 import static android.app.Notification.EXTRA_BUILDER_APPLICATION_INFO;
 import static android.app.Notification.EXTRA_LARGE_ICON_BIG;
@@ -34,7 +36,6 @@
 import static android.app.Notification.FLAG_BUBBLE;
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
 import static android.app.Notification.FLAG_FSI_REQUESTED_BUT_DENIED;
-import static android.app.Notification.FLAG_INSISTENT;
 import static android.app.Notification.FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
 import static android.app.Notification.FLAG_NO_CLEAR;
 import static android.app.Notification.FLAG_NO_DISMISS;
@@ -71,8 +72,6 @@
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
-import static android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR;
-import static android.app.Flags.lifetimeExtensionRefactor;
 import static android.app.NotificationManager.zenModeFromInterruptionFilter;
 import static android.app.StatusBarManager.ACTION_KEYGUARD_PRIVATE_NOTIFICATIONS_CHANGED;
 import static android.app.StatusBarManager.EXTRA_KM_PRIVATE_NOTIFS_ALLOWED;
@@ -88,8 +87,6 @@
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.media.audio.Flags.focusExclusiveWithRecording;
-import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
 import static android.os.Flags.allowPrivateProfile;
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
@@ -98,8 +95,8 @@
 import static android.os.UserHandle.USER_ALL;
 import static android.os.UserHandle.USER_NULL;
 import static android.os.UserHandle.USER_SYSTEM;
-import static android.service.notification.Flags.redactSensitiveNotificationsFromUntrustedListeners;
 import static android.service.notification.Flags.callstyleCallbackApi;
+import static android.service.notification.Flags.redactSensitiveNotificationsFromUntrustedListeners;
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ALERTING;
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_CONVERSATIONS;
 import static android.service.notification.NotificationListenerService.FLAG_FILTER_TYPE_ONGOING;
@@ -139,10 +136,9 @@
 import static android.service.notification.NotificationListenerService.Ranking.RANKING_UNCHANGED;
 import static android.service.notification.NotificationListenerService.TRIM_FULL;
 import static android.service.notification.NotificationListenerService.TRIM_LIGHT;
-import static android.view.contentprotection.flags.Flags.rapidClearNotificationsByListenerAppOpEnabled;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
+import static android.view.contentprotection.flags.Flags.rapidClearNotificationsByListenerAppOpEnabled;
 
-import static android.app.Flags.updateRankingTime;
 import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES;
 import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES;
@@ -185,7 +181,6 @@
 import android.app.ITransientNotification;
 import android.app.ITransientNotificationCallback;
 import android.app.IUriGrantsManager;
-import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.Notification.MessagingStyle;
 import android.app.NotificationChannel;
@@ -199,7 +194,6 @@
 import android.app.RemoteServiceException.BadForegroundServiceNotificationException;
 import android.app.RemoteServiceException.BadUserInitiatedJobNotificationException;
 import android.app.StatsManager;
-import android.app.StatusBarManager;
 import android.app.UriGrantsManager;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.app.backup.BackupManager;
@@ -238,7 +232,6 @@
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.graphics.drawable.Icon;
-import android.media.AudioAttributes;
 import android.metrics.LogMaker;
 import android.net.Uri;
 import android.os.Binder;
@@ -267,7 +260,6 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.VibrationEffect;
 import android.os.WorkSource;
 import android.permission.PermissionManager;
 import android.provider.DeviceConfig;
@@ -293,7 +285,6 @@
 import android.service.notification.ZenModeProto;
 import android.service.notification.ZenPolicy;
 import android.telecom.TelecomManager;
-import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
@@ -310,7 +301,6 @@
 import android.util.Xml;
 import android.util.proto.ProtoOutputStream;
 import android.view.Display;
-import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.RemoteViews;
 import android.widget.Toast;
@@ -350,7 +340,6 @@
 import com.android.server.SystemService;
 import com.android.server.job.JobSchedulerInternal;
 import com.android.server.lights.LightsManager;
-import com.android.server.lights.LogicalLight;
 import com.android.server.notification.GroupHelper.NotificationAttributes;
 import com.android.server.notification.ManagedServices.ManagedServiceInfo;
 import com.android.server.notification.ManagedServices.UserProfiles;
@@ -600,6 +589,8 @@
 
     private static final Duration POST_WAKE_LOCK_TIMEOUT = Duration.ofSeconds(30);
 
+    static final long NOTIFICATION_TTL = Duration.ofDays(3).toMillis();
+
     private IActivityManager mAm;
     private ActivityTaskManagerInternal mAtm;
     private ActivityManager mActivityManager;
@@ -1329,7 +1320,29 @@
                 // Notifications that have been interacted with should no longer be lifetime
                 // extended.
                 if (lifetimeExtensionRefactor()) {
-                    r.getSbn().getNotification().flags &= ~FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+                    // This cancellation should only work if
+                    // the notification still has FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY
+                    // We wait for 200 milliseconds before posting the cancel, to allow the app
+                    // time to update the notification in response instead.
+                    // If that update goes through, the notification won't have the lifetime
+                    // extended flag, and this cancellation will be dropped.
+                    mHandler.scheduleCancelNotification(
+                            new CancelNotificationRunnable(
+                                    callingUid,
+                                    callingPid,
+                                    r.getSbn().getPackageName(),
+                                    r.getSbn().getTag(),
+                                    r.getSbn().getId(),
+                                    FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY /*=mustHaveFlags*/,
+                                    FLAG_NO_DISMISS /*=mustNotHaveFlags*/,
+                                    false /*=sendDelete*/,
+                                    r.getUserId(),
+                                    REASON_CLICK,
+                                    -1 /*=rank*/,
+                                    -1 /*=count*/,
+                                    null /*=listener*/,
+                                    SystemClock.elapsedRealtime()),
+                            200);
                 }
             }
         }
@@ -1842,14 +1855,6 @@
                                 FLAG_FOREGROUND_SERVICE | FLAG_USER_INITIATED_JOB
                                         | FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY,
                                 true, record.getUserId(), REASON_TIMEOUT, null);
-                        // If cancellation will be prevented due to lifetime extension, we send an
-                        // update to system UI.
-                        final int packageImportance = getPackageImportanceWithIdentity(
-                                record.getSbn().getPackageName());
-                        synchronized (mNotificationLock) {
-                            maybeNotifySystemUiListenerLifetimeExtendedLocked(record,
-                                    record.getSbn().getPackageName(), packageImportance);
-                        }
                     } else {
                         cancelNotification(record.getSbn().getUid(),
                                 record.getSbn().getInitialPid(),
@@ -3660,15 +3665,6 @@
             if (lifetimeExtensionRefactor()) {
                 // Also don't allow client apps to cancel lifetime extended notifs.
                 mustNotHaveFlags |= FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
-                // If cancellation will be prevented due to lifetime extension, we send an update to
-                // system UI.
-                NotificationRecord record = null;
-                final int packageImportance = getPackageImportanceWithIdentity(pkg);
-                synchronized (mNotificationLock) {
-                    record = findNotificationLocked(pkg, tag, id, userId);
-                    maybeNotifySystemUiListenerLifetimeExtendedLocked(record, pkg,
-                            packageImportance);
-                }
             }
 
             cancelNotificationInternal(pkg, opPkg, Binder.getCallingUid(), Binder.getCallingPid(),
@@ -4865,7 +4861,7 @@
                                     || isNotificationRecent(r.getUpdateTimeMs());
                             cancelNotificationFromListenerLocked(info, callingUid, callingPid,
                                     r.getSbn().getPackageName(), r.getSbn().getTag(),
-                                    r.getSbn().getId(), userId, reason, packageImportance);
+                                    r.getSbn().getId(), userId, reason);
                         }
                     } else {
                         for (NotificationRecord notificationRecord : mNotificationList) {
@@ -5005,14 +5001,10 @@
         @GuardedBy("mNotificationLock")
         private void cancelNotificationFromListenerLocked(ManagedServiceInfo info,
                 int callingUid, int callingPid, String pkg, String tag, int id, int userId,
-                int reason, int packageImportance) {
+                int reason) {
             int mustNotHaveFlags = FLAG_ONGOING_EVENT;
             if (lifetimeExtensionRefactor()) {
                 mustNotHaveFlags |= FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
-                // If cancellation will be prevented due to lifetime extension, we send an update
-                // to system UI.
-                NotificationRecord record = findNotificationLocked(pkg, tag, id, userId);
-                maybeNotifySystemUiListenerLifetimeExtendedLocked(record, pkg, packageImportance);
             }
             cancelNotification(callingUid, callingPid, pkg, tag, id, 0 /* mustHaveFlags */,
                     mustNotHaveFlags,
@@ -5155,13 +5147,7 @@
             final int callingUid = Binder.getCallingUid();
             final int callingPid = Binder.getCallingPid();
             final long identity = Binder.clearCallingIdentity();
-            final int packageImportance;
             try {
-                if (lifetimeExtensionRefactor()) {
-                    packageImportance = getPackageImportanceWithIdentity(pkg);
-                } else {
-                    packageImportance = IMPORTANCE_NONE;
-                }
                 synchronized (mNotificationLock) {
                     final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
                     int cancelReason = REASON_LISTENER_CANCEL;
@@ -5174,7 +5160,7 @@
                                 + " use cancelNotification(key) instead.");
                     } else {
                         cancelNotificationFromListenerLocked(info, callingUid, callingPid,
-                                pkg, tag, id, info.userid, cancelReason, packageImportance);
+                                pkg, tag, id, info.userid, cancelReason);
                     }
                 }
             } finally {
@@ -7591,6 +7577,12 @@
 
         // Remote views? Are they too big?
         checkRemoteViews(pkg, tag, id, notification);
+
+        if (Flags.allNotifsNeedTtl()) {
+            if (notification.getTimeoutAfter() == 0) {
+                notification.setTimeoutAfter(NOTIFICATION_TTL);
+            }
+        }
     }
 
     /**
@@ -8159,19 +8151,30 @@
                 EventLogTags.writeNotificationCancel(mCallingUid, mCallingPid, mPkg, mId, mTag,
                         mUserId, mMustHaveFlags, mMustNotHaveFlags, mReason, listenerName);
             }
-
+            int packageImportance = IMPORTANCE_NONE;
+            if (lifetimeExtensionRefactor()) {
+                packageImportance = getPackageImportanceWithIdentity(mPkg);
+            }
             synchronized (mNotificationLock) {
                 // Look for the notification, searching both the posted and enqueued lists.
                 NotificationRecord r = findNotificationLocked(mPkg, mTag, mId, mUserId);
+
                 if (r != null) {
                     // The notification was found, check if it should be removed.
-
                     // Ideally we'd do this in the caller of this method. However, that would
                     // require the caller to also find the notification.
                     if (mReason == REASON_CLICK) {
                         mUsageStats.registerClickedByUser(r);
                     }
 
+                    // If cancellation will be prevented due to lifetime extension, we need to
+                    // send an update to system UI. This must be checked before flags are checked.
+                    // We do not want to send this update.
+                    if (lifetimeExtensionRefactor() && mReason != REASON_CLICK) {
+                        maybeNotifySystemUiListenerLifetimeExtendedLocked(r, mPkg,
+                                packageImportance);
+                    }
+
                     if ((mReason == REASON_LISTENER_CANCEL
                             && r.getNotification().isBubbleNotification())
                             || (mReason == REASON_CLICK && r.canBubble()
@@ -8499,7 +8502,7 @@
                         r.isUpdate = true;
                         final boolean isInterruptive = isVisuallyInterruptive(old, r);
                         r.setTextChanged(isInterruptive);
-                        if (updateRankingTime()) {
+                        if (android.app.Flags.updateRankingTime()) {
                             if (isInterruptive) {
                                 r.resetRankingTime();
                             }
@@ -8644,14 +8647,26 @@
             return false;
         }
 
-        // Ignore visual interruptions from foreground services because users
-        // consider them one 'session'. Count them for everything else.
-        if ((r.getSbn().getNotification().flags & FLAG_FOREGROUND_SERVICE) != 0) {
-            if (DEBUG_INTERRUPTIVENESS) {
-                Slog.v(TAG, "INTERRUPTIVENESS: "
-                        +  r.getKey() + " is not interruptive: foreground service");
+        if (android.app.Flags.updateRankingTime()) {
+            // Ignore visual interruptions from FGS/UIJs because users
+            // consider them one 'session'. Count them for everything else.
+            if (r.getSbn().getNotification().isFgsOrUij()) {
+                if (DEBUG_INTERRUPTIVENESS) {
+                    Slog.v(TAG, "INTERRUPTIVENESS: "
+                            + r.getKey() + " is not interruptive: FGS/UIJ");
+                }
+                return false;
             }
-            return false;
+        } else {
+            // Ignore visual interruptions from foreground services because users
+            // consider them one 'session'. Count them for everything else.
+            if ((r.getSbn().getNotification().flags & FLAG_FOREGROUND_SERVICE) != 0) {
+                if (DEBUG_INTERRUPTIVENESS) {
+                    Slog.v(TAG, "INTERRUPTIVENESS: "
+                            + r.getKey() + " is not interruptive: foreground service");
+                }
+                return false;
+            }
         }
 
         final String oldTitle = String.valueOf(oldN.extras.get(Notification.EXTRA_TITLE));
@@ -9327,12 +9342,17 @@
             }
         }
 
-        protected void scheduleCancelNotification(CancelNotificationRunnable cancelRunnable) {
-            if (Flags.notificationReduceMessagequeueUsage()) {
-                sendMessage(Message.obtain(this, cancelRunnable));
+        protected void scheduleCancelNotification(CancelNotificationRunnable cancelRunnable,
+                                                  int delay) {
+            if (lifetimeExtensionRefactor()) {
+                sendMessageDelayed(Message.obtain(this, cancelRunnable), delay);
             } else {
-                if (!hasCallbacks(cancelRunnable)) {
+                if (Flags.notificationReduceMessagequeueUsage()) {
                     sendMessage(Message.obtain(this, cancelRunnable));
+                } else {
+                    if (!hasCallbacks(cancelRunnable)) {
+                        sendMessage(Message.obtain(this, cancelRunnable));
+                    }
                 }
             }
         }
@@ -9688,7 +9708,7 @@
         // remove notification call ends up in not removing the notification.
         mHandler.scheduleCancelNotification(new CancelNotificationRunnable(callingUid, callingPid,
                 pkg, tag, id, mustHaveFlags, mustNotHaveFlags, sendDelete, userId, reason, rank,
-                count, listener, SystemClock.elapsedRealtime()));
+                count, listener, SystemClock.elapsedRealtime()), 0);
     }
 
     /**
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 7e58d0a..97d2620 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -15,6 +15,9 @@
  */
 package com.android.server.notification;
 
+import static android.app.Flags.restrictAudioAttributesAlarm;
+import static android.app.Flags.restrictAudioAttributesCall;
+import static android.app.Flags.restrictAudioAttributesMedia;
 import static android.app.Flags.updateRankingTime;
 import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
@@ -1090,7 +1093,7 @@
         Notification n = getNotification();
         // Take developer provided 'when', unless it's in the future.
         if (updateRankingTime()) {
-            if (n.when != n.creationTime && n.when <= getSbn().getPostTime()){
+            if (n.hasAppProvidedWhen() && n.when <= getSbn().getPostTime()){
                 return n.when;
             }
         } else {
@@ -1159,6 +1162,11 @@
             mChannel = channel;
             calculateImportance();
             calculateUserSentiment();
+            mVibration = calculateVibration();
+            if (restrictAudioAttributesCall() || restrictAudioAttributesAlarm()
+                    || restrictAudioAttributesMedia()) {
+                mAttributes = channel.getAudioAttributes();
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/notification/NotificationTimeComparator.java b/services/core/java/com/android/server/notification/NotificationTimeComparator.java
new file mode 100644
index 0000000..550c428
--- /dev/null
+++ b/services/core/java/com/android/server/notification/NotificationTimeComparator.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.notification;
+
+import java.util.Comparator;
+
+/**
+ * Sorts notifications by stabilised recency.
+ */
+public class NotificationTimeComparator implements Comparator<NotificationRecord> {
+    /**
+     * Sorts by time, with some stability being applied to updates
+     *
+     * Time stability logic lives in NotificationRecord.
+     */
+    @Override
+    public int compare(NotificationRecord left, NotificationRecord right) {
+        // earliest first
+        return -1 * Long.compare(left.getRankingTimeMs(), right.getRankingTimeMs());
+    }
+}
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 773d10b..7b12d86 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.notification;
 
+import static android.app.Flags.sortSectionByTime;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
 import static android.text.TextUtils.formatSimple;
 
 import android.annotation.NonNull;
@@ -28,12 +30,13 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
 
 public class RankingHelper {
     private static final String TAG = "RankingHelper";
 
     private final NotificationSignalExtractor[] mSignalExtractors;
-    private final NotificationComparator mPreliminaryComparator;
+    private final Comparator mPreliminaryComparator;
     private final GlobalSortKeyComparator mFinalComparator = new GlobalSortKeyComparator();
 
     private final ArrayMap<String, NotificationRecord> mProxyByGroupTmp = new ArrayMap<>();
@@ -46,7 +49,11 @@
             ZenModeHelper zenHelper, NotificationUsageStats usageStats, String[] extractorNames) {
         mContext = context;
         mRankingHandler = rankingHandler;
-        mPreliminaryComparator = new NotificationComparator(mContext);
+        if (sortSectionByTime()) {
+            mPreliminaryComparator = new NotificationTimeComparator();
+        } else {
+            mPreliminaryComparator = new NotificationComparator(mContext);
+        }
 
         final int N = extractorNames.length;
         mSignalExtractors = new NotificationSignalExtractor[N];
@@ -104,9 +111,13 @@
         }
 
         // Rank each record individually.
-        // Lock comparator state for consistent compare() results.
-        synchronized (mPreliminaryComparator.mStateLock) {
+        if (sortSectionByTime()) {
             notificationList.sort(mPreliminaryComparator);
+        } else {
+            // Lock comparator state for consistent compare() results.
+            synchronized (((NotificationComparator) mPreliminaryComparator).mStateLock) {
+                notificationList.sort(mPreliminaryComparator);
+            }
         }
 
         synchronized (mProxyByGroupTmp) {
@@ -114,10 +125,22 @@
             for (int i = 0; i < N; i++) {
                 final NotificationRecord record = notificationList.get(i);
                 record.setAuthoritativeRank(i);
-                final String groupKey = record.getGroupKey();
-                NotificationRecord existingProxy = mProxyByGroupTmp.get(groupKey);
-                if (existingProxy == null) {
-                    mProxyByGroupTmp.put(groupKey, record);
+                if (sortSectionByTime()) {
+                    final String groupKey = record.getGroupKey();
+                    NotificationRecord existingProxy = mProxyByGroupTmp.get(groupKey);
+                    // summaries are mostly hidden in systemui - if there is a child notification
+                    // with better information, use its rank
+                    if (existingProxy == null
+                            || (existingProxy.getNotification().isGroupSummary()
+                            && !existingProxy.getNotification().hasAppProvidedWhen())) {
+                        mProxyByGroupTmp.put(groupKey, record);
+                    }
+                } else {
+                    final String groupKey = record.getGroupKey();
+                    NotificationRecord existingProxy = mProxyByGroupTmp.get(groupKey);
+                    if (existingProxy == null) {
+                        mProxyByGroupTmp.put(groupKey, record);
+                    }
                 }
             }
             // assign global sort key:
@@ -142,12 +165,14 @@
                 }
 
                 boolean isGroupSummary = record.getNotification().isGroupSummary();
+                char intrusiveRank = sortSectionByTime()
+                        ? '2'
+                        : record.isRecentlyIntrusive() && record.getImportance() > IMPORTANCE_MIN
+                        ? '0' : '1';
                 record.setGlobalSortKey(
                         formatSimple("crtcl=0x%04x:intrsv=%c:grnk=0x%04x:gsmry=%c:%s:rnk=0x%04x",
                         record.getCriticality(),
-                        record.isRecentlyIntrusive()
-                                && record.getImportance() > NotificationManager.IMPORTANCE_MIN
-                                ? '0' : '1',
+                        intrusiveRank,
                         groupProxy.getAuthoritativeRank(),
                         isGroupSummary ? '0' : '1',
                         groupSortKeyPortion,
diff --git a/services/core/java/com/android/server/notification/flags.aconfig b/services/core/java/com/android/server/notification/flags.aconfig
index afd00af..077ed5a 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"
@@ -86,3 +87,11 @@
   description: "This flag controls the polite notification attention behavior updates as per UXR feedback"
   bug: "270456865"
 }
+
+flag {
+  name: "all_notifs_need_ttl"
+  namespace: "systemui"
+  description: "This flag sets a TTL on all notifications that don't already have an app provided one"
+  bug: "331967355"
+}
+
diff --git a/services/core/java/com/android/server/ondeviceintelligence/BundleUtil.java b/services/core/java/com/android/server/ondeviceintelligence/BundleUtil.java
new file mode 100644
index 0000000..681dd0b
--- /dev/null
+++ b/services/core/java/com/android/server/ondeviceintelligence/BundleUtil.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.ondeviceintelligence;
+
+import static android.system.OsConstants.F_GETFL;
+import static android.system.OsConstants.O_ACCMODE;
+import static android.system.OsConstants.O_RDONLY;
+import static android.system.OsConstants.PROT_READ;
+
+import android.app.ondeviceintelligence.IResponseCallback;
+import android.app.ondeviceintelligence.IStreamingResponseCallback;
+import android.app.ondeviceintelligence.ITokenInfoCallback;
+import android.app.ondeviceintelligence.OnDeviceIntelligenceManager.InferenceParams;
+import android.app.ondeviceintelligence.OnDeviceIntelligenceManager.ResponseParams;
+import android.app.ondeviceintelligence.OnDeviceIntelligenceManager.StateParams;
+import android.app.ondeviceintelligence.TokenInfo;
+import android.database.CursorWindow;
+import android.graphics.Bitmap;
+import android.os.BadParcelableException;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+import android.os.SharedMemory;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.util.Log;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Util methods for ensuring the Bundle passed in various methods are read-only and restricted to
+ * some known types.
+ */
+public class BundleUtil {
+    private static final String TAG = "BundleUtil";
+
+    /**
+     * Validation of the inference request payload as described in {@link InferenceParams}
+     * description.
+     *
+     * @throws BadParcelableException when the bundle does not meet the read-only requirements.
+     */
+    public static void sanitizeInferenceParams(
+            @InferenceParams Bundle bundle) {
+        ensureValidBundle(bundle);
+
+        if (!bundle.hasFileDescriptors()) {
+            return; //safe to exit if there are no FDs and Binders
+        }
+
+        for (String key : bundle.keySet()) {
+            Object obj = bundle.get(key);
+            if (obj == null) {
+                /* Null value here could also mean deserializing a custom parcelable has failed,
+                 *  and since {@link Bundle} is marked as defusable in system-server - the
+                 * {@link ClassNotFoundException} exception is swallowed and `null` is returned
+                 * instead. We want to ensure cleanup of null entries in such case.
+                 */
+                bundle.putObject(key, null);
+                continue;
+            }
+            if (canMarshall(obj) || obj instanceof CursorWindow) {
+                continue;
+            }
+
+            if (obj instanceof ParcelFileDescriptor) {
+                validatePfdReadOnly((ParcelFileDescriptor) obj);
+            } else if (obj instanceof SharedMemory) {
+                ((SharedMemory) obj).setProtect(PROT_READ);
+            } else if (obj instanceof Bitmap) {
+                if (((Bitmap) obj).isMutable()) {
+                    throw new BadParcelableException(
+                            "Encountered a mutable Bitmap in the Bundle at key : " + key);
+                }
+            } else {
+                throw new BadParcelableException(
+                        "Unsupported Parcelable type encountered in the Bundle: "
+                                + obj.getClass().getSimpleName());
+            }
+        }
+    }
+
+    /**
+     * Validation of the inference request payload as described in {@link ResponseParams}
+     * description.
+     *
+     * @throws BadParcelableException when the bundle does not meet the read-only requirements.
+     */
+    public static void sanitizeResponseParams(
+            @ResponseParams Bundle bundle) {
+        ensureValidBundle(bundle);
+
+        if (!bundle.hasFileDescriptors()) {
+            return; //safe to exit if there are no FDs and Binders
+        }
+
+        for (String key : bundle.keySet()) {
+            Object obj = bundle.get(key);
+            if (obj == null) {
+                /* Null value here could also mean deserializing a custom parcelable has failed,
+                 *  and since {@link Bundle} is marked as defusable in system-server - the
+                 * {@link ClassNotFoundException} exception is swallowed and `null` is returned
+                 * instead. We want to ensure cleanup of null entries in such case.
+                 */
+                bundle.putObject(key, null);
+                continue;
+            }
+            if (canMarshall(obj)) {
+                continue;
+            }
+
+            if (obj instanceof ParcelFileDescriptor) {
+                validatePfdReadOnly((ParcelFileDescriptor) obj);
+            } else if (obj instanceof Bitmap) {
+                if (((Bitmap) obj).isMutable()) {
+                    throw new BadParcelableException(
+                            "Encountered a mutable Bitmap in the Bundle at key : " + key);
+                }
+            } else {
+                throw new BadParcelableException(
+                        "Unsupported Parcelable type encountered in the Bundle: "
+                                + obj.getClass().getSimpleName());
+            }
+        }
+        Log.e(TAG, "validateResponseParams : Finished");
+    }
+
+    /**
+     * Validation of the inference request payload as described in {@link StateParams}
+     * description.
+     *
+     * @throws BadParcelableException when the bundle does not meet the read-only requirements.
+     */
+    public static void sanitizeStateParams(
+            @StateParams Bundle bundle) {
+        ensureValidBundle(bundle);
+
+        if (!bundle.hasFileDescriptors()) {
+            return; //safe to exit if there are no FDs and Binders
+        }
+
+        for (String key : bundle.keySet()) {
+            Object obj = bundle.get(key);
+            if (obj == null) {
+                /* Null value here could also mean deserializing a custom parcelable has failed,
+                 *  and since {@link Bundle} is marked as defusable in system-server - the
+                 * {@link ClassNotFoundException} exception is swallowed and `null` is returned
+                 * instead. We want to ensure cleanup of null entries in such case.
+                 */
+                bundle.putObject(key, null);
+                continue;
+            }
+            if (canMarshall(obj)) {
+                continue;
+            }
+
+            if (obj instanceof ParcelFileDescriptor) {
+                validatePfdReadOnly((ParcelFileDescriptor) obj);
+            } else {
+                throw new BadParcelableException(
+                        "Unsupported Parcelable type encountered in the Bundle: "
+                                + obj.getClass().getSimpleName());
+            }
+        }
+    }
+
+
+    public static IStreamingResponseCallback wrapWithValidation(
+            IStreamingResponseCallback streamingResponseCallback,
+            Executor resourceClosingExecutor) {
+        return new IStreamingResponseCallback.Stub() {
+            @Override
+            public void onNewContent(Bundle processedResult) throws RemoteException {
+                try {
+                    sanitizeResponseParams(processedResult);
+                    streamingResponseCallback.onNewContent(processedResult);
+                } finally {
+                    resourceClosingExecutor.execute(() -> tryCloseResource(processedResult));
+                }
+            }
+
+            @Override
+            public void onSuccess(Bundle resultBundle)
+                    throws RemoteException {
+                try {
+                    sanitizeResponseParams(resultBundle);
+                    streamingResponseCallback.onSuccess(resultBundle);
+                } finally {
+                    resourceClosingExecutor.execute(() -> tryCloseResource(resultBundle));
+                }
+            }
+
+            @Override
+            public void onFailure(int errorCode, String errorMessage,
+                    PersistableBundle errorParams) throws RemoteException {
+                streamingResponseCallback.onFailure(errorCode, errorMessage, errorParams);
+            }
+
+            @Override
+            public void onDataAugmentRequest(Bundle processedContent,
+                    RemoteCallback remoteCallback)
+                    throws RemoteException {
+                try {
+                    sanitizeResponseParams(processedContent);
+                    streamingResponseCallback.onDataAugmentRequest(processedContent,
+                            new RemoteCallback(
+                                    augmentedData -> {
+                                        try {
+                                            sanitizeInferenceParams(augmentedData);
+                                            remoteCallback.sendResult(augmentedData);
+                                        } finally {
+                                            resourceClosingExecutor.execute(
+                                                    () -> tryCloseResource(augmentedData));
+                                        }
+                                    }));
+                } finally {
+                    resourceClosingExecutor.execute(() -> tryCloseResource(processedContent));
+                }
+            }
+        };
+    }
+
+    public static IResponseCallback wrapWithValidation(IResponseCallback responseCallback,
+            Executor resourceClosingExecutor) {
+        return new IResponseCallback.Stub() {
+            @Override
+            public void onSuccess(Bundle resultBundle)
+                    throws RemoteException {
+                try {
+                    sanitizeResponseParams(resultBundle);
+                    responseCallback.onSuccess(resultBundle);
+                } finally {
+                    resourceClosingExecutor.execute(() -> tryCloseResource(resultBundle));
+                }
+            }
+
+            @Override
+            public void onFailure(int errorCode, String errorMessage,
+                    PersistableBundle errorParams) throws RemoteException {
+                responseCallback.onFailure(errorCode, errorMessage, errorParams);
+            }
+
+            @Override
+            public void onDataAugmentRequest(Bundle processedContent,
+                    RemoteCallback remoteCallback)
+                    throws RemoteException {
+                try {
+                    sanitizeResponseParams(processedContent);
+                    responseCallback.onDataAugmentRequest(processedContent, new RemoteCallback(
+                            augmentedData -> {
+                                try {
+                                    sanitizeInferenceParams(augmentedData);
+                                    remoteCallback.sendResult(augmentedData);
+                                } finally {
+                                    resourceClosingExecutor.execute(
+                                            () -> tryCloseResource(augmentedData));
+                                }
+                            }));
+                } finally {
+                    resourceClosingExecutor.execute(() -> tryCloseResource(processedContent));
+                }
+            }
+        };
+    }
+
+
+    public static ITokenInfoCallback wrapWithValidation(ITokenInfoCallback responseCallback) {
+        return new ITokenInfoCallback.Stub() {
+            @Override
+            public void onSuccess(TokenInfo tokenInfo) throws RemoteException {
+                responseCallback.onSuccess(tokenInfo);
+            }
+
+            @Override
+            public void onFailure(int errorCode, String errorMessage, PersistableBundle errorParams)
+                    throws RemoteException {
+                responseCallback.onFailure(errorCode, errorMessage, errorParams);
+            }
+        };
+    }
+
+    private static boolean canMarshall(Object obj) {
+        return obj instanceof byte[] || obj instanceof PersistableBundle
+                || PersistableBundle.isValidType(obj);
+    }
+
+    private static void ensureValidBundle(Bundle bundle) {
+        if (bundle == null) {
+            throw new IllegalArgumentException("Request passed is expected to be non-null");
+        }
+
+        if (bundle.hasBinders() != Bundle.STATUS_BINDERS_NOT_PRESENT) {
+            throw new BadParcelableException("Bundle should not contain IBinder objects.");
+        }
+    }
+
+    public static void validatePfdReadOnly(ParcelFileDescriptor pfd) {
+        if (pfd == null) {
+            return;
+        }
+        try {
+            int readMode = Os.fcntlInt(pfd.getFileDescriptor(), F_GETFL, 0) & O_ACCMODE;
+            if (readMode != O_RDONLY) {
+                throw new BadParcelableException(
+                        "Bundle contains a parcel file descriptor which is not read-only.");
+            }
+        } catch (ErrnoException e) {
+            throw new BadParcelableException(
+                    "Invalid File descriptor passed in the Bundle.", e);
+        }
+    }
+
+    public static void tryCloseResource(Bundle bundle) {
+        if (bundle == null || bundle.isEmpty() || !bundle.hasFileDescriptors()) {
+            return;
+        }
+
+        for (String key : bundle.keySet()) {
+            Object obj = bundle.get(key);
+
+            try {
+                // TODO(b/329898589) : This can be cleaned up after the flag passing is fixed.
+                if (obj instanceof ParcelFileDescriptor) {
+                    ((ParcelFileDescriptor) obj).close();
+                } else if (obj instanceof CursorWindow) {
+                    ((CursorWindow) obj).close();
+                } else if (obj instanceof SharedMemory) {
+                    // TODO(b/331796886) : Shared memory should honour parcelable flags.
+                    ((SharedMemory) obj).close();
+                }
+            } catch (Exception e) {
+                Log.e(TAG, "Error closing resource with key: " + key, e);
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java b/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
index d39debb..af339df 100644
--- a/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
+++ b/services/core/java/com/android/server/ondeviceintelligence/OnDeviceIntelligenceManagerService.java
@@ -16,6 +16,12 @@
 
 package com.android.server.ondeviceintelligence;
 
+import static com.android.server.ondeviceintelligence.BundleUtil.sanitizeInferenceParams;
+import static com.android.server.ondeviceintelligence.BundleUtil.validatePfdReadOnly;
+import static com.android.server.ondeviceintelligence.BundleUtil.sanitizeStateParams;
+import static com.android.server.ondeviceintelligence.BundleUtil.wrapWithValidation;
+
+
 import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -61,6 +67,7 @@
 import android.service.ondeviceintelligence.OnDeviceIntelligenceService;
 import android.service.ondeviceintelligence.OnDeviceSandboxedInferenceService;
 import android.text.TextUtils;
+import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.R;
@@ -72,8 +79,11 @@
 import com.android.server.SystemService;
 
 import java.io.FileDescriptor;
+import java.io.IOException;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
 
 /**
  * This is the system service for handling calls on the
@@ -99,6 +109,9 @@
     private static final boolean DEFAULT_SERVICE_ENABLED = true;
     private static final String NAMESPACE_ON_DEVICE_INTELLIGENCE = "ondeviceintelligence";
 
+    private final Executor resourceClosingExecutor = Executors.newCachedThreadPool();
+    private final Executor callbackExecutor = Executors.newCachedThreadPool();
+
     private final Context mContext;
     protected final Object mLock = new Object();
 
@@ -261,7 +274,7 @@
                 ensureRemoteIntelligenceServiceInitialized();
                 mRemoteOnDeviceIntelligenceService.run(
                         service -> service.requestFeatureDownload(Binder.getCallingUid(), feature,
-                                cancellationSignalFuture,
+                                wrapCancellationFuture(cancellationSignalFuture),
                                 downloadCallback));
             }
 
@@ -272,26 +285,35 @@
                     AndroidFuture cancellationSignalFuture,
                     ITokenInfoCallback tokenInfoCallback) throws RemoteException {
                 Slog.i(TAG, "OnDeviceIntelligenceManagerInternal requestTokenInfo");
-                Objects.requireNonNull(feature);
-                Objects.requireNonNull(request);
-                Objects.requireNonNull(tokenInfoCallback);
+                AndroidFuture<Void> result = null;
+                try {
+                    Objects.requireNonNull(feature);
+                    sanitizeInferenceParams(request);
+                    Objects.requireNonNull(tokenInfoCallback);
 
-                mContext.enforceCallingOrSelfPermission(
-                        Manifest.permission.USE_ON_DEVICE_INTELLIGENCE, TAG);
-                if (!mIsServiceEnabled) {
-                    Slog.w(TAG, "Service not available");
-                    tokenInfoCallback.onFailure(
-                            OnDeviceIntelligenceException.ON_DEVICE_INTELLIGENCE_SERVICE_UNAVAILABLE,
-                            "OnDeviceIntelligenceManagerService is unavailable",
-                            PersistableBundle.EMPTY);
+                    mContext.enforceCallingOrSelfPermission(
+                            Manifest.permission.USE_ON_DEVICE_INTELLIGENCE, TAG);
+                    if (!mIsServiceEnabled) {
+                        Slog.w(TAG, "Service not available");
+                        tokenInfoCallback.onFailure(
+                                OnDeviceIntelligenceException.ON_DEVICE_INTELLIGENCE_SERVICE_UNAVAILABLE,
+                                "OnDeviceIntelligenceManagerService is unavailable",
+                                PersistableBundle.EMPTY);
+                    }
+                    ensureRemoteInferenceServiceInitialized();
+
+                    result = mRemoteInferenceService.post(
+                            service -> service.requestTokenInfo(Binder.getCallingUid(), feature,
+                                    request,
+                                    wrapCancellationFuture(cancellationSignalFuture),
+                                    wrapWithValidation(tokenInfoCallback)));
+                    result.whenCompleteAsync((c, e) -> BundleUtil.tryCloseResource(request),
+                            resourceClosingExecutor);
+                } finally {
+                    if (result == null) {
+                        resourceClosingExecutor.execute(() -> BundleUtil.tryCloseResource(request));
+                    }
                 }
-                ensureRemoteInferenceServiceInitialized();
-
-                mRemoteInferenceService.run(
-                        service -> service.requestTokenInfo(Binder.getCallingUid(), feature,
-                                request,
-                                cancellationSignalFuture,
-                                tokenInfoCallback));
             }
 
             @Override
@@ -302,24 +324,36 @@
                     AndroidFuture processingSignalFuture,
                     IResponseCallback responseCallback)
                     throws RemoteException {
-                Slog.i(TAG, "OnDeviceIntelligenceManagerInternal processRequest");
-                Objects.requireNonNull(feature);
-                Objects.requireNonNull(responseCallback);
-                mContext.enforceCallingOrSelfPermission(
-                        Manifest.permission.USE_ON_DEVICE_INTELLIGENCE, TAG);
-                if (!mIsServiceEnabled) {
-                    Slog.w(TAG, "Service not available");
-                    responseCallback.onFailure(
-                            OnDeviceIntelligenceException.PROCESSING_ERROR_SERVICE_UNAVAILABLE,
-                            "OnDeviceIntelligenceManagerService is unavailable",
-                            PersistableBundle.EMPTY);
+                AndroidFuture<Void> result = null;
+                try {
+                    Slog.i(TAG, "OnDeviceIntelligenceManagerInternal processRequest");
+                    Objects.requireNonNull(feature);
+                    sanitizeInferenceParams(request);
+                    Objects.requireNonNull(responseCallback);
+                    mContext.enforceCallingOrSelfPermission(
+                            Manifest.permission.USE_ON_DEVICE_INTELLIGENCE, TAG);
+                    if (!mIsServiceEnabled) {
+                        Slog.w(TAG, "Service not available");
+                        responseCallback.onFailure(
+                                OnDeviceIntelligenceException.PROCESSING_ERROR_SERVICE_UNAVAILABLE,
+                                "OnDeviceIntelligenceManagerService is unavailable",
+                                PersistableBundle.EMPTY);
+                    }
+                    ensureRemoteInferenceServiceInitialized();
+                    result = mRemoteInferenceService.post(
+                            service -> service.processRequest(Binder.getCallingUid(), feature,
+                                    request,
+                                    requestType,
+                                    wrapCancellationFuture(cancellationSignalFuture),
+                                    wrapProcessingFuture(processingSignalFuture),
+                                    wrapWithValidation(responseCallback, resourceClosingExecutor)));
+                    result.whenCompleteAsync((c, e) -> BundleUtil.tryCloseResource(request),
+                            resourceClosingExecutor);
+                } finally {
+                    if (result == null) {
+                        resourceClosingExecutor.execute(() -> BundleUtil.tryCloseResource(request));
+                    }
                 }
-                ensureRemoteInferenceServiceInitialized();
-                mRemoteInferenceService.run(
-                        service -> service.processRequest(Binder.getCallingUid(), feature, request,
-                                requestType,
-                                cancellationSignalFuture, processingSignalFuture,
-                                responseCallback));
             }
 
             @Override
@@ -329,24 +363,36 @@
                     AndroidFuture cancellationSignalFuture,
                     AndroidFuture processingSignalFuture,
                     IStreamingResponseCallback streamingCallback) throws RemoteException {
-                Slog.i(TAG, "OnDeviceIntelligenceManagerInternal processRequestStreaming");
-                Objects.requireNonNull(feature);
-                Objects.requireNonNull(streamingCallback);
-                mContext.enforceCallingOrSelfPermission(
-                        Manifest.permission.USE_ON_DEVICE_INTELLIGENCE, TAG);
-                if (!mIsServiceEnabled) {
-                    Slog.w(TAG, "Service not available");
-                    streamingCallback.onFailure(
-                            OnDeviceIntelligenceException.PROCESSING_ERROR_SERVICE_UNAVAILABLE,
-                            "OnDeviceIntelligenceManagerService is unavailable",
-                            PersistableBundle.EMPTY);
+                AndroidFuture<Void> result = null;
+                try {
+                    Slog.i(TAG, "OnDeviceIntelligenceManagerInternal processRequestStreaming");
+                    Objects.requireNonNull(feature);
+                    sanitizeInferenceParams(request);
+                    Objects.requireNonNull(streamingCallback);
+                    mContext.enforceCallingOrSelfPermission(
+                            Manifest.permission.USE_ON_DEVICE_INTELLIGENCE, TAG);
+                    if (!mIsServiceEnabled) {
+                        Slog.w(TAG, "Service not available");
+                        streamingCallback.onFailure(
+                                OnDeviceIntelligenceException.PROCESSING_ERROR_SERVICE_UNAVAILABLE,
+                                "OnDeviceIntelligenceManagerService is unavailable",
+                                PersistableBundle.EMPTY);
+                    }
+                    ensureRemoteInferenceServiceInitialized();
+                    result = mRemoteInferenceService.post(
+                            service -> service.processRequestStreaming(Binder.getCallingUid(),
+                                    feature,
+                                    request, requestType,
+                                    wrapCancellationFuture(cancellationSignalFuture),
+                                    wrapProcessingFuture(processingSignalFuture),
+                                    streamingCallback));
+                    result.whenCompleteAsync((c, e) -> BundleUtil.tryCloseResource(request),
+                            resourceClosingExecutor);
+                } finally {
+                    if (result == null) {
+                        resourceClosingExecutor.execute(() -> BundleUtil.tryCloseResource(request));
+                    }
                 }
-                ensureRemoteInferenceServiceInitialized();
-                mRemoteInferenceService.run(
-                        service -> service.processRequestStreaming(Binder.getCallingUid(), feature,
-                                request, requestType,
-                                cancellationSignalFuture, processingSignalFuture,
-                                streamingCallback));
             }
 
             @Override
@@ -372,9 +418,9 @@
                             public void onConnected(
                                     @NonNull IOnDeviceIntelligenceService service) {
                                 try {
-                                    service.ready();
                                     service.registerRemoteServices(
                                             getRemoteProcessingService());
+                                    service.ready();
                                 } catch (RemoteException ex) {
                                     Slog.w(TAG, "Failed to send connected event", ex);
                                 }
@@ -391,10 +437,24 @@
             public void updateProcessingState(
                     Bundle processingState,
                     IProcessingUpdateStatusCallback callback) {
-                ensureRemoteInferenceServiceInitialized();
-                mRemoteInferenceService.run(
-                        service -> service.updateProcessingState(
-                                processingState, callback));
+                callbackExecutor.execute(() -> {
+                    AndroidFuture<Void> result = null;
+                    try {
+                        sanitizeStateParams(processingState);
+                        ensureRemoteInferenceServiceInitialized();
+                        result = mRemoteInferenceService.post(
+                                service -> service.updateProcessingState(
+                                        processingState, callback));
+                        result.whenCompleteAsync(
+                                (c, e) -> BundleUtil.tryCloseResource(processingState),
+                                resourceClosingExecutor);
+                    } finally {
+                        if (result == null) {
+                            resourceClosingExecutor.execute(
+                                    () -> BundleUtil.tryCloseResource(processingState));
+                        }
+                    }
+                });
             }
         };
     }
@@ -415,7 +475,7 @@
                                 try {
                                     ensureRemoteIntelligenceServiceInitialized();
                                     mRemoteOnDeviceIntelligenceService.run(
-                                            intelligenceService -> intelligenceService.notifyInferenceServiceConnected());
+                                            IOnDeviceIntelligenceService::notifyInferenceServiceConnected);
                                     service.registerRemoteStorageService(
                                             getIRemoteStorageService());
                                 } catch (RemoteException ex) {
@@ -434,18 +494,49 @@
             public void getReadOnlyFileDescriptor(
                     String filePath,
                     AndroidFuture<ParcelFileDescriptor> future) {
+                ensureRemoteIntelligenceServiceInitialized();
+                AndroidFuture<ParcelFileDescriptor> pfdFuture = new AndroidFuture<>();
                 mRemoteOnDeviceIntelligenceService.run(
                         service -> service.getReadOnlyFileDescriptor(
-                                filePath, future));
+                                filePath, pfdFuture));
+                pfdFuture.whenCompleteAsync((pfd, error) -> {
+                    try {
+                        if (error != null) {
+                            future.completeExceptionally(error);
+                        } else {
+                            validatePfdReadOnly(pfd);
+                            future.complete(pfd);
+                        }
+                    } finally {
+                        tryClosePfd(pfd);
+                    }
+                }, callbackExecutor);
             }
 
             @Override
             public void getReadOnlyFeatureFileDescriptorMap(
                     Feature feature,
                     RemoteCallback remoteCallback) {
+                ensureRemoteIntelligenceServiceInitialized();
                 mRemoteOnDeviceIntelligenceService.run(
                         service -> service.getReadOnlyFeatureFileDescriptorMap(
-                                feature, remoteCallback));
+                                feature,
+                                new RemoteCallback(result -> callbackExecutor.execute(() -> {
+                                    try {
+                                        if (result == null) {
+                                            remoteCallback.sendResult(null);
+                                        }
+                                        for (String key : result.keySet()) {
+                                            ParcelFileDescriptor pfd = result.getParcelable(key,
+                                                    ParcelFileDescriptor.class);
+                                            validatePfdReadOnly(pfd);
+                                        }
+                                        remoteCallback.sendResult(result);
+                                    } finally {
+                                        resourceClosingExecutor.execute(
+                                                () -> BundleUtil.tryCloseResource(result));
+                                    }
+                                }))));
             }
         };
     }
@@ -461,7 +552,8 @@
             ServiceInfo serviceInfo = AppGlobals.getPackageManager().getServiceInfo(
                     serviceComponent,
                     PackageManager.MATCH_DIRECT_BOOT_AWARE
-                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, 0);
+                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
+                    UserHandle.SYSTEM.getIdentifier());
             if (serviceInfo != null) {
                 if (!checkIsolated) {
                     checkServiceRequiresPermission(serviceInfo,
@@ -539,10 +631,14 @@
                 Manifest.permission.USE_ON_DEVICE_INTELLIGENCE, TAG);
         synchronized (mLock) {
             mTemporaryServiceNames = componentNames;
-            mRemoteInferenceService.unbind();
-            mRemoteOnDeviceIntelligenceService.unbind();
-            mRemoteOnDeviceIntelligenceService = null;
-            mRemoteInferenceService = null;
+            if (mRemoteInferenceService != null) {
+                mRemoteInferenceService.unbind();
+                mRemoteInferenceService = null;
+            }
+            if (mRemoteOnDeviceIntelligenceService != null) {
+                mRemoteOnDeviceIntelligenceService.unbind();
+                mRemoteOnDeviceIntelligenceService = null;
+            }
             if (mTemporaryHandler == null) {
                 mTemporaryHandler = new Handler(Looper.getMainLooper(), null, true) {
                     @Override
@@ -592,4 +688,57 @@
 
         throw new SecurityException(message + ": Only shell user can call it");
     }
+
+    private AndroidFuture<IBinder> wrapCancellationFuture(
+            AndroidFuture future) {
+        if (future == null) {
+            return null;
+        }
+        AndroidFuture<IBinder> cancellationFuture = new AndroidFuture<>();
+        cancellationFuture.whenCompleteAsync((c, e) -> {
+            if (e != null) {
+                Log.e(TAG, "Error forwarding ICancellationSignal to manager layer", e);
+                future.completeExceptionally(e);
+            } else {
+                future.complete(new ICancellationSignal.Stub() {
+                    @Override
+                    public void cancel() throws RemoteException {
+                        ICancellationSignal.Stub.asInterface(c).cancel();
+                    }
+                });
+            }
+        });
+        return cancellationFuture;
+    }
+
+    private AndroidFuture<IBinder> wrapProcessingFuture(
+            AndroidFuture future) {
+        if (future == null) {
+            return null;
+        }
+        AndroidFuture<IBinder> processingSignalFuture = new AndroidFuture<>();
+        processingSignalFuture.whenCompleteAsync((c, e) -> {
+            if (e != null) {
+                future.completeExceptionally(e);
+            } else {
+                future.complete(new IProcessingSignal.Stub() {
+                    @Override
+                    public void sendSignal(PersistableBundle actionParams) throws RemoteException {
+                        IProcessingSignal.Stub.asInterface(c).sendSignal(actionParams);
+                    }
+                });
+            }
+        });
+        return processingSignalFuture;
+    }
+
+    private static void tryClosePfd(ParcelFileDescriptor pfd) {
+        if (pfd != null) {
+            try {
+                pfd.close();
+            } catch (IOException e) {
+                Log.e(TAG, "Failed to close parcel file descriptor ", e);
+            }
+        }
+    }
 }
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/DefaultCrossProfileIntentFiltersUtils.java b/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
index 017cf55..306f77d 100644
--- a/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
+++ b/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFiltersUtils.java
@@ -25,6 +25,7 @@
 
 import android.content.Intent;
 import android.hardware.usb.UsbManager;
+import android.nfc.NfcAdapter;
 import android.provider.AlarmClock;
 import android.provider.MediaStore;
 
@@ -361,6 +362,7 @@
                     .addCategory(Intent.CATEGORY_DEFAULT)
                     .build();
 
+
     public static List<DefaultCrossProfileIntentFilter> getDefaultManagedProfileFilters() {
         List<DefaultCrossProfileIntentFilter> filters =
                 new ArrayList<DefaultCrossProfileIntentFilter>();
@@ -637,6 +639,33 @@
                     .addDataType("video/*")
                     .build();
 
+    /** NFC TAG intent is always resolved by the primary user. */
+    static final DefaultCrossProfileIntentFilter PARENT_TO_CLONE_NFC_TAG_DISCOVERED =
+            new DefaultCrossProfileIntentFilter.Builder(
+                    DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
+                    /* flags= */0,
+                    /* letsPersonalDataIntoProfile= */ false)
+                    .addAction(NfcAdapter.ACTION_TAG_DISCOVERED)
+                    .build();
+
+    /** NFC TAG intent is always resolved by the primary user. */
+    static final DefaultCrossProfileIntentFilter PARENT_TO_CLONE_NFC_TECH_DISCOVERED =
+            new DefaultCrossProfileIntentFilter.Builder(
+                    DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
+                    /* flags= */0,
+                    /* letsPersonalDataIntoProfile= */ false)
+                    .addAction(NfcAdapter.ACTION_TECH_DISCOVERED)
+                    .build();
+
+    /** NFC TAG intent is always resolved by the primary user. */
+    static final DefaultCrossProfileIntentFilter PARENT_TO_CLONE_NFC_NDEF_DISCOVERED =
+            new DefaultCrossProfileIntentFilter.Builder(
+                    DefaultCrossProfileIntentFilter.Direction.TO_PROFILE,
+                    /* flags= */0,
+                    /* letsPersonalDataIntoProfile= */ false)
+                    .addAction(NfcAdapter.ACTION_NDEF_DISCOVERED)
+                    .build();
+
     public static List<DefaultCrossProfileIntentFilter> getDefaultCloneProfileFilters() {
         return Arrays.asList(
                 PARENT_TO_CLONE_SEND_ACTION,
@@ -652,7 +681,10 @@
                 CLONE_TO_PARENT_SMS_MMS,
                 CLONE_TO_PARENT_PHOTOPICKER_SELECTION,
                 CLONE_TO_PARENT_ACTION_PICK_IMAGES,
-                CLONE_TO_PARENT_ACTION_PICK_IMAGES_WITH_DATA_TYPES
+                CLONE_TO_PARENT_ACTION_PICK_IMAGES_WITH_DATA_TYPES,
+                PARENT_TO_CLONE_NFC_TAG_DISCOVERED,
+                PARENT_TO_CLONE_NFC_TECH_DISCOVERED,
+                PARENT_TO_CLONE_NFC_NDEF_DISCOVERED
         );
     }
 
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 87b1769..2a3b939 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -19,6 +19,7 @@
 import static android.content.pm.Flags.disallowSdkLibsToBeApps;
 import static android.content.pm.PackageManager.APP_METADATA_SOURCE_APK;
 import static android.content.pm.PackageManager.APP_METADATA_SOURCE_INSTALLER;
+import static android.content.pm.PackageManager.APP_METADATA_SOURCE_UNKNOWN;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
@@ -2210,6 +2211,7 @@
                     Map<String, PackageManager.Property> properties = parsedPackage.getProperties();
                     if (Flags.aslInApkAppMetadataSource()
                             && properties.containsKey(PROPERTY_ANDROID_SAFETY_LABEL_PATH)) {
+                        // ASL file extraction is done in post-install
                         ps.setAppMetadataFilePath(appMetadataFile.getAbsolutePath());
                         ps.setAppMetadataSource(APP_METADATA_SOURCE_APK);
                     } else {
@@ -2809,6 +2811,20 @@
         }
 
         if (succeeded) {
+            if (Flags.aslInApkAppMetadataSource()
+                    && pkgSetting.getAppMetadataSource() == APP_METADATA_SOURCE_APK) {
+                if (!PackageManagerServiceUtils.extractAppMetadataFromApk(request.getPkg(),
+                        pkgSetting.getAppMetadataFilePath())) {
+                    synchronized (mPm.mLock) {
+                        PackageSetting setting = mPm.mSettings.getPackageLPr(packageName);
+                        if (setting != null) {
+                            setting.setAppMetadataFilePath(null)
+                                    .setAppMetadataSource(APP_METADATA_SOURCE_UNKNOWN);
+                        }
+                    }
+                }
+            }
+
             // Clear the uid cache after we installed a new package.
             mPm.mPerUidReadTimeoutsCache = null;
 
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 29320ae..a5cd821 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -838,7 +838,8 @@
 
         if ((params.installFlags & PackageManager.INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK) != 0
                 && !PackageManagerServiceUtils.isSystemOrRootOrShell(callingUid)
-                && !Build.IS_DEBUGGABLE) {
+                && !Build.IS_DEBUGGABLE
+                && !PackageManagerServiceUtils.isAdoptedShell(callingUid, mContext)) {
             // If the bypass flag is set, but not running as system root or shell then remove
             // the flag
             params.installFlags &= ~PackageManager.INSTALL_BYPASS_LOW_TARGET_SDK_BLOCK;
diff --git a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
index 7a72e70..d2b60a4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
+++ b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
@@ -16,7 +16,7 @@
 
 package com.android.server.pm;
 
-import static android.app.admin.flags.Flags.crossUserSuspensionEnabled;
+import static android.app.admin.flags.Flags.crossUserSuspensionEnabledRo;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
 import static android.content.pm.PackageManager.RESTRICTION_NONE;
 
@@ -690,7 +690,7 @@
     @Deprecated
     public final void unsuspendAdminSuspendedPackages(int affectedUser) {
         final int suspendingUserId =
-                crossUserSuspensionEnabled() ? UserHandle.USER_SYSTEM : affectedUser;
+                crossUserSuspensionEnabledRo() ? UserHandle.USER_SYSTEM : affectedUser;
         mService.unsuspendForSuspendingPackage(
                 snapshot(), PLATFORM_PACKAGE_NAME, suspendingUserId, /* inAllUsers= */ false);
     }
@@ -699,7 +699,7 @@
     @Deprecated
     public final boolean isAdminSuspendingAnyPackages(int userId) {
         final int suspendingUserId =
-                crossUserSuspensionEnabled() ? UserHandle.USER_SYSTEM : userId;
+                crossUserSuspensionEnabledRo() ? UserHandle.USER_SYSTEM : userId;
         return snapshot().isSuspendingAnyPackages(PLATFORM_PACKAGE_NAME, suspendingUserId, userId);
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 4da280b..68cd3e4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -18,9 +18,7 @@
 import static android.Manifest.permission.MANAGE_DEVICE_ADMINS;
 import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS;
 import static android.app.AppOpsManager.MODE_IGNORED;
-import static android.app.admin.flags.Flags.crossUserSuspensionEnabled;
-import static android.content.pm.PackageManager.APP_METADATA_SOURCE_APK;
-import static android.content.pm.PackageManager.APP_METADATA_SOURCE_UNKNOWN;
+import static android.app.admin.flags.Flags.crossUserSuspensionEnabledRo;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
@@ -3182,7 +3180,7 @@
                     callingMethod);
         }
 
-        if (crossUserSuspensionEnabled()) {
+        if (crossUserSuspensionEnabledRo()) {
             final int suspendingPackageUid =
                     snapshot.getPackageUid(suspender.packageName, 0, suspender.userId);
             if (suspendingPackageUid != callingUid) {
@@ -3220,7 +3218,7 @@
         final String[] allPackages = computer.getPackageStates().keySet().toArray(new String[0]);
         final Predicate<UserPackage> suspenderPredicate =
                 UserPackage.of(suspendingUserId, suspendingPackage)::equals;
-        if (!crossUserSuspensionEnabled() || !inAllUsers) {
+        if (!crossUserSuspensionEnabledRo() || !inAllUsers) {
             mSuspendPackageHelper.removeSuspensionsBySuspendingPackage(computer,
                     allPackages, suspenderPredicate, suspendingUserId);
         } else {
@@ -4366,7 +4364,7 @@
         }
         mInstantAppRegistry.onUserRemoved(userId);
         mPackageMonitorCallbackHelper.onUserRemoved(userId);
-        if (crossUserSuspensionEnabled()) {
+        if (crossUserSuspensionEnabledRo()) {
             cleanUpCrossUserSuspension(userId);
         }
     }
@@ -5232,26 +5230,6 @@
                 return null;
             }
             File file = new File(filePath);
-            if (Flags.aslInApkAppMetadataSource() && !file.exists()
-                    && ps.getAppMetadataSource() == APP_METADATA_SOURCE_APK) {
-                AndroidPackageInternal pkg = ps.getPkg();
-                if (pkg == null) {
-                    Slog.w(TAG, "Unable to to extract app metadata for " + packageName
-                            + ". APK missing from device");
-                    return null;
-                }
-                if (!PackageManagerServiceUtils.extractAppMetadataFromApk(pkg, file)) {
-                    if (file.exists()) {
-                        file.delete();
-                    }
-                    synchronized (mLock) {
-                        PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
-                        pkgSetting.setAppMetadataFilePath(null);
-                        pkgSetting.setAppMetadataSource(APP_METADATA_SOURCE_UNKNOWN);
-                    }
-                    return null;
-                }
-            }
             try {
                 return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
             } catch (FileNotFoundException e) {
@@ -6302,7 +6280,7 @@
             final boolean quarantined = ((flags & PackageManager.FLAG_SUSPEND_QUARANTINED) != 0)
                     && Flags.quarantinedEnabled();
             final Computer snapshot = snapshotComputer();
-            final UserPackage suspender = crossUserSuspensionEnabled()
+            final UserPackage suspender = crossUserSuspensionEnabledRo()
                     ? UserPackage.of(suspendingUserId, suspendingPackage)
                     : UserPackage.of(targetUserId, suspendingPackage);
             enforceCanSetPackagesSuspendedAsUser(snapshot, quarantined, suspender, callingUid,
@@ -6519,7 +6497,19 @@
                 throw new SecurityException("Not allowed to query domain verification agent");
             }
             final Computer snapshot = snapshotComputer();
-            return getDomainVerificationAgentComponentNameLPr(snapshot, userId);
+            final ComponentName agent = mDomainVerificationManager.getProxy().getComponentName();
+            final PackageStateInternal ps = snapshot.getPackageStateForInstalledAndFiltered(
+                    agent.getPackageName(), callerUid, userId);
+            if (ps == null) {
+                return null;
+            }
+            final var disabledComponents =
+                    ps.getUserStateOrDefault(userId).getDisabledComponentsNoCopy();
+            if (disabledComponents != null && disabledComponents.contains(agent.getClassName())) {
+                return null;
+            }
+            // Only return the result if the agent is installed and enabled on the target user
+            return agent;
         }
 
         @Override
@@ -6775,7 +6765,7 @@
             // Suspension by admin isn't attributed to admin package but to the platform,
             // Using USER_SYSTEM for consistency with other internal suspenders, like shell or root.
             final int suspendingUserId =
-                    crossUserSuspensionEnabled() ? UserHandle.USER_SYSTEM : userId;
+                    crossUserSuspensionEnabledRo() ? UserHandle.USER_SYSTEM : userId;
             final UserPackage suspender = UserPackage.of(
                     suspendingUserId, PackageManagerService.PLATFORM_PACKAGE_NAME);
             return mSuspendPackageHelper.setPackagesSuspended(snapshotComputer(), packageNames,
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 110a29c..9484d0d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -1570,7 +1570,12 @@
     /**
      * Extract the app.metadata file from apk.
      */
-    public static boolean extractAppMetadataFromApk(AndroidPackage pkg, File appMetadataFile) {
+    public static boolean extractAppMetadataFromApk(AndroidPackage pkg,
+            String appMetadataFilePath) {
+        if (appMetadataFilePath == null) {
+            return false;
+        }
+        File appMetadataFile = new File(appMetadataFilePath);
         Map<String, Property> properties = pkg.getProperties();
         if (!properties.containsKey(PROPERTY_ANDROID_SAFETY_LABEL_PATH)) {
             return false;
@@ -1596,6 +1601,7 @@
                 }
             } catch (Exception e) {
                 Slog.e(TAG, e.getMessage());
+                appMetadataFile.delete();
             }
         }
         return false;
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 59faf24..1793794 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -28,7 +28,6 @@
 import static android.content.pm.PackageManager.RESTRICTION_NONE;
 
 import static com.android.server.LocalManagerRegistry.ManagerNotFoundException;
-import static com.android.server.pm.PackageManagerService.DEFAULT_FILE_ACCESS_MODE;
 
 import android.accounts.IAccountManager;
 import android.annotation.NonNull;
@@ -45,6 +44,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ArchivedPackageParcel;
 import android.content.pm.FeatureInfo;
+import android.content.pm.Flags;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageInstaller;
 import android.content.pm.IPackageManager;
@@ -3387,6 +3387,18 @@
                     }
                     sessionParams.setEnableRollback(true, rollbackStrategy);
                     break;
+                case "--rollback-impact-level":
+                    if (!Flags.recoverabilityDetection()) {
+                        throw new IllegalArgumentException("Unknown option " + opt);
+                    }
+                    int rollbackImpactLevel = Integer.parseInt(peekNextArg());
+                    if (rollbackImpactLevel < PackageManager.ROLLBACK_USER_IMPACT_LOW
+                            || rollbackImpactLevel
+                                    > PackageManager.ROLLBACK_USER_IMPACT_ONLY_MANUAL) {
+                        throw new IllegalArgumentException(
+                            rollbackImpactLevel + " is not a valid rollback impact level.");
+                    }
+                    sessionParams.setRollbackImpactLevel(rollbackImpactLevel);
                 case "--staged-ready-timeout":
                     params.stagedReadyTimeoutMs = Long.parseLong(getNextArgRequired());
                     break;
@@ -4489,7 +4501,9 @@
         pw.println("      -d: filter to only show disabled packages");
         pw.println("      -e: filter to only show enabled packages");
         pw.println("      -s: filter to only show system packages");
-        pw.println("      -q: filter to only show quarantined packages");
+        if (Flags.quarantinedEnabled()) {
+            pw.println("      -q: filter to only show quarantined packages");
+        }
         pw.println("      -3: filter to only show third party packages");
         pw.println("      -i: see the installer for the packages");
         pw.println("      -l: ignored (used for compatibility with older releases)");
@@ -4569,6 +4583,11 @@
         pw.println("      --full: cause the app to be installed as a non-ephemeral full app");
         pw.println("      --enable-rollback: enable rollbacks for the upgrade.");
         pw.println("          0=restore (default), 1=wipe, 2=retain");
+        if (Flags.recoverabilityDetection()) {
+            pw.println(
+                    "      --rollback-impact-level: set device impact required for rollback.");
+            pw.println("          0=low (default), 1=high, 2=manual only");
+        }
         pw.println("      --install-location: force the install location:");
         pw.println("          0=auto, 1=internal only, 2=prefer external");
         pw.println("      --install-reason: indicates why the app is being installed:");
@@ -4846,8 +4865,10 @@
         pw.println("    to unarchive an app to the responsible installer. Options are:");
         pw.println("      --user: request unarchival of the app from the given user.");
         pw.println("");
-        pw.println("  get-domain-verification-agent");
+        pw.println("  get-domain-verification-agent [--user USER_ID]");
         pw.println("    Displays the component name of the domain verification agent on device.");
+        pw.println("    If the component isn't enabled, an error message will be displayed.");
+        pw.println("      --user: return the agent of the given user (SYSTEM_USER if unspecified)");
         pw.println("");
         printArtServiceHelp();
         pw.println("");
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index b44042c..7870b17 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -16,7 +16,7 @@
 
 package com.android.server.pm;
 
-import static android.app.admin.flags.Flags.crossUserSuspensionEnabled;
+import static android.app.admin.flags.Flags.crossUserSuspensionEnabledRo;
 import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
@@ -1241,7 +1241,7 @@
                 for (int j = 0; j < state.getSuspendParams().size(); j++) {
                     proto.write(PackageProto.UserInfoProto.SUSPENDING_PACKAGE,
                             state.getSuspendParams().keyAt(j).packageName);
-                    if (crossUserSuspensionEnabled()) {
+                    if (crossUserSuspensionEnabledRo()) {
                         proto.write(PackageProto.UserInfoProto.SUSPENDING_USER,
                                 state.getSuspendParams().keyAt(j).userId);
                     }
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index f5ed8d4..0f868eb 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -16,7 +16,7 @@
 
 package com.android.server.pm;
 
-import static android.app.admin.flags.Flags.crossUserSuspensionEnabled;
+import static android.app.admin.flags.Flags.crossUserSuspensionEnabledRo;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
@@ -93,6 +93,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.pm.parsing.pkg.AndroidPackageInternal;
 import com.android.internal.pm.pkg.component.ParsedComponent;
 import com.android.internal.pm.pkg.component.ParsedIntentInfo;
 import com.android.internal.pm.pkg.component.ParsedPermission;
@@ -911,8 +912,10 @@
             sharedUserSetting.mDisabledPackages.remove(p);
         }
         p.getPkgState().setUpdatedSystemApp(false);
+        final AndroidPackageInternal pkg = p.getPkg();
         PackageSetting ret = addPackageLPw(name, p.getRealName(), p.getPath(), p.getAppId(),
-                p.getFlags(), p.getPrivateFlags(), mDomainVerificationManager.generateNewId());
+                p.getFlags(), p.getPrivateFlags(), mDomainVerificationManager.generateNewId(),
+                pkg == null ? false : pkg.isSdkLibrary());
         if (ret != null) {
             ret.setLegacyNativeLibraryPath(p.getLegacyNativeLibraryPath());
             ret.setPrimaryCpuAbi(p.getPrimaryCpuAbiLegacy());
@@ -951,8 +954,8 @@
         }
     }
 
-    PackageSetting addPackageLPw(String name, String realName, File codePath, int uid, int pkgFlags,
-                                 int pkgPrivateFlags, @NonNull UUID domainSetId) {
+    PackageSetting addPackageLPw(String name, String realName, File codePath, int uid,
+            int pkgFlags, int pkgPrivateFlags, @NonNull UUID domainSetId, boolean isSdkLibrary) {
         PackageSetting p = mPackages.get(name);
         if (p != null) {
             if (p.getAppId() == uid) {
@@ -964,7 +967,8 @@
         }
         p = new PackageSetting(name, realName, codePath, pkgFlags, pkgPrivateFlags, domainSetId)
                 .setAppId(uid);
-        if (mAppIds.registerExistingAppId(uid, p, name)) {
+        if ((uid == Process.INVALID_UID && isSdkLibrary && Flags.disallowSdkLibsToBeApps())
+                || mAppIds.registerExistingAppId(uid, p, name)) {
             mPackages.put(name, p);
             return p;
         }
@@ -2054,7 +2058,7 @@
             return null;
         }
         int suspendingUserId;
-        if (crossUserSuspensionEnabled()) {
+        if (crossUserSuspensionEnabledRo()) {
             suspendingUserId = parser.getAttributeInt(
                     null, ATTR_SUSPENDING_USER, UserHandle.USER_NULL);
             if (suspendingUserId == UserHandle.USER_NULL) {
@@ -2433,7 +2437,7 @@
                                 serializer.startTag(null, TAG_SUSPEND_PARAMS);
                                 serializer.attribute(null, ATTR_SUSPENDING_PACKAGE,
                                         suspendingPackage.packageName);
-                                if (crossUserSuspensionEnabled()) {
+                                if (crossUserSuspensionEnabledRo()) {
                                     serializer.attributeInt(null, ATTR_SUSPENDING_USER,
                                             suspendingPackage.userId);
                                 }
@@ -4176,7 +4180,7 @@
             } else if (appId > 0 || (appId == Process.INVALID_UID && isSdkLibrary
                     && Flags.disallowSdkLibsToBeApps())) {
                 packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
-                        appId, pkgFlags, pkgPrivateFlags, domainSetId);
+                        appId, pkgFlags, pkgPrivateFlags, domainSetId, isSdkLibrary);
                 if (PackageManagerService.DEBUG_SETTINGS)
                     Log.i(PackageManagerService.TAG, "Reading package " + name + ": appId="
                             + appId + " pkg=" + packageSetting);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index f5ac830..ff41245 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -567,7 +567,7 @@
                     int autoLockPreference =
                             Settings.Secure.getIntForUser(mContext.getContentResolver(),
                                     Settings.Secure.PRIVATE_SPACE_AUTO_LOCK,
-                                    Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_NEVER,
+                                    Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_AFTER_DEVICE_RESTART,
                                     getMainUserIdUnchecked());
                     Slog.i(LOG_TAG, "Auto-lock settings changed to " + autoLockPreference);
                     setOrUpdateAutoLockPreferenceForPrivateProfile(autoLockPreference);
@@ -615,7 +615,7 @@
         int privateSpaceAutoLockPreference =
                 Settings.Secure.getIntForUser(mContext.getContentResolver(),
                         Settings.Secure.PRIVATE_SPACE_AUTO_LOCK,
-                        Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_NEVER,
+                        Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_AFTER_DEVICE_RESTART,
                         getMainUserIdUnchecked());
         if (privateSpaceAutoLockPreference
                 != Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_AFTER_INACTIVITY) {
@@ -714,7 +714,7 @@
         if (isAutoLockForPrivateSpaceEnabled()) {
             int autoLockPreference = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                     Settings.Secure.PRIVATE_SPACE_AUTO_LOCK,
-                    Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_NEVER,
+                    Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_AFTER_DEVICE_RESTART,
                     getMainUserIdUnchecked());
             boolean isAutoLockOnDeviceLockSelected =
                     autoLockPreference == Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_ON_DEVICE_LOCK;
@@ -1052,7 +1052,8 @@
                 setOrUpdateAutoLockPreferenceForPrivateProfile(
                         Settings.Secure.getIntForUser(mContext.getContentResolver(),
                                 Settings.Secure.PRIVATE_SPACE_AUTO_LOCK,
-                                Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_NEVER, mainUserId));
+                                Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_AFTER_DEVICE_RESTART,
+                                mainUserId));
             }
         }
 
@@ -1718,10 +1719,11 @@
                     }
 
                     final KeyguardManager km = mContext.getSystemService(KeyguardManager.class);
-                    if (km != null && km.isDeviceSecure()) {
+                    int parentUserId = getProfileParentId(userId);
+                    if (km != null && km.isDeviceSecure(parentUserId)) {
                         showConfirmCredentialToDisableQuietMode(userId, target, callingPackage);
                         return false;
-                    } else if (km != null && !km.isDeviceSecure()
+                    } else if (km != null && !km.isDeviceSecure(parentUserId)
                             && android.multiuser.Flags.showSetScreenLockDialog()
                             // TODO(b/330720545): Add a better way to accomplish this, also use it
                             //  to block profile creation w/o device credentials present.
@@ -1731,7 +1733,8 @@
                                 SetScreenLockDialogActivity
                                         .createBaseIntent(LAUNCH_REASON_DISABLE_QUIET_MODE);
                         setScreenLockPromptIntent.putExtra(EXTRA_ORIGIN_USER_ID, userId);
-                        mContext.startActivity(setScreenLockPromptIntent);
+                        mContext.startActivityAsUser(setScreenLockPromptIntent,
+                                UserHandle.of(parentUserId));
                         return false;
                     } else {
                         Slog.w(LOG_TAG, "Allowing profile unlock even when device credentials "
diff --git a/services/core/java/com/android/server/pm/UserTypeFactory.java b/services/core/java/com/android/server/pm/UserTypeFactory.java
index 7f9c1cf..33b5a70 100644
--- a/services/core/java/com/android/server/pm/UserTypeFactory.java
+++ b/services/core/java/com/android/server/pm/UserTypeFactory.java
@@ -327,7 +327,8 @@
                                 UserProperties.CROSS_PROFILE_CONTENT_SHARING_DELEGATE_FROM_PARENT)
                         .setProfileApiVisibility(
                                 UserProperties.PROFILE_API_VISIBILITY_HIDDEN)
-                        .setItemsRestrictedOnHomeScreen(true));
+                        .setItemsRestrictedOnHomeScreen(true)
+                        .setUpdateCrossProfileIntentFiltersOnOTA(true));
     }
 
     /**
diff --git a/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java b/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java
new file mode 100644
index 0000000..3edd697
--- /dev/null
+++ b/services/core/java/com/android/server/pm/permission/AccessCheckDelegate.java
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm.permission;
+
+import static android.os.Process.INVALID_UID;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.AppOpsManager;
+import android.app.AppOpsManager.AttributionFlags;
+import android.app.AppOpsManagerInternal.CheckOpsDelegate;
+import android.app.SyncNotedAppOp;
+import android.content.AttributionSource;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.SparseArray;
+
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.function.DodecFunction;
+import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.OctFunction;
+import com.android.internal.util.function.QuadFunction;
+import com.android.internal.util.function.TriFunction;
+import com.android.internal.util.function.UndecFunction;
+import com.android.server.LocalServices;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.CheckPermissionDelegate;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Interface to intercept incoming parameters and outgoing results to permission and appop checks
+ */
+public interface AccessCheckDelegate extends CheckPermissionDelegate, CheckOpsDelegate {
+
+    /**
+     * Assigns the package whose permissions are delegated the state of Shell's permissions.
+     *
+     * @param delegateUid the UID whose permissions are delegated to shell
+     * @param packageName the name of the package whose permissions are delegated to shell
+     * @param permissions the set of permissions to delegate to shell. If null then all
+     *                    permission will be delegated
+     */
+    void setShellPermissionDelegate(int delegateUid, @NonNull String packageName,
+            @Nullable String[] permissions);
+
+    /**
+     * Removes the assigned Shell permission delegate.
+     */
+    void removeShellPermissionDelegate();
+
+    /**
+     * @return a list of permissions delegated to Shell's permission state
+     */
+    @NonNull
+    List<String> getDelegatedPermissionNames();
+
+    /**
+     * @return whether there exists a Shell permission delegate
+     */
+    boolean hasShellPermissionDelegate();
+
+    /**
+     * @param uid the UID to check
+     * @return whether the UID's permissions are delegated to Shell's and the owner of overrides
+     */
+    boolean isDelegateAndOwnerUid(int uid);
+
+    /**
+     * @param uid the UID to check
+     * @param packageName the package to check
+     * @return whether the UID and package combination's permissions are delegated to Shell's
+     * permissions
+     */
+    boolean isDelegatePackage(int uid, @NonNull String packageName);
+
+    /**
+     * Adds permission to be overridden to the given state.
+     *
+     * @param ownerUid the UID of the app who assigned the permission override
+     * @param uid The UID of the app whose permission will be overridden
+     * @param permission The permission whose state will be overridden
+     * @param result The state to override the permission to
+     */
+    void addOverridePermissionState(int ownerUid, int uid, @NonNull String permission,
+            int result);
+
+    /**
+     * Removes overridden permission. UiAutomation must be connected to root user.
+     *
+     * @param uid The UID of the app whose permission is overridden
+     * @param permission The permission whose state will no longer be overridden
+     *
+     * @hide
+     */
+    void removeOverridePermissionState(int uid, @NonNull String permission);
+
+    /**
+     * Clears all overridden permissions for the given UID.
+     *
+     * @param uid The UID of the app whose permissions will no longer be overridden
+     */
+    void clearOverridePermissionStates(int uid);
+
+    /**
+     * Clears all overridden permissions on the device.
+     */
+    void clearAllOverridePermissionStates();
+
+    /**
+     * @return whether there exists any permission overrides
+     */
+    boolean hasOverriddenPermissions();
+
+    /**
+     * @return whether there exists permissions delegated to Shell's permissions or overridden
+     */
+    boolean hasDelegateOrOverrides();
+
+    class AccessCheckDelegateImpl implements AccessCheckDelegate {
+        public static final String SHELL_PKG = "com.android.shell";
+        private int mDelegateAndOwnerUid = INVALID_UID;
+        @Nullable
+        private String mDelegatePackage;
+        @Nullable
+        private String[] mDelegatePermissions;
+        boolean mDelegateAllPermissions;
+        @Nullable
+        private SparseArray<ArrayMap<String, Integer>> mOverridePermissionStates;
+
+        @Override
+        public void setShellPermissionDelegate(int uid, @NonNull String packageName,
+                @Nullable String[] permissions) {
+            mDelegateAndOwnerUid = uid;
+            mDelegatePackage = packageName;
+            mDelegatePermissions = permissions;
+            mDelegateAllPermissions = permissions == null;
+            PackageManager.invalidatePackageInfoCache();
+        }
+
+        @Override
+        public void removeShellPermissionDelegate() {
+            mDelegatePackage = null;
+            mDelegatePermissions = null;
+            mDelegateAllPermissions = false;
+            PackageManager.invalidatePackageInfoCache();
+        }
+
+        @Override
+        public void addOverridePermissionState(int ownerUid, int uid, @NonNull String permission,
+                int state) {
+            if (mOverridePermissionStates == null) {
+                mDelegateAndOwnerUid = ownerUid;
+                mOverridePermissionStates = new SparseArray<>();
+            }
+
+            int uidIdx = mOverridePermissionStates.indexOfKey(uid);
+            ArrayMap<String, Integer> perUidOverrides;
+            if (uidIdx < 0) {
+                perUidOverrides = new ArrayMap<>();
+                mOverridePermissionStates.put(uid, perUidOverrides);
+            } else {
+                perUidOverrides = mOverridePermissionStates.valueAt(uidIdx);
+            }
+
+            perUidOverrides.put(permission, state);
+            PackageManager.invalidatePackageInfoCache();
+        }
+
+        @Override
+        public void removeOverridePermissionState(int uid, @NonNull String permission) {
+            if (mOverridePermissionStates == null) {
+                return;
+            }
+
+            ArrayMap<String, Integer> perUidOverrides = mOverridePermissionStates.get(uid);
+
+            if (perUidOverrides == null) {
+                return;
+            }
+
+            perUidOverrides.remove(permission);
+            PackageManager.invalidatePackageInfoCache();
+
+            if (perUidOverrides.isEmpty()) {
+                mOverridePermissionStates.remove(uid);
+            }
+            if (mOverridePermissionStates.size() == 0) {
+                mOverridePermissionStates = null;
+            }
+        }
+
+        @Override
+        public void clearOverridePermissionStates(int uid) {
+            if (mOverridePermissionStates == null) {
+                return;
+            }
+
+            mOverridePermissionStates.remove(uid);
+            PackageManager.invalidatePackageInfoCache();
+
+            if (mOverridePermissionStates.size() == 0) {
+                mOverridePermissionStates = null;
+            }
+        }
+
+        @Override
+        public void clearAllOverridePermissionStates() {
+            mOverridePermissionStates = null;
+            PackageManager.invalidatePackageInfoCache();
+        }
+
+        @Override
+        public List<String> getDelegatedPermissionNames() {
+            return mDelegatePermissions == null ? null : List.of(mDelegatePermissions);
+        }
+
+        @Override
+        public boolean hasShellPermissionDelegate() {
+            return mDelegateAllPermissions || mDelegatePermissions != null;
+        }
+
+        @Override
+        public boolean isDelegatePackage(int uid, @NonNull String packageName) {
+            return mDelegateAndOwnerUid == uid && TextUtils.equals(mDelegatePackage, packageName);
+        }
+
+        @Override
+        public boolean hasOverriddenPermissions() {
+            return mOverridePermissionStates != null;
+        }
+
+        @Override
+        public boolean isDelegateAndOwnerUid(int uid) {
+            return uid == mDelegateAndOwnerUid;
+        }
+
+        @Override
+        public boolean hasDelegateOrOverrides() {
+            return hasShellPermissionDelegate() || hasOverriddenPermissions();
+        }
+
+        @Override
+        public int checkPermission(@NonNull String packageName, @NonNull String permissionName,
+                @NonNull String persistentDeviceId, @UserIdInt int userId,
+                @NonNull QuadFunction<String, String, String, Integer, Integer> superImpl) {
+            if (TextUtils.equals(mDelegatePackage, packageName) && !SHELL_PKG.equals(packageName)) {
+                if (isDelegatePermission(permissionName)) {
+                    final long identity = Binder.clearCallingIdentity();
+                    try {
+                        return checkPermission(SHELL_PKG, permissionName,
+                                persistentDeviceId, userId, superImpl);
+                    } finally {
+                        Binder.restoreCallingIdentity(identity);
+                    }
+                }
+            }
+            if (mOverridePermissionStates != null) {
+                int uid = LocalServices.getService(PackageManagerInternal.class)
+                                .getPackageUid(packageName, 0, userId);
+                if (uid >= 0) {
+                    Map<String, Integer> permissionGrants = mOverridePermissionStates.get(uid);
+                    if (permissionGrants != null && permissionGrants.containsKey(permissionName)) {
+                        return permissionGrants.get(permissionName);
+                    }
+                }
+            }
+            return superImpl.apply(packageName, permissionName, persistentDeviceId, userId);
+        }
+
+        @Override
+        public int checkUidPermission(int uid, @NonNull String permissionName,
+                @NonNull String persistentDeviceId,
+                @NonNull TriFunction<Integer, String, String, Integer> superImpl) {
+            if (uid == mDelegateAndOwnerUid && uid != Process.SHELL_UID) {
+                if (isDelegatePermission(permissionName)) {
+                    final long identity = Binder.clearCallingIdentity();
+                    try {
+                        return checkUidPermission(Process.SHELL_UID, permissionName,
+                                persistentDeviceId, superImpl);
+                    } finally {
+                        Binder.restoreCallingIdentity(identity);
+                    }
+                }
+            }
+            if (mOverridePermissionStates != null) {
+                Map<String, Integer> permissionGrants = mOverridePermissionStates.get(uid);
+                if (permissionGrants != null && permissionGrants.containsKey(permissionName)) {
+                    return permissionGrants.get(permissionName);
+                }
+            }
+            return superImpl.apply(uid, permissionName, persistentDeviceId);
+        }
+
+        @Override
+        public int checkOperation(int code, int uid, @Nullable String packageName,
+                @Nullable String attributionTag, int virtualDeviceId, boolean raw,
+                @NonNull HexFunction<Integer, Integer, String, String, Integer, Boolean, Integer>
+                        superImpl) {
+            if (uid == mDelegateAndOwnerUid && isDelegateOp(code)) {
+                final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
+                        Process.SHELL_UID);
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return superImpl.apply(code, shellUid, "com.android.shell", null,
+                            virtualDeviceId, raw);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return superImpl.apply(code, uid, packageName, attributionTag, virtualDeviceId, raw);
+        }
+
+        @Override
+        public int checkAudioOperation(int code, int usage, int uid, @Nullable String packageName,
+                @NonNull QuadFunction<Integer, Integer, Integer, String, Integer> superImpl) {
+            if (uid == mDelegateAndOwnerUid && isDelegateOp(code)) {
+                final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
+                        Process.SHELL_UID);
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return superImpl.apply(code, usage, shellUid, "com.android.shell");
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return superImpl.apply(code, usage, uid, packageName);
+        }
+
+        @Override
+        public SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
+                @Nullable String featureId, int virtualDeviceId, boolean shouldCollectAsyncNotedOp,
+                @Nullable String message, boolean shouldCollectMessage,
+                @NonNull OctFunction<Integer, Integer, String, String, Integer, Boolean, String,
+                        Boolean, SyncNotedAppOp> superImpl) {
+            if (uid == mDelegateAndOwnerUid && isDelegateOp(code)) {
+                final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
+                        Process.SHELL_UID);
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return superImpl.apply(code, shellUid, "com.android.shell", featureId,
+                            virtualDeviceId, shouldCollectAsyncNotedOp, message,
+                            shouldCollectMessage);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return superImpl.apply(code, uid, packageName, featureId, virtualDeviceId,
+                    shouldCollectAsyncNotedOp, message, shouldCollectMessage);
+        }
+
+        @Override
+        public SyncNotedAppOp noteProxyOperation(int code,
+                @NonNull AttributionSource attributionSource, boolean shouldCollectAsyncNotedOp,
+                @Nullable String message, boolean shouldCollectMessage, boolean skiProxyOperation,
+                @NonNull HexFunction<Integer, AttributionSource, Boolean, String, Boolean,
+                        Boolean, SyncNotedAppOp> superImpl) {
+            if (attributionSource.getUid() == mDelegateAndOwnerUid && isDelegateOp(code)) {
+                final int shellUid = UserHandle.getUid(
+                        UserHandle.getUserId(attributionSource.getUid()), Process.SHELL_UID);
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return superImpl.apply(code,
+                            new AttributionSource(shellUid, Process.INVALID_PID,
+                                    "com.android.shell", attributionSource.getAttributionTag(),
+                                    attributionSource.getToken(), /*renouncedPermissions*/ null,
+                                    attributionSource.getDeviceId(), attributionSource.getNext()),
+                            shouldCollectAsyncNotedOp, message, shouldCollectMessage,
+                            skiProxyOperation);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return superImpl.apply(code, attributionSource, shouldCollectAsyncNotedOp,
+                    message, shouldCollectMessage, skiProxyOperation);
+        }
+
+        @Override
+        public SyncNotedAppOp startOperation(@NonNull IBinder token, int code, int uid,
+                @Nullable String packageName, @Nullable String attributionTag, int virtualDeviceId,
+                boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
+                @Nullable String message, boolean shouldCollectMessage,
+                @AttributionFlags int attributionFlags, int attributionChainId,
+                @NonNull DodecFunction<IBinder, Integer, Integer, String, String, Integer, Boolean,
+                        Boolean, String, Boolean, Integer, Integer, SyncNotedAppOp> superImpl) {
+            if (uid == mDelegateAndOwnerUid && isDelegateOp(code)) {
+                final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
+                        Process.SHELL_UID);
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return superImpl.apply(token, code, shellUid, "com.android.shell",
+                            attributionTag, virtualDeviceId, startIfModeDefault,
+                            shouldCollectAsyncNotedOp, message, shouldCollectMessage,
+                            attributionFlags, attributionChainId);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return superImpl.apply(token, code, uid, packageName, attributionTag, virtualDeviceId,
+                    startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
+                    attributionFlags, attributionChainId);
+        }
+
+        @Override
+        public SyncNotedAppOp startProxyOperation(@NonNull IBinder clientId, int code,
+                @NonNull AttributionSource attributionSource, boolean startIfModeDefault,
+                boolean shouldCollectAsyncNotedOp, @Nullable String message,
+                boolean shouldCollectMessage, boolean skipProxyOperation,
+                @AttributionFlags int proxyAttributionFlags,
+                @AttributionFlags int proxiedAttributionFlags, int attributionChainId,
+                @NonNull UndecFunction<IBinder, Integer, AttributionSource, Boolean,
+                        Boolean, String, Boolean, Boolean, Integer, Integer, Integer,
+                        SyncNotedAppOp> superImpl) {
+            if (attributionSource.getUid() == mDelegateAndOwnerUid && isDelegateOp(code)) {
+                final int shellUid = UserHandle.getUid(UserHandle.getUserId(
+                        attributionSource.getUid()), Process.SHELL_UID);
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    return superImpl.apply(clientId, code,
+                            new AttributionSource(shellUid, Process.INVALID_PID,
+                                    "com.android.shell", attributionSource.getAttributionTag(),
+                                    attributionSource.getToken(), /*renouncedPermissions*/ null,
+                                    attributionSource.getDeviceId(), attributionSource.getNext()),
+                            startIfModeDefault, shouldCollectAsyncNotedOp, message,
+                            shouldCollectMessage, skipProxyOperation, proxyAttributionFlags,
+                            proxiedAttributionFlags, attributionChainId);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            return superImpl.apply(clientId, code, attributionSource, startIfModeDefault,
+                    shouldCollectAsyncNotedOp, message, shouldCollectMessage, skipProxyOperation,
+                    proxyAttributionFlags, proxiedAttributionFlags, attributionChainId);
+        }
+
+        @Override
+        public void finishProxyOperation(@NonNull IBinder clientId, int code,
+                @NonNull AttributionSource attributionSource, boolean skipProxyOperation,
+                @NonNull QuadFunction<IBinder, Integer, AttributionSource, Boolean,
+                        Void> superImpl) {
+            if (attributionSource.getUid() == mDelegateAndOwnerUid && isDelegateOp(code)) {
+                final int shellUid = UserHandle.getUid(UserHandle.getUserId(
+                        attributionSource.getUid()), Process.SHELL_UID);
+                final long identity = Binder.clearCallingIdentity();
+                try {
+                    superImpl.apply(clientId, code,
+                            new AttributionSource(shellUid, Process.INVALID_PID,
+                                    "com.android.shell", attributionSource.getAttributionTag(),
+                                    attributionSource.getToken(), /*renouncedPermissions*/ null,
+                                    attributionSource.getDeviceId(), attributionSource.getNext()),
+                            skipProxyOperation);
+                } finally {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+            superImpl.apply(clientId, code, attributionSource, skipProxyOperation);
+        }
+
+        private boolean isDelegatePermission(@NonNull String permission) {
+            // null permissions means all permissions are delegated
+            return mDelegateAndOwnerUid != INVALID_UID
+                    && (mDelegateAllPermissions
+                    || ArrayUtils.contains(mDelegatePermissions, permission));
+        }
+
+        private boolean isDelegateOp(int code) {
+            if (mDelegateAllPermissions) {
+                return true;
+            }
+            // no permission for the op means the op is targeted
+            final String permission = AppOpsManager.opToPermission(code);
+            if (permission == null) {
+                return true;
+            }
+            return isDelegatePermission(permission);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 21e2bf2..bd0501d 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -76,11 +76,10 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.Preconditions;
-import com.android.internal.util.function.QuadFunction;
-import com.android.internal.util.function.TriFunction;
 import com.android.server.LocalServices;
 import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
 import com.android.server.pm.UserManagerService;
+import com.android.server.pm.permission.PermissionManagerServiceInternal.CheckPermissionDelegate;
 import com.android.server.pm.permission.PermissionManagerServiceInternal.HotwordDetectionServiceProvider;
 import com.android.server.pm.pkg.AndroidPackage;
 import com.android.server.pm.pkg.PackageState;
@@ -88,7 +87,6 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
@@ -323,6 +321,12 @@
         return true;
     }
 
+    private void setCheckPermissionDelegateInternal(CheckPermissionDelegate delegate) {
+        synchronized (mLock) {
+            mCheckPermissionDelegate = delegate;
+        }
+    }
+
     private boolean checkAutoRevokeAccess(AndroidPackage pkg, int callingUid) {
         final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
                 Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS)
@@ -369,42 +373,6 @@
         }
     }
 
-    private void startShellPermissionIdentityDelegationInternal(int uid,
-            @NonNull String packageName, @Nullable List<String> permissionNames) {
-        synchronized (mLock) {
-            final CheckPermissionDelegate oldDelegate = mCheckPermissionDelegate;
-            if (oldDelegate != null && oldDelegate.getDelegatedUid() != uid) {
-                throw new SecurityException(
-                        "Shell can delegate permissions only to one UID at a time");
-            }
-            final ShellDelegate delegate = new ShellDelegate(uid, packageName, permissionNames);
-            setCheckPermissionDelegateLocked(delegate);
-        }
-    }
-
-    private void stopShellPermissionIdentityDelegationInternal() {
-        synchronized (mLock) {
-            setCheckPermissionDelegateLocked(null);
-        }
-    }
-
-    @Nullable
-    private List<String> getDelegatedShellPermissionsInternal() {
-        synchronized (mLock) {
-            if (mCheckPermissionDelegate == null) {
-                return Collections.EMPTY_LIST;
-            }
-            return mCheckPermissionDelegate.getDelegatedPermissionNames();
-        }
-    }
-
-    private void setCheckPermissionDelegateLocked(@Nullable CheckPermissionDelegate delegate) {
-        if (delegate != null || mCheckPermissionDelegate != null) {
-            PackageManager.invalidatePackageInfoCache();
-        }
-        mCheckPermissionDelegate = delegate;
-    }
-
     @NonNull
     private OneTimePermissionUserManager getOneTimePermissionUserManager(@UserIdInt int userId) {
         OneTimePermissionUserManager oneTimePermissionUserManager;
@@ -663,24 +631,6 @@
         }
 
         @Override
-        public void startShellPermissionIdentityDelegation(int uid, @NonNull String packageName,
-                @Nullable List<String> permissionNames) {
-            Objects.requireNonNull(packageName, "packageName");
-            startShellPermissionIdentityDelegationInternal(uid, packageName, permissionNames);
-        }
-
-        @Override
-        public void stopShellPermissionIdentityDelegation() {
-            stopShellPermissionIdentityDelegationInternal();
-        }
-
-        @Override
-        @NonNull
-        public List<String> getDelegatedShellPermissions() {
-            return getDelegatedShellPermissionsInternal();
-        }
-
-        @Override
         public void setHotwordDetectionServiceProvider(HotwordDetectionServiceProvider provider) {
             mHotwordDetectionServiceProvider = provider;
         }
@@ -891,6 +841,11 @@
                     .getAllPermissionsWithProtectionFlags(protectionFlags);
         }
 
+        @Override
+        public void setCheckPermissionDelegate(CheckPermissionDelegate delegate) {
+            setCheckPermissionDelegateInternal(delegate);
+        }
+
         /* End of delegate methods to PermissionManagerServiceInterface */
     }
 
@@ -902,120 +857,6 @@
     private int[] getAllUserIds() {
         return UserManagerService.getInstance().getUserIdsIncludingPreCreated();
     }
-
-    /**
-     * Interface to intercept permission checks and optionally pass through to the original
-     * implementation.
-     */
-    private interface CheckPermissionDelegate {
-        /**
-         * Get the UID whose permission checks is being delegated.
-         *
-         * @return the UID
-         */
-        int getDelegatedUid();
-
-        /**
-         * Check whether the given package has been granted the specified permission.
-         *
-         * @param packageName the name of the package to be checked
-         * @param permissionName the name of the permission to be checked
-         * @param persistentDeviceId The persistent device ID
-         * @param userId the user ID
-         * @param superImpl the original implementation that can be delegated to
-         * @return {@link android.content.pm.PackageManager#PERMISSION_GRANTED} if the package has
-         * the permission, or {@link android.content.pm.PackageManager#PERMISSION_DENIED} otherwise
-         *
-         * @see android.content.pm.PackageManager#checkPermission(String, String)
-         */
-        int checkPermission(@NonNull String packageName, @NonNull String permissionName,
-                String persistentDeviceId, @UserIdInt int userId,
-                @NonNull QuadFunction<String, String, String, Integer, Integer> superImpl);
-
-        /**
-         * Check whether the given UID has been granted the specified permission.
-         *
-         * @param uid the UID to be checked
-         * @param permissionName the name of the permission to be checked
-         * @param persistentDeviceId The persistent device ID
-         * @param superImpl the original implementation that can be delegated to
-         * @return {@link android.content.pm.PackageManager#PERMISSION_GRANTED} if the package has
-         * the permission, or {@link android.content.pm.PackageManager#PERMISSION_DENIED} otherwise
-         */
-        int checkUidPermission(int uid, @NonNull String permissionName, String persistentDeviceId,
-                TriFunction<Integer, String, String, Integer> superImpl);
-
-        /**
-         * @return list of delegated permissions
-         */
-        List<String> getDelegatedPermissionNames();
-    }
-
-    private class ShellDelegate implements CheckPermissionDelegate {
-        private final int mDelegatedUid;
-        @NonNull
-        private final String mDelegatedPackageName;
-        @Nullable
-        private final List<String> mDelegatedPermissionNames;
-
-        public ShellDelegate(int delegatedUid, @NonNull String delegatedPackageName,
-                @Nullable List<String> delegatedPermissionNames) {
-            mDelegatedUid = delegatedUid;
-            mDelegatedPackageName = delegatedPackageName;
-            mDelegatedPermissionNames = delegatedPermissionNames;
-        }
-
-        @Override
-        public int getDelegatedUid() {
-            return mDelegatedUid;
-        }
-
-        @Override
-        public int checkPermission(@NonNull String packageName, @NonNull String permissionName,
-                String persistentDeviceId, int userId,
-                @NonNull QuadFunction<String, String, String, Integer, Integer> superImpl) {
-            if (mDelegatedPackageName.equals(packageName)
-                    && isDelegatedPermission(permissionName)) {
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    return superImpl.apply("com.android.shell", permissionName, persistentDeviceId,
-                            userId);
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-            return superImpl.apply(packageName, permissionName, persistentDeviceId, userId);
-        }
-
-        @Override
-        public int checkUidPermission(int uid, @NonNull String permissionName,
-                String persistentDeviceId,
-                @NonNull TriFunction<Integer, String, String, Integer> superImpl) {
-            if (uid == mDelegatedUid && isDelegatedPermission(permissionName)) {
-                final long identity = Binder.clearCallingIdentity();
-                try {
-                    return superImpl.apply(Process.SHELL_UID, permissionName, persistentDeviceId);
-                } finally {
-                    Binder.restoreCallingIdentity(identity);
-                }
-            }
-            return superImpl.apply(uid, permissionName, persistentDeviceId);
-        }
-
-        @Override
-        public List<String> getDelegatedPermissionNames() {
-            return mDelegatedPermissionNames == null
-                    ? null
-                    : new ArrayList<>(mDelegatedPermissionNames);
-        }
-
-        private boolean isDelegatedPermission(@NonNull String permissionName) {
-            // null permissions means all permissions are targeted
-            return mDelegatedPermissionNames == null
-                    || mDelegatedPermissionNames.contains(permissionName);
-        }
-    }
-
     private static final class AttributionSourceRegistry {
         private final Object mLock = new Object();
 
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
index 132cdce..a5c1284 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
@@ -25,6 +25,8 @@
 import android.permission.PermissionManagerInternal;
 import android.util.ArrayMap;
 
+import com.android.internal.util.function.QuadFunction;
+import com.android.internal.util.function.TriFunction;
 import com.android.server.pm.pkg.AndroidPackage;
 import com.android.server.pm.pkg.PackageState;
 
@@ -173,29 +175,47 @@
             @PermissionInfo.ProtectionFlags int protectionFlags);
 
     /**
-     * Start delegate the permission identity of the shell UID to the given UID.
-     *
-     * @param uid the UID to delegate shell permission identity to
-     * @param packageName the name of the package to delegate shell permission identity to
-     * @param permissionNames the names of the permissions to delegate shell permission identity
-     *                       for, or {@code null} for all permissions
+     * Sets the current check permission delegate
      */
-    //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-    void startShellPermissionIdentityDelegation(int uid,
-            @NonNull String packageName, @Nullable List<String> permissionNames);
+    void setCheckPermissionDelegate(CheckPermissionDelegate delegate);
 
-    /**
-     * Stop delegating the permission identity of the shell UID.
-     *
-     * @see #startShellPermissionIdentityDelegation(int, String, List)
+     /**
+     * Interface to intercept permission checks and optionally pass through to the original
+     * implementation.
      */
-    //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-    void stopShellPermissionIdentityDelegation();
+    interface CheckPermissionDelegate {
 
-    /**
-     * Get all delegated shell permissions.
-     */
-    @NonNull List<String> getDelegatedShellPermissions();
+        /**
+         * Check whether the given package has been granted the specified permission.
+         *
+         * @param packageName the name of the package to be checked
+         * @param permissionName the name of the permission to be checked
+         * @param persistentDeviceId The persistent device ID
+         * @param userId the user ID
+         * @param superImpl the original implementation that can be delegated to
+         * @return {@link android.content.pm.PackageManager#PERMISSION_GRANTED} if the package has
+         * the permission, or {@link android.content.pm.PackageManager#PERMISSION_DENIED} otherwise
+         *
+         * @see android.content.pm.PackageManager#checkPermission(String, String)
+         */
+        int checkPermission(@NonNull String packageName, @NonNull String permissionName,
+                @NonNull String persistentDeviceId, @UserIdInt int userId,
+                @NonNull QuadFunction<String, String, String, Integer, Integer> superImpl);
+
+        /**
+         * Check whether the given UID has been granted the specified permission.
+         *
+         * @param uid the UID to be checked
+         * @param permissionName the name of the permission to be checked
+         * @param persistentDeviceId The persistent device ID
+         * @param superImpl the original implementation that can be delegated to
+         * @return {@link android.content.pm.PackageManager#PERMISSION_GRANTED} if the package has
+         * the permission, or {@link android.content.pm.PackageManager#PERMISSION_DENIED} otherwise
+         */
+        int checkUidPermission(int uid, @NonNull String permissionName,
+                @NonNull String persistentDeviceId,
+                @NonNull TriFunction<Integer, String, String, Integer> superImpl);
+    }
 
     /**
      * Read legacy permissions from legacy permission settings.
diff --git a/services/core/java/com/android/server/policy/Android.bp b/services/core/java/com/android/server/policy/Android.bp
index fa55bf0..325b6cb 100644
--- a/services/core/java/com/android/server/policy/Android.bp
+++ b/services/core/java/com/android/server/policy/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "policy_flags",
     package: "com.android.server.policy",
+    container: "system",
     srcs: ["*.aconfig"],
 }
 
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 76bf8fd..7db83d7 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -5664,6 +5664,13 @@
         }
     }
 
+    @Override
+    public void onDisplaySwitchStart(int displayId) {
+        if (displayId == DEFAULT_DISPLAY) {
+            mDefaultDisplayPolicy.onDisplaySwitchStart();
+        }
+    }
+
     private long getKeyguardDrawnTimeout() {
         final boolean bootCompleted =
                 LocalServices.getService(SystemServiceManager.class).isBootCompleted();
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 5956594..2623025 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -895,6 +895,9 @@
         void onScreenOff();
     }
 
+    /** Called when the physical display starts to switch, e.g. fold/unfold. */
+    void onDisplaySwitchStart(int displayId);
+
     /**
      * Return whether the default display is on and not blocked by a black surface.
      */
diff --git a/services/core/java/com/android/server/policy/window_policy_flags.aconfig b/services/core/java/com/android/server/policy/window_policy_flags.aconfig
index 2154a26..7914b94 100644
--- a/services/core/java/com/android/server/policy/window_policy_flags.aconfig
+++ b/services/core/java/com/android/server/policy/window_policy_flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.policy"
+container: "system"
 
 flag {
     name: "support_input_wakeup_delegate"
diff --git a/services/core/java/com/android/server/power/Android.bp b/services/core/java/com/android/server/power/Android.bp
index 863ff76..5d4065d 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/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 3dec02e..b5d49b3 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -179,6 +179,9 @@
     // Message: Sent when an attentive timeout occurs to update the power state.
     private static final int MSG_ATTENTIVE_TIMEOUT = 5;
 
+    // Message: Sent when the policy want to release all timeout override wake locks.
+    private static final int MSG_RELEASE_ALL_OVERRIDE_WAKE_LOCKS = 6;
+
     // Dirty bit: mWakeLocks changed
     private static final int DIRTY_WAKE_LOCKS = 1 << 0;
     // Dirty bit: mWakefulness changed
@@ -219,6 +222,7 @@
     static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake
     static final int WAKE_LOCK_DOZE = 1 << 6;
     static final int WAKE_LOCK_DRAW = 1 << 7;
+    static final int WAKE_LOCK_SCREEN_TIMEOUT_OVERRIDE = 1 << 8;
 
     // Summarizes the user activity state.
     static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;
@@ -616,7 +620,8 @@
     public final float mScreenBrightnessDim;
 
     // Value we store for tracking face down behavior.
-    private boolean mIsFaceDown = false;
+    @VisibleForTesting
+    boolean mIsFaceDown = false;
     private long mLastFlipTime = 0L;
 
     // The screen brightness setting override from the window manager
@@ -707,6 +712,9 @@
     // Whether to keep dreaming when the device is unplugging.
     private boolean mKeepDreamingWhenUnplugging;
 
+    @GuardedBy("mLock")
+    private ScreenTimeoutOverridePolicy mScreenTimeoutOverridePolicy;
+
     private final class DreamManagerStateListener implements
             DreamManagerInternal.DreamManagerStateListener {
         @Override
@@ -734,6 +742,12 @@
                 userActivityNoUpdateLocked(mPowerGroups.get(groupId), eventTime,
                         PowerManager.USER_ACTIVITY_EVENT_OTHER, flags, uid);
             }
+
+            // Release wake lock when default display is not interactive.
+            if (mScreenTimeoutOverridePolicy != null && groupId == Display.DEFAULT_DISPLAY_GROUP) {
+                mScreenTimeoutOverridePolicy.onWakefulnessChange(mWakeLockSummary, wakefulness);
+            }
+
             mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS;
             mNotifier.onGroupWakefulnessChangeStarted(groupId, wakefulness, reason, eventTime);
             updateGlobalWakefulnessLocked(eventTime, reason, uid, opUid, opPackageName, details);
@@ -1401,6 +1415,13 @@
             // Go.
             readConfigurationLocked();
             updateSettingsLocked();
+            if (mFeatureFlags.isEarlyScreenTimeoutDetectorEnabled()) {
+                mScreenTimeoutOverridePolicy = new ScreenTimeoutOverridePolicy(mContext,
+                        mMinimumScreenOffTimeoutConfig, () -> {
+                    Message msg = mHandler.obtainMessage(MSG_RELEASE_ALL_OVERRIDE_WAKE_LOCKS);
+                    mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
+                });
+            }
             mDirty |= DIRTY_BATTERY_STATE;
             updatePowerStateLocked();
         }
@@ -1805,7 +1826,7 @@
     }
 
     @GuardedBy("mLock")
-    private void removeWakeLockLocked(WakeLock wakeLock, int index) {
+    private void removeWakeLockNoUpdateLocked(WakeLock wakeLock, int index) {
         mWakeLocks.remove(index);
         UidState state = wakeLock.mUidState;
         state.mNumWakeLocks--;
@@ -1813,10 +1834,15 @@
                 state.mProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
             mUidState.remove(state.mUid);
         }
-        notifyWakeLockReleasedLocked(wakeLock);
 
+        notifyWakeLockReleasedLocked(wakeLock);
         applyWakeLockFlagsOnReleaseLocked(wakeLock);
         mDirty |= DIRTY_WAKE_LOCKS;
+    }
+
+    @GuardedBy("mLock")
+    private void removeWakeLockLocked(WakeLock wakeLock, int index) {
+        removeWakeLockNoUpdateLocked(wakeLock, index);
         updatePowerStateLocked();
     }
 
@@ -1999,7 +2025,9 @@
 
                 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
                     return mSystemReady && mDisplayManagerInternal.isProximitySensorAvailable();
-
+                case PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK:
+                    return mSystemReady && mFeatureFlags.isEarlyScreenTimeoutDetectorEnabled()
+                            && mScreenTimeoutOverridePolicy != null;
                 default:
                     return false;
             }
@@ -2096,6 +2124,10 @@
             mNotifier.onUserActivity(powerGroup.getGroupId(), event, uid);
             mAttentionDetector.onUserActivity(eventTime, event);
 
+            if (mScreenTimeoutOverridePolicy != null) {
+                mScreenTimeoutOverridePolicy.onUserActivity(mWakeLockSummary, event);
+            }
+
             if (mUserInactiveOverrideFromWindowManager) {
                 mUserInactiveOverrideFromWindowManager = false;
                 mOverriddenTimeout = -1;
@@ -2751,6 +2783,11 @@
                 }
             }
 
+            // Screen wake lock or non-interactive will release all override wake locks.
+            if (mScreenTimeoutOverridePolicy != null) {
+                mScreenTimeoutOverridePolicy.checkScreenWakeLock(mWakeLockSummary);
+            }
+
             for (int idx = 0; idx < mPowerGroups.size(); idx++) {
                 final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
                 final int wakeLockSummary = adjustWakeLockSummary(powerGroup.getWakefulnessLocked(),
@@ -2826,6 +2863,8 @@
                 return WAKE_LOCK_DOZE;
             case PowerManager.DRAW_WAKE_LOCK:
                 return WAKE_LOCK_DRAW;
+            case PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK:
+                return WAKE_LOCK_SCREEN_TIMEOUT_OVERRIDE;
         }
         return 0;
     }
@@ -2906,11 +2945,10 @@
 
         final long attentiveTimeout = getAttentiveTimeoutLocked();
         final long sleepTimeout = getSleepTimeoutLocked(attentiveTimeout);
-        long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,
+        final long defaultScreenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,
                 attentiveTimeout);
-        final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
-        screenOffTimeout =
-                getScreenOffTimeoutWithFaceDownLocked(screenOffTimeout, screenDimDuration);
+        final long defaultScreenDimDuration = getScreenDimDurationLocked(defaultScreenOffTimeout);
+
         final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
         long nextTimeout = -1;
         boolean hasUserActivitySummary = false;
@@ -2919,6 +2957,16 @@
             long groupNextTimeout = 0;
             final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
             final int wakefulness = powerGroup.getWakefulnessLocked();
+
+            // The default display screen timeout could be overridden by policy.
+            long screenOffTimeout = defaultScreenOffTimeout;
+            long screenDimDuration = defaultScreenDimDuration;
+            if (powerGroup.getGroupId() == Display.DEFAULT_DISPLAY_GROUP) {
+                screenOffTimeout =
+                        getScreenOffTimeoutOverrideLocked(screenOffTimeout, screenDimDuration);
+                screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
+            }
+
             if (wakefulness != WAKEFULNESS_ASLEEP) {
                 final long lastUserActivityTime = powerGroup.getLastUserActivityTimeLocked();
                 final long lastUserActivityTimeNoChangeLights =
@@ -3196,15 +3244,20 @@
                 (long)(screenOffTimeout * mMaximumScreenDimRatioConfig));
     }
 
+    @VisibleForTesting
     @GuardedBy("mLock")
-    private long getScreenOffTimeoutWithFaceDownLocked(
-            long screenOffTimeout, long screenDimDuration) {
-        // If face down, we decrease the timeout to equal the dim duration so that the
-        // device will go into a dim state.
-        if (mIsFaceDown) {
-            return Math.min(screenDimDuration, screenOffTimeout);
+    long getScreenOffTimeoutOverrideLocked(long screenOffTimeout, long screenDimDuration) {
+        long shortestScreenOffTimeout = screenOffTimeout;
+        if (mScreenTimeoutOverridePolicy != null) {
+            shortestScreenOffTimeout =
+                    mScreenTimeoutOverridePolicy.getScreenTimeoutOverrideLocked(
+                            mWakeLockSummary, screenOffTimeout);
         }
-        return screenOffTimeout;
+        if (mIsFaceDown) {
+            shortestScreenOffTimeout = Math.min(screenDimDuration, shortestScreenOffTimeout);
+        }
+
+        return shortestScreenOffTimeout;
     }
 
     /**
@@ -4815,6 +4868,13 @@
         mAmbientDisplaySuppressionController.dump(pw);
 
         mLowPowerStandbyController.dump(pw);
+
+        synchronized (mLock) {
+            if (mScreenTimeoutOverridePolicy != null) {
+                mScreenTimeoutOverridePolicy.dump(pw);
+            }
+        }
+
         mFeatureFlags.dump(pw);
     }
 
@@ -5284,6 +5344,9 @@
                 case MSG_ATTENTIVE_TIMEOUT:
                     handleAttentiveTimeout();
                     break;
+                case MSG_RELEASE_ALL_OVERRIDE_WAKE_LOCKS:
+                    releaseAllOverrideWakeLocks();
+                    break;
             }
 
             return true;
@@ -5475,21 +5538,23 @@
         private String getLockLevelString() {
             switch (mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
                 case PowerManager.FULL_WAKE_LOCK:
-                    return "FULL_WAKE_LOCK                ";
+                    return "FULL_WAKE_LOCK                   ";
                 case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
-                    return "SCREEN_BRIGHT_WAKE_LOCK       ";
+                    return "SCREEN_BRIGHT_WAKE_LOCK          ";
                 case PowerManager.SCREEN_DIM_WAKE_LOCK:
-                    return "SCREEN_DIM_WAKE_LOCK          ";
+                    return "SCREEN_DIM_WAKE_LOCK             ";
                 case PowerManager.PARTIAL_WAKE_LOCK:
-                    return "PARTIAL_WAKE_LOCK             ";
+                    return "PARTIAL_WAKE_LOCK                ";
                 case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
-                    return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
+                    return "PROXIMITY_SCREEN_OFF_WAKE_LOCK   ";
                 case PowerManager.DOZE_WAKE_LOCK:
-                    return "DOZE_WAKE_LOCK                ";
+                    return "DOZE_WAKE_LOCK                   ";
                 case PowerManager.DRAW_WAKE_LOCK:
-                    return "DRAW_WAKE_LOCK                ";
+                    return "DRAW_WAKE_LOCK                   ";
+                case PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK:
+                    return "SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK";
                 default:
-                    return "???                           ";
+                    return "???                              ";
             }
         }
 
@@ -5732,6 +5797,17 @@
                 mContext.enforceCallingOrSelfPermission(
                         android.Manifest.permission.DEVICE_POWER, null);
             }
+
+            if ((flags & PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK) != 0) {
+                if (!mFeatureFlags.isEarlyScreenTimeoutDetectorEnabled()) {
+                    throw new IllegalArgumentException("Acquiring an unsupported wake lock:"
+                            + " flags=" + flags + ", tag=" + tag);
+                }
+
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.SCREEN_TIMEOUT_OVERRIDE, null);
+            }
+
             if (ws != null && !ws.isEmpty()) {
                 mContext.enforceCallingOrSelfPermission(
                         android.Manifest.permission.UPDATE_DEVICE_STATS, null);
@@ -7182,4 +7258,23 @@
         }
         return false;
     }
+
+    private void releaseAllOverrideWakeLocks() {
+        synchronized (mLock) {
+            final int size = mWakeLocks.size();
+            boolean change = false;
+            for (int i = size - 1; i >= 0; i--) {
+                final WakeLock wakeLock = mWakeLocks.get(i);
+                if ((wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK)
+                        == PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK) {
+                    removeWakeLockNoUpdateLocked(wakeLock, i);
+                    change = true;
+                }
+            }
+
+            if (change) {
+                updatePowerStateLocked();
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/power/ScreenTimeoutOverridePolicy.java b/services/core/java/com/android/server/power/ScreenTimeoutOverridePolicy.java
new file mode 100644
index 0000000..adde518
--- /dev/null
+++ b/services/core/java/com/android/server/power/ScreenTimeoutOverridePolicy.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
+
+import static com.android.server.power.PowerManagerService.WAKE_LOCK_BUTTON_BRIGHT;
+import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_BRIGHT;
+import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_DIM;
+import static com.android.server.power.PowerManagerService.WAKE_LOCK_SCREEN_TIMEOUT_OVERRIDE;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.util.IndentingPrintWriter;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.PrintWriter;
+
+/**
+  * Policy that handle the screen timeout override wake lock behavior.
+  */
+@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+final class ScreenTimeoutOverridePolicy {
+    private static final String TAG = "ScreenTimeoutOverridePolicy";
+
+    /**
+     * Release reason code: The wake lock is never acquired.
+     */
+    public static final int RELEASE_REASON_UNKNOWN = -1;
+
+    /**
+     * Release reason code: The wake lock can't be acquired because of screen off.
+     */
+    public static final int RELEASE_REASON_NON_INTERACTIVE = 1;
+
+    /**
+     * Release reason code: Release because user activity occurred.
+     */
+    public static final int RELEASE_REASON_USER_ACTIVITY = 2;
+    /**
+     * Release reason code: Release because a screen lock is acquired.
+     */
+    public static final int RELEASE_REASON_SCREEN_LOCK = 3;
+
+    // The screen timeout override config in milliseconds.
+    private long mScreenTimeoutOverrideConfig;
+
+    // The last reason that wake locks had been released by service.
+    private int mLastAutoReleaseReason = RELEASE_REASON_UNKNOWN;
+
+    interface PolicyCallback {
+        /**
+         * Notify {@link PowerManagerService} to release all override wake locks.
+         */
+        void releaseAllScreenTimeoutOverrideWakelocks();
+    }
+    private PolicyCallback mPolicyCallback;
+
+    ScreenTimeoutOverridePolicy(Context context, long minimumScreenOffTimeoutConfig,
+            PolicyCallback callback) {
+        mScreenTimeoutOverrideConfig = context.getResources().getInteger(
+                com.android.internal.R.integer.config_screenTimeoutOverride);
+        if (mScreenTimeoutOverrideConfig < minimumScreenOffTimeoutConfig) {
+            Slog.w(TAG, "Screen timeout override is smaller than the minimum timeout : "
+                    + mScreenTimeoutOverrideConfig);
+            mScreenTimeoutOverrideConfig = -1;
+        }
+        mPolicyCallback = callback;
+    }
+
+    /**
+     * Return the valid screen timeout override value.
+     */
+    long getScreenTimeoutOverrideLocked(int wakeLockSummary, long screenOffTimeout) {
+        if (!isWakeLockAcquired(wakeLockSummary)) {
+            return screenOffTimeout;
+        }
+
+        if (mScreenTimeoutOverrideConfig < 0) {
+            return screenOffTimeout;
+        }
+
+        // If screen timeout overlay wake lock is acquired, return the policy timeout.
+        return Math.min(mScreenTimeoutOverrideConfig, screenOffTimeout);
+    }
+
+    /**
+     * Called when the policy have to release all wake lock when user activity occurred.
+     */
+    void onUserActivity(int wakeLockSummary, @PowerManager.UserActivityEvent int event) {
+        if (!isWakeLockAcquired(wakeLockSummary)) {
+            return;
+        }
+
+        switch (event) {
+            case PowerManager.USER_ACTIVITY_EVENT_ATTENTION:
+            case PowerManager.USER_ACTIVITY_EVENT_OTHER:
+            case PowerManager.USER_ACTIVITY_EVENT_BUTTON:
+            case PowerManager.USER_ACTIVITY_EVENT_TOUCH:
+            case PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY:
+                releaseAllWakeLocks(RELEASE_REASON_USER_ACTIVITY);
+        }
+    }
+
+    /**
+     * Check the summary whether a screen wake lock acquired .
+     */
+    void checkScreenWakeLock(int wakeLockSummary) {
+        if (!isWakeLockAcquired(wakeLockSummary)) {
+            return;
+        }
+
+        if ((wakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
+                | WAKE_LOCK_BUTTON_BRIGHT)) != 0) {
+            releaseAllWakeLocks(RELEASE_REASON_SCREEN_LOCK);
+        }
+    }
+
+    /**
+     * Check the device is in non-interactive
+     */
+    void onWakefulnessChange(int wakeLockSummary, int globalWakefulness) {
+        if (!isWakeLockAcquired(wakeLockSummary)) {
+            return;
+        }
+
+        if (globalWakefulness != WAKEFULNESS_AWAKE) {
+            releaseAllWakeLocks(RELEASE_REASON_NON_INTERACTIVE);
+        }
+    }
+
+    private boolean isWakeLockAcquired(int wakeLockSummary) {
+        return (wakeLockSummary & WAKE_LOCK_SCREEN_TIMEOUT_OVERRIDE) != 0;
+    }
+
+    private void logReleaseReason() {
+        Slog.i(TAG, "Releasing all screen timeout override wake lock."
+                + " (reason=" + mLastAutoReleaseReason + ")");
+    }
+
+    private void releaseAllWakeLocks(int reason) {
+        mPolicyCallback.releaseAllScreenTimeoutOverrideWakelocks();
+        mLastAutoReleaseReason = reason;
+        logReleaseReason();
+    }
+
+    void dump(PrintWriter pw) {
+        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
+
+        ipw.println();
+        ipw.println("ScreenTimeoutOverridePolicy:");
+        ipw.increaseIndent();
+
+        ipw.println("mScreenTimeoutOverrideConfig=" + mScreenTimeoutOverrideConfig);
+        ipw.println("mLastAutoReleaseReason=" + mLastAutoReleaseReason);
+    }
+}
diff --git a/services/core/java/com/android/server/power/WakeLockLog.java b/services/core/java/com/android/server/power/WakeLockLog.java
index d3486a4..b131311 100644
--- a/services/core/java/com/android/server/power/WakeLockLog.java
+++ b/services/core/java/com/android/server/power/WakeLockLog.java
@@ -86,7 +86,7 @@
     private static final int TAG_DATABASE_SIZE = 128;
     private static final int TAG_DATABASE_SIZE_MAX = 128;
 
-    private static final int LEVEL_UNKNOWN = 0;
+    private static final int LEVEL_SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK = 0;
     private static final int LEVEL_PARTIAL_WAKE_LOCK = 1;
     private static final int LEVEL_FULL_WAKE_LOCK = 2;
     private static final int LEVEL_SCREEN_DIM_WAKE_LOCK = 3;
@@ -96,7 +96,7 @@
     private static final int LEVEL_DRAW_WAKE_LOCK = 7;
 
     private static final String[] LEVEL_TO_STRING = {
-        "unknown",
+        "override",
         "partial",
         "full",
         "screen-dim",
@@ -311,6 +311,9 @@
             case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
                 newFlags = LEVEL_PROXIMITY_SCREEN_OFF_WAKE_LOCK;
                 break;
+            case PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK:
+                newFlags = LEVEL_SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK;
+                break;
             default:
                 Slog.w(TAG, "Unsupported lock level for logging, flags: " + flags);
                 break;
diff --git a/services/core/java/com/android/server/power/batterysaver/OWNERS b/services/core/java/com/android/server/power/batterysaver/OWNERS
index cf23bea..dc2d0b3 100644
--- a/services/core/java/com/android/server/power/batterysaver/OWNERS
+++ b/services/core/java/com/android/server/power/batterysaver/OWNERS
@@ -1,3 +1,2 @@
-kwekua@google.com
 omakoto@google.com
-yamasani@google.com
\ No newline at end of file
+yamasani@google.com
diff --git a/services/core/java/com/android/server/power/feature/Android.bp b/services/core/java/com/android/server/power/feature/Android.bp
index 2295b41..fee3114 100644
--- a/services/core/java/com/android/server/power/feature/Android.bp
+++ b/services/core/java/com/android/server/power/feature/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "power_flags",
     package: "com.android.server.power.feature.flags",
+    container: "system",
     srcs: [
         "*.aconfig",
     ],
diff --git a/services/core/java/com/android/server/power/feature/power_flags.aconfig b/services/core/java/com/android/server/power/feature/power_flags.aconfig
index f5dfb5c..ca58153 100644
--- a/services/core/java/com/android/server/power/feature/power_flags.aconfig
+++ b/services/core/java/com/android/server/power/feature/power_flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.power.feature.flags"
+container: "system"
 
 # Important: Flags must be accessed through PowerManagerFlags.
 
diff --git a/services/core/java/com/android/server/power/hint/Android.bp b/services/core/java/com/android/server/power/hint/Android.bp
index 8a98de6..d7dd902 100644
--- a/services/core/java/com/android/server/power/hint/Android.bp
+++ b/services/core/java/com/android/server/power/hint/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "power_hint_flags",
     package: "com.android.server.power.hint",
+    container: "system",
     srcs: [
         "flags.aconfig",
     ],
diff --git a/services/core/java/com/android/server/power/hint/HintManagerService.java b/services/core/java/com/android/server/power/hint/HintManagerService.java
index 3f1b1c1..101983e 100644
--- a/services/core/java/com/android/server/power/hint/HintManagerService.java
+++ b/services/core/java/com/android/server/power/hint/HintManagerService.java
@@ -456,6 +456,9 @@
                         totalDurationNs / durationNsList.length);
                 int th90DurationUs = (int) TimeUnit.NANOSECONDS.toMicros(
                         durationNsList[(int) (durationNsList.length * 0.9)]);
+                FrameworkStatsLog.write(FrameworkStatsLog.ADPF_HINT_SESSION_TID_CLEANUP, uid,
+                        totalDurationUs, maxDurationUs, totalTidCnt, totalInvalidTidCnt,
+                        maxInvalidTidCnt, sessionCnt, isForeground);
                 Slog.d(TAG,
                         "Invalid tid found for UID" + uid + " in " + totalDurationUs + "us:\n\t"
                                 + "count("
diff --git a/services/core/java/com/android/server/power/hint/TEST_MAPPING b/services/core/java/com/android/server/power/hint/TEST_MAPPING
index 10c5362..ce6277d 100644
--- a/services/core/java/com/android/server/power/hint/TEST_MAPPING
+++ b/services/core/java/com/android/server/power/hint/TEST_MAPPING
@@ -1,5 +1,5 @@
 {
-  "postsubmit": [
+  "presubmit": [
     {
       "name": "FrameworksServicesTests",
       "options": [
@@ -10,6 +10,17 @@
           "exclude-annotation": "androidx.test.filters.FlakyTest"
         }
       ]
+    },
+    {
+      "name": "CtsStatsdAtomHostTestCases",
+      "options": [
+        {"exclude-annotation": "androidx.test.filters.FlakyTest"},
+        {"exclude-annotation": "org.junit.Ignore"},
+        {"include-filter": "android.cts.statsdatom.powermanager"}
+      ],
+      "file_patterns": [
+        "(/|^)ThermalManagerService.java"
+      ]
     }
   ]
 }
\ No newline at end of file
diff --git a/services/core/java/com/android/server/power/hint/flags.aconfig b/services/core/java/com/android/server/power/hint/flags.aconfig
index f4afcb1..0997744 100644
--- a/services/core/java/com/android/server/power/hint/flags.aconfig
+++ b/services/core/java/com/android/server/power/hint/flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.power.hint"
+container: "system"
 
 flag {
     name: "powerhint_thread_cleanup"
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 c42ccea..54ae84f4 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/README.md b/services/core/java/com/android/server/rollback/README.md
index f6bcbd0..a38315c 100644
--- a/services/core/java/com/android/server/rollback/README.md
+++ b/services/core/java/com/android/server/rollback/README.md
@@ -203,6 +203,15 @@
 $ adb install --enable-rollback 1 FooV2.apk
 ```
 
+### Setting Rollback Impact Level
+
+The `adb install` command accepts the `--rollback-impact-level [0/1/2]` flag to control
+when a rollback can be performed by `PackageWatchdog`.
+
+The default rollback impact level is `ROLLBACK_USER_IMPACT_LOW` (0). To use a
+different impact level, use `ROLLBACK_USER_IMPACT_HIGH` (1) or `ROLLBACK_USER_IMPACT_ONLY_MANUAL`
+(2).
+
 ### Triggering Rollback Manually
 
 If rollback is available for an application, the pm command can be used to
@@ -225,6 +234,8 @@
 469808841:
   -state: committed
   -timestamp: 2019-04-23T14:57:35.944Z
+  -rollbackLifetimeMillis: 0
+  -rollbackUserImpact: 1
   -packages:
     com.android.tests.rollback.testapp.B 2 -> 1 [0]
   -causePackages:
@@ -232,6 +243,8 @@
 649899517:
   -state: committed
   -timestamp: 2019-04-23T12:55:21.342Z
+  -rollbackLifetimeMillis: 0
+  -rollbackUserImpact: 0
   -stagedSessionId: 343374391
   -packages:
     com.android.tests.rollback.testapex 2 -> 1 [0]
diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java
index d1f91c8..8f39ffb 100644
--- a/services/core/java/com/android/server/rollback/Rollback.java
+++ b/services/core/java/com/android/server/rollback/Rollback.java
@@ -27,6 +27,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentSender;
+import android.content.pm.Flags;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
@@ -960,6 +961,9 @@
         ipw.println("-stateDescription: " + mStateDescription);
         ipw.println("-timestamp: " + getTimestamp());
         ipw.println("-rollbackLifetimeMillis: " + getRollbackLifetimeMillis());
+        if (Flags.recoverabilityDetection()) {
+            ipw.println("-rollbackImpactLevel: " + info.getRollbackImpactLevel());
+        }
         ipw.println("-isStaged: " + isStaged());
         ipw.println("-originalSessionId: " + getOriginalSessionId());
         ipw.println("-packages:");
diff --git a/services/core/java/com/android/server/stats/Android.bp b/services/core/java/com/android/server/stats/Android.bp
index e597c3a..f7955e8 100644
--- a/services/core/java/com/android/server/stats/Android.bp
+++ b/services/core/java/com/android/server/stats/Android.bp
@@ -1,6 +1,7 @@
 aconfig_declarations {
     name: "stats_flags",
     package: "com.android.server.stats",
+    container: "system",
     srcs: [
         "stats_flags.aconfig",
     ],
diff --git a/services/core/java/com/android/server/stats/pull/AggregatedMobileDataStatsPuller.java b/services/core/java/com/android/server/stats/pull/AggregatedMobileDataStatsPuller.java
index 881583a..2088e41 100644
--- a/services/core/java/com/android/server/stats/pull/AggregatedMobileDataStatsPuller.java
+++ b/services/core/java/com/android/server/stats/pull/AggregatedMobileDataStatsPuller.java
@@ -16,6 +16,7 @@
 
 package com.android.server.stats.pull;
 
+import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.StatsManager;
 import android.app.usage.NetworkStatsManager;
@@ -125,6 +126,11 @@
     @GuardedBy("mLock")
     private final Map<UidProcState, MobileDataStats> mUidStats;
 
+    // No reason to keep more dimensions than 3000. The 3000 is the hard top for the statsd metrics
+    // dimensions guardrail. It also will keep the result binder transaction size capped to
+    // approximately 220kB for 3000 atoms
+    private static final int UID_STATS_MAX_SIZE = 3000;
+
     private final SparseIntArray mUidPreviousState;
 
     private NetworkStats mLastMobileUidStats = new NetworkStats(0, -1);
@@ -135,7 +141,7 @@
 
     private final RateLimiter mRateLimiter;
 
-    AggregatedMobileDataStatsPuller(NetworkStatsManager networkStatsManager) {
+    AggregatedMobileDataStatsPuller(@NonNull NetworkStatsManager networkStatsManager) {
         if (DEBUG) {
             if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
                 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,
@@ -188,14 +194,18 @@
         }
 
         final UidProcState statsKey = new UidProcState(uid, previousState);
-        MobileDataStats stats;
         if (mUidStats.containsKey(statsKey)) {
-            stats = mUidStats.get(statsKey);
-        } else {
-            stats = new MobileDataStats();
-            mUidStats.put(statsKey, stats);
+            return mUidStats.get(statsKey);
         }
-        return stats;
+        if (mUidStats.size() < UID_STATS_MAX_SIZE) {
+            MobileDataStats stats = new MobileDataStats();
+            mUidStats.put(statsKey, stats);
+            return stats;
+        }
+        if (DEBUG) {
+            Slog.w(TAG, "getUidStatsForPreviousStateLocked() UID_STATS_MAX_SIZE reached");
+        }
+        return null;
     }
 
     private void noteUidProcessStateImpl(int uid, int state) {
@@ -252,10 +262,12 @@
                     continue;
                 }
                 MobileDataStats stats = getUidStatsForPreviousStateLocked(entry.getUid());
-                stats.addTxBytes(entry.getTxBytes());
-                stats.addRxBytes(entry.getRxBytes());
-                stats.addTxPackets(entry.getTxPackets());
-                stats.addRxPackets(entry.getRxPackets());
+                if (stats != null) {
+                    stats.addTxBytes(entry.getTxBytes());
+                    stats.addRxBytes(entry.getRxBytes());
+                    stats.addTxPackets(entry.getTxPackets());
+                    stats.addRxPackets(entry.getRxPackets());
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 0ffd002..b5df30f 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -37,6 +37,7 @@
 import static android.net.NetworkTemplate.OEM_MANAGED_PAID;
 import static android.net.NetworkTemplate.OEM_MANAGED_PRIVATE;
 import static android.os.Debug.getIonHeapsSizeKb;
+import static android.os.Process.INVALID_UID;
 import static android.os.Process.LAST_SHARED_APPLICATION_GID;
 import static android.os.Process.SYSTEM_UID;
 import static android.os.Process.getUidForPid;
@@ -844,8 +845,6 @@
         mStorageManager = (StorageManager) mContext.getSystemService(StorageManager.class);
         mNetworkStatsManager = mContext.getSystemService(NetworkStatsManager.class);
 
-        initMobileDataStatsPuller();
-
         // Initialize DiskIO
         mStoragedUidIoStatsReader = new StoragedUidIoStatsReader();
 
@@ -1015,7 +1014,8 @@
         }
         if (ENABLE_MOBILE_DATA_STATS_AGGREGATED_PULLER) {
             mAggregatedMobileDataStatsPuller =
-                    new AggregatedMobileDataStatsPuller(mNetworkStatsManager);
+                    new AggregatedMobileDataStatsPuller(
+                            mContext.getSystemService(NetworkStatsManager.class));
         }
     }
 
@@ -1061,6 +1061,7 @@
         registerMobileBytesTransfer();
         registerMobileBytesTransferBackground();
         if (ENABLE_MOBILE_DATA_STATS_AGGREGATED_PULLER) {
+            initMobileDataStatsPuller();
             registerMobileBytesTransferByProcState();
         }
         registerBytesTransferByTagAndMetered();
@@ -3537,17 +3538,23 @@
                     String roleName = roleEntry.getKey();
                     Set<String> packageNames = roleEntry.getValue();
 
-                    for (String packageName : packageNames) {
-                        PackageInfo pkg;
-                        try {
-                            pkg = pm.getPackageInfoAsUser(packageName, 0, userId);
-                        } catch (PackageManager.NameNotFoundException e) {
-                            Slog.w(TAG, "Role holder " + packageName + " not found");
-                            return StatsManager.PULL_SKIP;
-                        }
+                    if (!packageNames.isEmpty()) {
+                        for (String packageName : packageNames) {
+                            PackageInfo pkg;
+                            try {
+                                pkg = pm.getPackageInfoAsUser(packageName, 0, userId);
+                            } catch (PackageManager.NameNotFoundException e) {
+                                Slog.w(TAG, "Role holder " + packageName + " not found");
+                                return StatsManager.PULL_SKIP;
+                            }
 
+                            pulledData.add(FrameworkStatsLog.buildStatsEvent(
+                                    atomTag, pkg.applicationInfo.uid, packageName, roleName));
+                        }
+                    } else {
+                        // Ensure that roles set to None are logged with an empty state.
                         pulledData.add(FrameworkStatsLog.buildStatsEvent(
-                                atomTag, pkg.applicationInfo.uid, packageName, roleName));
+                                atomTag, INVALID_UID, "", roleName));
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/stats/stats_flags.aconfig b/services/core/java/com/android/server/stats/stats_flags.aconfig
index 5101a69..101b98e 100644
--- a/services/core/java/com/android/server/stats/stats_flags.aconfig
+++ b/services/core/java/com/android/server/stats/stats_flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.stats"
+container: "system"
 
 flag {
     name: "add_mobile_bytes_transfer_by_proc_state_puller"
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 2b05993..f62c76e 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -61,7 +61,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
-import android.security.Authorization;
+import android.security.KeyStoreAuthorization;
 import android.service.trust.GrantTrustResult;
 import android.service.trust.TrustAgentService;
 import android.text.TextUtils;
@@ -155,6 +155,7 @@
     /* package */ final TrustArchive mArchive = new TrustArchive();
     private final Context mContext;
     private final LockPatternUtils mLockPatternUtils;
+    private final KeyStoreAuthorization mKeyStoreAuthorization;
     private final UserManager mUserManager;
     private final ActivityManager mActivityManager;
     private FingerprintManager mFingerprintManager;
@@ -252,25 +253,27 @@
      * cases.
      */
     protected static class Injector {
-        private final LockPatternUtils mLockPatternUtils;
-        private final Looper mLooper;
+        private final Context mContext;
 
-        public Injector(LockPatternUtils lockPatternUtils, Looper looper) {
-            mLockPatternUtils = lockPatternUtils;
-            mLooper = looper;
+        public Injector(Context context) {
+            mContext = context;
         }
 
         LockPatternUtils getLockPatternUtils() {
-            return mLockPatternUtils;
+            return new LockPatternUtils(mContext);
+        }
+
+        KeyStoreAuthorization getKeyStoreAuthorization() {
+            return KeyStoreAuthorization.getInstance();
         }
 
         Looper getLooper() {
-            return mLooper;
+            return Looper.myLooper();
         }
     }
 
     public TrustManagerService(Context context) {
-        this(context, new Injector(new LockPatternUtils(context), Looper.myLooper()));
+        this(context, new Injector(context));
     }
 
     protected TrustManagerService(Context context, Injector injector) {
@@ -280,6 +283,7 @@
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
         mLockPatternUtils = injector.getLockPatternUtils();
+        mKeyStoreAuthorization = injector.getKeyStoreAuthorization();
         mStrongAuthTracker = new StrongAuthTracker(context, injector.getLooper());
         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
     }
@@ -915,16 +919,16 @@
                 int authUserId = mLockPatternUtils.isProfileWithUnifiedChallenge(userId)
                         ? resolveProfileParent(userId) : userId;
 
-                Authorization.onDeviceLocked(userId, getBiometricSids(authUserId),
+                mKeyStoreAuthorization.onDeviceLocked(userId, getBiometricSids(authUserId),
                         isWeakUnlockMethodEnabled(authUserId));
             } else {
-                Authorization.onDeviceLocked(userId, getBiometricSids(userId), false);
+                mKeyStoreAuthorization.onDeviceLocked(userId, getBiometricSids(userId), false);
             }
         } else {
             // Notify Keystore that the device is now unlocked for the user.  Note that for unlocks
             // with LSKF, this is redundant with the call from LockSettingsService which provides
             // the password.  However, for unlocks with biometric or trust agent, this is required.
-            Authorization.onDeviceUnlocked(userId, /* password= */ null);
+            mKeyStoreAuthorization.onDeviceUnlocked(userId, /* password= */ null);
         }
     }
 
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 163116b..6f37837 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"
diff --git a/services/core/java/com/android/server/utils/quota/OWNERS b/services/core/java/com/android/server/utils/quota/OWNERS
index a2943f3..469acb2 100644
--- a/services/core/java/com/android/server/utils/quota/OWNERS
+++ b/services/core/java/com/android/server/utils/quota/OWNERS
@@ -1,4 +1,3 @@
 dplotnikov@google.com
-kwekua@google.com
 omakoto@google.com
 yamasani@google.com
diff --git a/services/core/java/com/android/server/vibrator/Vibration.java b/services/core/java/com/android/server/vibrator/Vibration.java
index 6fc9d9a..ad54efc 100644
--- a/services/core/java/com/android/server/vibrator/Vibration.java
+++ b/services/core/java/com/android/server/vibrator/Vibration.java
@@ -32,8 +32,9 @@
 import android.util.proto.ProtoOutputStream;
 
 import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
-import java.util.Date;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
 import java.util.Locale;
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -42,10 +43,11 @@
  * The base class for all vibrations.
  */
 abstract class Vibration {
-    private static final SimpleDateFormat DEBUG_TIME_FORMAT =
-            new SimpleDateFormat("HH:mm:ss.SSS");
-    private static final SimpleDateFormat DEBUG_DATE_TIME_FORMAT =
-            new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
+    private static final DateTimeFormatter DEBUG_TIME_FORMATTER = DateTimeFormatter.ofPattern(
+            "HH:mm:ss.SSS").withZone(ZoneId.systemDefault());
+    private static final DateTimeFormatter DEBUG_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(
+            "MM-dd HH:mm:ss.SSS").withZone(ZoneId.systemDefault());
+
     // Used to generate globally unique vibration ids.
     private static final AtomicInteger sNextVibrationId = new AtomicInteger(1); // 0 = no callback
 
@@ -240,10 +242,12 @@
 
         @Override
         public String toString() {
-            return "createTime: " + DEBUG_DATE_TIME_FORMAT.format(new Date(mCreateTime))
-                    + ", startTime: " + DEBUG_DATE_TIME_FORMAT.format(new Date(mStartTime))
-                    + ", endTime: "
-                    + (mEndTime == 0 ? null : DEBUG_DATE_TIME_FORMAT.format(new Date(mEndTime)))
+            return "createTime: " + DEBUG_DATE_TIME_FORMATTER.format(
+                    Instant.ofEpochMilli(mCreateTime))
+                    + ", startTime: " + DEBUG_DATE_TIME_FORMATTER.format(
+                    Instant.ofEpochMilli(mStartTime))
+                    + ", endTime: " + (mEndTime == 0 ? null : DEBUG_DATE_TIME_FORMATTER.format(
+                    Instant.ofEpochMilli(mEndTime)))
                     + ", durationMs: " + mDurationMs
                     + ", status: " + mStatus.name().toLowerCase(Locale.ROOT)
                     + ", playedEffect: " + mPlayedEffect
@@ -267,12 +271,14 @@
             boolean isExternalVibration = mPlayedEffect == null;
             String timingsStr = String.format(Locale.ROOT,
                     "%s | %8s | %20s | duration: %5dms | start: %12s | end: %12s",
-                    DEBUG_DATE_TIME_FORMAT.format(new Date(mCreateTime)),
+                    DEBUG_DATE_TIME_FORMATTER.format(Instant.ofEpochMilli(mCreateTime)),
                     isExternalVibration ? "external" : "effect",
                     mStatus.name().toLowerCase(Locale.ROOT),
                     mDurationMs,
-                    mStartTime == 0 ? "" : DEBUG_TIME_FORMAT.format(new Date(mStartTime)),
-                    mEndTime == 0 ? "" : DEBUG_TIME_FORMAT.format(new Date(mEndTime)));
+                    mStartTime == 0 ? ""
+                            : DEBUG_TIME_FORMATTER.format(Instant.ofEpochMilli(mStartTime)),
+                    mEndTime == 0 ? ""
+                            : DEBUG_TIME_FORMATTER.format(Instant.ofEpochMilli(mEndTime)));
             String paramStr = String.format(Locale.ROOT,
                     " | scale: %8s (adaptive=%.2f) | flags: %4s | usage: %s",
                     VibrationScaler.scaleLevelToString(mScaleLevel), mAdaptiveScale,
@@ -307,10 +313,12 @@
             pw.increaseIndent();
             pw.println("status = " + mStatus.name().toLowerCase(Locale.ROOT));
             pw.println("durationMs = " + mDurationMs);
-            pw.println("createTime = " + DEBUG_DATE_TIME_FORMAT.format(new Date(mCreateTime)));
-            pw.println("startTime = " + DEBUG_DATE_TIME_FORMAT.format(new Date(mStartTime)));
-            pw.println("endTime = "
-                    + (mEndTime == 0 ? null : DEBUG_DATE_TIME_FORMAT.format(new Date(mEndTime))));
+            pw.println("createTime = " + DEBUG_DATE_TIME_FORMATTER.format(
+                    Instant.ofEpochMilli(mCreateTime)));
+            pw.println("startTime = " + DEBUG_DATE_TIME_FORMATTER.format(
+                    Instant.ofEpochMilli(mStartTime)));
+            pw.println("endTime = " + (mEndTime == 0 ? null
+                    : DEBUG_DATE_TIME_FORMATTER.format(Instant.ofEpochMilli(mEndTime))));
             pw.println("playedEffect = " + mPlayedEffect);
             pw.println("originalEffect = " + mOriginalEffect);
             pw.println("scale = " + VibrationScaler.scaleLevelToString(mScaleLevel));
diff --git a/services/core/java/com/android/server/vibrator/VibratorControlService.java b/services/core/java/com/android/server/vibrator/VibratorControlService.java
index 10317c9..b33fa6f 100644
--- a/services/core/java/com/android/server/vibrator/VibratorControlService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorControlService.java
@@ -51,8 +51,9 @@
 import com.android.internal.util.ArrayUtils;
 
 import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
-import java.util.Date;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
 import java.util.Locale;
 import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
@@ -66,8 +67,8 @@
     private static final int UNRECOGNIZED_VIBRATION_TYPE = -1;
     private static final int NO_SCALE = -1;
 
-    private static final SimpleDateFormat DEBUG_DATE_TIME_FORMAT =
-            new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
+    private static final DateTimeFormatter DEBUG_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(
+            "MM-dd HH:mm:ss.SSS").withZone(ZoneId.systemDefault());
 
     private final VibrationParamsRecords mVibrationParamsRecords;
     private final VibratorControllerHolder mVibratorControllerHolder;
@@ -567,7 +568,7 @@
         public void dump(IndentingPrintWriter pw) {
             String line = String.format(Locale.ROOT,
                     "%s | %6s | scale: %5s | typesMask: %6s | usages: %s",
-                    DEBUG_DATE_TIME_FORMAT.format(new Date(mCreateTime)),
+                    DEBUG_DATE_TIME_FORMATTER.format(Instant.ofEpochMilli(mCreateTime)),
                     mOperation.name().toLowerCase(Locale.ROOT),
                     (mScale == NO_SCALE) ? "" : String.format(Locale.ROOT, "%.2f", mScale),
                     Long.toBinaryString(mTypesMask), createVibrationUsagesString());
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperCropper.java b/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
index 5175b74..6905802 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wallpaper;
 
+import static android.app.WallpaperManager.ORIENTATION_UNKNOWN;
 import static android.app.WallpaperManager.getOrientation;
 import static android.app.WallpaperManager.getRotatedOrientation;
 import static android.view.Display.DEFAULT_DISPLAY;
@@ -86,7 +87,7 @@
     public interface WallpaperCropUtils {
 
         /**
-         * Equivalent to {@link #getCrop(Point, Point, SparseArray, boolean)}
+         * Equivalent to {@link WallpaperCropper#getCrop(Point, Point, SparseArray, boolean)}
          */
         Rect getCrop(Point displaySize, Point bitmapSize,
                 SparseArray<Rect> suggestedCrops, boolean rtl);
@@ -120,16 +121,23 @@
     public Rect getCrop(Point displaySize, Point bitmapSize,
             SparseArray<Rect> suggestedCrops, boolean rtl) {
 
-        // Case 1: if no crops are provided, center align the full image
+        int orientation = getOrientation(displaySize);
+
+        // Case 1: if no crops are provided, show the full image (from the left, or right if RTL).
         if (suggestedCrops == null || suggestedCrops.size() == 0) {
-            Rect crop = new Rect(0, 0, displaySize.x, displaySize.y);
-            float scale = Math.min(
-                    ((float) bitmapSize.x) / displaySize.x,
-                    ((float) bitmapSize.y) / displaySize.y);
-            crop.scale(scale);
-            crop.offset((bitmapSize.x - crop.width()) / 2,
-                    (bitmapSize.y - crop.height()) / 2);
-            return crop;
+            Rect crop = new Rect(0, 0, bitmapSize.x, bitmapSize.y);
+
+            // The first exception is if the device is a foldable and we're on the folded screen.
+            // In that case, show the center of what's on the unfolded screen.
+            int unfoldedOrientation = mWallpaperDisplayHelper.getUnfoldedOrientation(orientation);
+            if (unfoldedOrientation != ORIENTATION_UNKNOWN) {
+                // Let the system know that we're showing the full image on the unfolded screen
+                SparseArray<Rect> newSuggestedCrops = new SparseArray<>();
+                newSuggestedCrops.put(unfoldedOrientation, crop);
+                // This will fall into "Case 4" of this function and center the folded screen
+                return getCrop(displaySize, bitmapSize, newSuggestedCrops, rtl);
+            }
+            return getAdjustedCrop(crop, bitmapSize, displaySize, true, rtl, ADD);
         }
 
         // If any suggested crop is invalid, fallback to case 1
@@ -142,8 +150,6 @@
             }
         }
 
-        int orientation = getOrientation(displaySize);
-
         // Case 2: if the orientation exists in the suggested crops, adjust the suggested crop
         Rect suggestedCrop = suggestedCrops.get(orientation);
         if (suggestedCrop != null) {
@@ -168,11 +174,21 @@
         suggestedCrop = suggestedCrops.get(unfoldedOrientation);
         suggestedDisplaySize = defaultDisplaySizes.get(unfoldedOrientation);
         if (suggestedCrop != null) {
-            // only keep the visible part (without parallax)
+            // compute the visible part (without parallax) of the unfolded screen
             Rect adjustedCrop = noParallax(suggestedCrop, suggestedDisplaySize, bitmapSize, rtl);
-            return getAdjustedCrop(adjustedCrop, bitmapSize, displaySize, false, rtl, REMOVE);
+            // compute the folded crop, at the center of the crop of the unfolded screen
+            Rect res = getAdjustedCrop(adjustedCrop, bitmapSize, displaySize, false, rtl, REMOVE);
+            // if we removed some width, add it back to add a parallax effect
+            if (res.width() < adjustedCrop.width()) {
+                if (rtl) res.left = Math.min(res.left, adjustedCrop.left);
+                else res.right = Math.max(res.right, adjustedCrop.right);
+                // use getAdjustedCrop(parallax=true) to make sure we don't exceed MAX_PARALLAX
+                res = getAdjustedCrop(res, bitmapSize, displaySize, true, rtl, ADD);
+            }
+            return res;
         }
 
+
         // Case 5: if the device is a foldable, if we're looking for an unfolded orientation and
         // have the suggested crop of the relative folded orientation, reuse it by adding content.
         int foldedOrientation = mWallpaperDisplayHelper.getFoldedOrientation(orientation);
@@ -274,11 +290,8 @@
             if (additionalWidthForParallax > MAX_PARALLAX) {
                 int widthToRemove = (int) Math.ceil(
                         (additionalWidthForParallax - MAX_PARALLAX) * screenRatio * crop.height());
-                if (rtl) {
-                    adjustedCrop.left += widthToRemove;
-                } else {
-                    adjustedCrop.right -= widthToRemove;
-                }
+                adjustedCrop.left += widthToRemove / 2;
+                adjustedCrop.right -= widthToRemove / 2 + widthToRemove % 2;
             }
         } else {
             // TODO (b/281648899) the third case is not always correct, fix that.
@@ -366,6 +379,24 @@
      */
     SparseArray<Rect> getDefaultCrops(SparseArray<Rect> suggestedCrops, Point bitmapSize) {
 
+        // If the suggested crops is single-element map with (ORIENTATION_UNKNOWN, cropHint),
+        // Crop the bitmap using the cropHint and compute the crops for cropped bitmap.
+        Rect cropHint = suggestedCrops.get(ORIENTATION_UNKNOWN);
+        if (cropHint != null) {
+            Rect bitmapRect = new Rect(0, 0, bitmapSize.x, bitmapSize.y);
+            if (suggestedCrops.size() != 1 || !bitmapRect.contains(cropHint)) {
+                Slog.w(TAG, "Couldn't get default crops from suggested crops " + suggestedCrops
+                        + " for bitmap of size " + bitmapSize + "; ignoring suggested crops");
+                return getDefaultCrops(new SparseArray<>(), bitmapSize);
+            }
+            Point cropSize = new Point(cropHint.width(), cropHint.height());
+            SparseArray<Rect> relativeDefaultCrops = getDefaultCrops(new SparseArray<>(), cropSize);
+            for (int i = 0; i < relativeDefaultCrops.size(); i++) {
+                relativeDefaultCrops.valueAt(i).offset(cropHint.left, cropHint.top);
+            }
+            return relativeDefaultCrops;
+        }
+
         SparseArray<Point> defaultDisplaySizes = mWallpaperDisplayHelper.getDefaultDisplaySizes();
         boolean rtl = TextUtils.getLayoutDirectionFromLocale(Locale.getDefault())
                 == View.LAYOUT_DIRECTION_RTL;
@@ -422,26 +453,74 @@
         } else {
             boolean needCrop = false;
             boolean needScale;
-            boolean multiCrop = multiCrop() && wallpaper.mSupportsMultiCrop;
 
             Point bitmapSize = new Point(options.outWidth, options.outHeight);
+            Rect bitmapRect = new Rect(0, 0, bitmapSize.x, bitmapSize.y);
 
+            if (multiCrop()) {
+                // Check that the suggested crops per screen orientation are all within the bitmap.
+                for (int i = 0; i < wallpaper.mCropHints.size(); i++) {
+                    int orientation = wallpaper.mCropHints.keyAt(i);
+                    Rect crop = wallpaper.mCropHints.valueAt(i);
+                    if (crop.isEmpty() || !bitmapRect.contains(crop)) {
+                        Slog.w(TAG, "Invalid crop " + crop + " for orientation " + orientation
+                                + " and bitmap size " + bitmapSize + "; clearing suggested crops.");
+                        wallpaper.mCropHints.clear();
+                        wallpaper.cropHint.set(bitmapRect);
+                        break;
+                    }
+                }
+            }
             final Rect cropHint;
-            if (multiCrop) {
-                SparseArray<Rect> defaultDisplayCrops =
-                        getDefaultCrops(wallpaper.mCropHints, bitmapSize);
-                // adapt the entries in wallpaper.mCropHints for the actual display
+
+            // A wallpaper with cropHints = Map.of(ORIENTATION_UNKNOWN, rect) is treated like
+            // a wallpaper with cropHints = null and  cropHint = rect.
+            Rect tempCropHint = wallpaper.mCropHints.get(ORIENTATION_UNKNOWN);
+            if (multiCrop() && tempCropHint != null) {
+                wallpaper.cropHint.set(tempCropHint);
+                wallpaper.mCropHints.clear();
+            }
+            if (multiCrop() && wallpaper.mCropHints.size() > 0) {
+                // Some suggested crops per screen orientation were provided,
+                // use them to compute the default crops for this device
+                SparseArray<Rect> defaultCrops = getDefaultCrops(wallpaper.mCropHints, bitmapSize);
+                // Adapt the provided crops to match the actual crops for the default display
                 SparseArray<Rect> updatedCropHints = new SparseArray<>();
                 for (int i = 0; i < wallpaper.mCropHints.size(); i++) {
                     int orientation = wallpaper.mCropHints.keyAt(i);
-                    Rect defaultCrop = defaultDisplayCrops.get(orientation);
+                    Rect defaultCrop = defaultCrops.get(orientation);
                     if (defaultCrop != null) {
                         updatedCropHints.put(orientation, defaultCrop);
                     }
                 }
                 wallpaper.mCropHints = updatedCropHints;
-                cropHint = getTotalCrop(defaultDisplayCrops);
+
+                // Finally, compute the cropHint based on the default crops
+                cropHint = getTotalCrop(defaultCrops);
                 wallpaper.cropHint.set(cropHint);
+                if (DEBUG) {
+                    Slog.d(TAG, "Generated default crops for wallpaper: " + defaultCrops
+                            + " based on suggested crops: " + wallpaper.mCropHints);
+                }
+            } else if (multiCrop()) {
+                // No crops per screen orientation were provided, but an overall cropHint may be
+                // defined in wallpaper.cropHint. Compute the default crops for the sub-image
+                // defined by the cropHint, then recompute the cropHint based on the default crops.
+                // If the cropHint is empty or invalid, ignore it and use the full image.
+                if (wallpaper.cropHint.isEmpty()) wallpaper.cropHint.set(bitmapRect);
+                if (!bitmapRect.contains(wallpaper.cropHint)) {
+                    Slog.w(TAG, "Ignoring wallpaper.cropHint = " + wallpaper.cropHint
+                            + "; not within the bitmap of size " + bitmapSize);
+                    wallpaper.cropHint.set(bitmapRect);
+                }
+                Point cropSize = new Point(wallpaper.cropHint.width(), wallpaper.cropHint.height());
+                SparseArray<Rect> defaultCrops = getDefaultCrops(new SparseArray<>(), cropSize);
+                cropHint = getTotalCrop(defaultCrops);
+                cropHint.offset(wallpaper.cropHint.left, wallpaper.cropHint.top);
+                wallpaper.cropHint.set(cropHint);
+                if (DEBUG) {
+                    Slog.d(TAG, "Generated default crops for wallpaper: " + defaultCrops);
+                }
             } else {
                 cropHint = new Rect(wallpaper.cropHint);
             }
@@ -455,11 +534,11 @@
             }
 
             // Empty crop means use the full image
-            if (cropHint.isEmpty()) {
+            if (!multiCrop() && cropHint.isEmpty()) {
                 cropHint.left = cropHint.top = 0;
                 cropHint.right = options.outWidth;
                 cropHint.bottom = options.outHeight;
-            } else {
+            } else if (!multiCrop()) {
                 // force the crop rect to lie within the measured bounds
                 int dx = cropHint.right > options.outWidth ? options.outWidth - cropHint.right : 0;
                 int dy = cropHint.bottom > options.outHeight
@@ -473,19 +552,19 @@
                 if (cropHint.top < 0) {
                     cropHint.top = 0;
                 }
-
-                // Don't bother cropping if what we're left with is identity
-                needCrop = (options.outHeight > cropHint.height()
-                        || options.outWidth > cropHint.width());
             }
 
+            // Don't bother cropping if what we're left with is identity
+            needCrop = (options.outHeight > cropHint.height()
+                    || options.outWidth > cropHint.width());
+
             // scale if the crop height winds up not matching the recommended metrics
             needScale = cropHint.height() > wpData.mHeight
                     || cropHint.height() > GLHelper.getMaxTextureSize()
                     || cropHint.width() > GLHelper.getMaxTextureSize();
 
             //make sure screen aspect ratio is preserved if width is scaled under screen size
-            if (needScale && !multiCrop) {
+            if (needScale && !multiCrop()) {
                 final float scaleByHeight = (float) wpData.mHeight / (float) cropHint.height();
                 final int newWidth = (int) (cropHint.width() * scaleByHeight);
                 if (newWidth < displayInfo.logicalWidth) {
@@ -543,7 +622,7 @@
                     final Rect estimateCrop = new Rect(cropHint);
                     estimateCrop.scale(1f / options.inSampleSize);
                     float hRatio = (float) wpData.mHeight / estimateCrop.height();
-                    if (multiCrop) {
+                    if (multiCrop()) {
                         // make sure the crop height is at most the display largest dimension
                         hRatio = (float) mWallpaperDisplayHelper.getDefaultDisplayLargestDimension()
                                 / estimateCrop.height();
@@ -557,7 +636,7 @@
                         if (DEBUG) {
                             Slog.w(TAG, "Invalid crop dimensions, trying to adjust.");
                         }
-                        if (multiCrop) {
+                        if (multiCrop()) {
                             // clear custom crop guidelines, fallback to system default
                             wallpaper.mCropHints.clear();
                             generateCropInternal(wallpaper);
@@ -618,7 +697,7 @@
                         final Bitmap finalCrop = Bitmap.createScaledBitmap(cropped,
                                 safeWidth, safeHeight, true);
 
-                        if (multiCrop) {
+                        if (multiCrop()) {
                             wallpaper.mSampleSize =
                                     ((float) cropHint.height()) / finalCrop.getHeight();
                         }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperData.java b/services/core/java/com/android/server/wallpaper/WallpaperData.java
index 02594d2..b792f79 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperData.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperData.java
@@ -172,11 +172,6 @@
     SparseArray<Rect> mCropHints = new SparseArray<>();
 
     /**
-     * cropHints will be ignored if this flag is false
-     */
-    boolean mSupportsMultiCrop;
-
-    /**
      * The phone orientation when the wallpaper was set. Only relevant for image wallpapers
      */
     int mOrientationWhenSet = ORIENTATION_UNKNOWN;
@@ -204,7 +199,6 @@
         if (source.mCropHints != null) {
             this.mCropHints = source.mCropHints.clone();
         }
-        this.mSupportsMultiCrop = source.mSupportsMultiCrop;
         this.allowBackup = source.allowBackup;
         this.primaryColors = source.primaryColors;
         this.mWallpaperDimAmount = source.mWallpaperDimAmount;
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
index 7f53ea3..4aefb54 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperDataParser.java
@@ -324,10 +324,7 @@
                 getAttributeInt(parser, "totalCropTop", 0),
                 getAttributeInt(parser, "totalCropRight", 0),
                 getAttributeInt(parser, "totalCropBottom", 0));
-        wallpaper.mSupportsMultiCrop = multiCrop() && (
-                parser.getAttributeBoolean(null, "supportsMultiCrop", false)
-                || mImageWallpaper.equals(wallpaper.wallpaperComponent));
-        if (wallpaper.mSupportsMultiCrop) {
+        if (multiCrop() && mImageWallpaper.equals(wallpaper.nextWallpaperComponent)) {
             wallpaper.mCropHints = new SparseArray<>();
             for (Pair<Integer, String> pair: screenDimensionPairs()) {
                 Rect cropHint = new Rect(
@@ -342,16 +339,14 @@
             }
             if (wallpaper.mCropHints.size() == 0 && totalCropHint.isEmpty()) {
                 // migration case: the crops per screen orientation are not specified.
-                int orientation = legacyCropHint.width() < legacyCropHint.height()
-                        ? WallpaperManager.PORTRAIT : WallpaperManager.LANDSCAPE;
                 if (!legacyCropHint.isEmpty()) {
-                    wallpaper.mCropHints.put(orientation, legacyCropHint);
+                    wallpaper.cropHint.set(legacyCropHint);
                 }
             } else {
                 wallpaper.cropHint.set(totalCropHint);
             }
             wallpaper.mSampleSize = parser.getAttributeFloat(null, "sampleSize", 1f);
-        } else {
+        } else if (!multiCrop()) {
             wallpaper.cropHint.set(legacyCropHint);
         }
         final DisplayData wpData = mWallpaperDisplayHelper
@@ -467,13 +462,12 @@
         out.startTag(null, tag);
         out.attributeInt(null, "id", wallpaper.wallpaperId);
 
-        out.attributeBoolean(null, "supportsMultiCrop", wallpaper.mSupportsMultiCrop);
-
-        if (multiCrop() && wallpaper.mSupportsMultiCrop) {
+        if (multiCrop() && mImageWallpaper.equals(wallpaper.wallpaperComponent)) {
             if (wallpaper.mCropHints == null) {
                 Slog.e(TAG, "cropHints should not be null when saved");
                 wallpaper.mCropHints = new SparseArray<>();
             }
+            Rect rectToPutInLegacyCrop = new Rect(wallpaper.cropHint);
             for (Pair<Integer, String> pair : screenDimensionPairs()) {
                 Rect cropHint = wallpaper.mCropHints.get(pair.first);
                 if (cropHint == null) continue;
@@ -493,12 +487,14 @@
                     }
                 }
                 if (pair.first == orientationToPutInLegacyCrop) {
-                    out.attributeInt(null, "cropLeft", cropHint.left);
-                    out.attributeInt(null, "cropTop", cropHint.top);
-                    out.attributeInt(null, "cropRight", cropHint.right);
-                    out.attributeInt(null, "cropBottom", cropHint.bottom);
+                    rectToPutInLegacyCrop.set(cropHint);
                 }
             }
+            out.attributeInt(null, "cropLeft", rectToPutInLegacyCrop.left);
+            out.attributeInt(null, "cropTop", rectToPutInLegacyCrop.top);
+            out.attributeInt(null, "cropRight", rectToPutInLegacyCrop.right);
+            out.attributeInt(null, "cropBottom", rectToPutInLegacyCrop.bottom);
+
             out.attributeInt(null, "totalCropLeft", wallpaper.cropHint.left);
             out.attributeInt(null, "totalCropTop", wallpaper.cropHint.top);
             out.attributeInt(null, "totalCropRight", wallpaper.cropHint.right);
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 885baf6..8c4c0de 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -803,7 +803,7 @@
                     null /* options */);
             mWindowManagerInternal.setWallpaperShowWhenLocked(
                     mToken, (wallpaper.mWhich & FLAG_LOCK) != 0);
-            if (multiCrop() && wallpaper.mSupportsMultiCrop) {
+            if (multiCrop() && mImageWallpaper.equals(wallpaper.wallpaperComponent)) {
                 mWindowManagerInternal.setWallpaperCropHints(mToken,
                         mWallpaperCropper.getRelativeCropHints(wallpaper));
             } else {
@@ -1917,11 +1917,17 @@
             final ComponentName component;
             final int finalWhich;
 
-            if ((which & FLAG_LOCK) > 0 && lockWallpaper != null) {
-                clearWallpaperBitmaps(lockWallpaper);
-            }
-            if ((which & FLAG_SYSTEM) > 0) {
-                clearWallpaperBitmaps(wallpaper);
+            // Clear any previous ImageWallpaper related fields
+            List<WallpaperData> toClear = new ArrayList<>();
+            if ((which & FLAG_LOCK) > 0 && lockWallpaper != null) toClear.add(lockWallpaper);
+            if ((which & FLAG_SYSTEM) > 0) toClear.add(wallpaper);
+            for (WallpaperData wallpaperToClear : toClear) {
+                clearWallpaperBitmaps(wallpaperToClear);
+                if (multiCrop()) {
+                    wallpaperToClear.mCropHints.clear();
+                    wallpaperToClear.cropHint.set(0, 0, 0, 0);
+                    wallpaperToClear.mSampleSize = 1;
+                }
             }
 
             // lock only case: set the system wallpaper component to both screens
@@ -2225,7 +2231,9 @@
             checkPermission(READ_WALLPAPER_INTERNAL);
             WallpaperData wallpaper = (which == FLAG_LOCK) ? mLockWallpaperMap.get(userId)
                     : mWallpaperMap.get(userId);
-            if (wallpaper == null || !wallpaper.mSupportsMultiCrop) return null;
+            if (wallpaper == null || !mImageWallpaper.equals(wallpaper.wallpaperComponent)) {
+                return null;
+            }
             SparseArray<Rect> relativeSuggestedCrops =
                     mWallpaperCropper.getRelativeCropHints(wallpaper);
             Point croppedBitmapSize = new Point(
@@ -2255,7 +2263,7 @@
     @Override
     public List<Rect> getFutureBitmapCrops(Point bitmapSize, List<Point> displaySizes,
             int[] screenOrientations, List<Rect> crops) {
-        SparseArray<Rect> cropMap = getCropMap(screenOrientations, crops, ORIENTATION_UNKNOWN);
+        SparseArray<Rect> cropMap = getCropMap(screenOrientations, crops);
         SparseArray<Rect> defaultCrops = mWallpaperCropper.getDefaultCrops(cropMap, bitmapSize);
         List<Rect> result = new ArrayList<>();
         boolean rtl = TextUtils.getLayoutDirectionFromLocale(Locale.getDefault())
@@ -2272,7 +2280,7 @@
             throw new UnsupportedOperationException(
                     "This method should only be called with the multi crop flag enabled");
         }
-        SparseArray<Rect> cropMap = getCropMap(screenOrientations, crops, ORIENTATION_UNKNOWN);
+        SparseArray<Rect> cropMap = getCropMap(screenOrientations, crops);
         SparseArray<Rect> defaultCrops = mWallpaperCropper.getDefaultCrops(cropMap, bitmapSize);
         return WallpaperCropper.getTotalCrop(defaultCrops);
     }
@@ -2860,10 +2868,8 @@
             return null;
         }
 
-        int currentOrientation = mWallpaperDisplayHelper.getDefaultDisplayCurrentOrientation();
-        SparseArray<Rect> cropMap = !multiCrop() ? null
-                : getCropMap(screenOrientations, crops, currentOrientation);
-        Rect cropHint = multiCrop() || crops == null ? null : crops.get(0);
+        SparseArray<Rect> cropMap = !multiCrop() ? null : getCropMap(screenOrientations, crops);
+        Rect cropHint = multiCrop() || crops == null || crops.isEmpty() ? new Rect() : crops.get(0);
         final boolean fromForegroundApp = !multiCrop() ? false
                 : isFromForegroundApp(callingPackage);
 
@@ -2912,12 +2918,15 @@
                     wallpaper.setComplete = completion;
                     wallpaper.fromForegroundApp = multiCrop() ? fromForegroundApp
                             : isFromForegroundApp(callingPackage);
-                    if (!multiCrop()) wallpaper.cropHint.set(cropHint);
-                    if (multiCrop()) wallpaper.mSupportsMultiCrop = true;
-                    if (multiCrop()) wallpaper.mCropHints = cropMap;
+                    wallpaper.cropHint.set(cropHint);
+                    if (multiCrop()) {
+                        wallpaper.mCropHints = cropMap;
+                        wallpaper.mSampleSize = 1f;
+                        wallpaper.mOrientationWhenSet =
+                                mWallpaperDisplayHelper.getDefaultDisplayCurrentOrientation();
+                    }
                     wallpaper.allowBackup = allowBackup;
                     wallpaper.mWallpaperDimAmount = getWallpaperDimAmount();
-                    wallpaper.mOrientationWhenSet = currentOrientation;
                 }
                 return pfd;
             } finally {
@@ -2926,16 +2935,14 @@
         }
     }
 
-    private SparseArray<Rect> getCropMap(int[] screenOrientations, List<Rect> crops,
-            int currentOrientation) {
+    private SparseArray<Rect> getCropMap(int[] screenOrientations, List<Rect> crops) {
         if ((crops == null ^ screenOrientations == null)
                 || (crops != null && crops.size() != screenOrientations.length)) {
             throw new IllegalArgumentException(
                     "Illegal crops/orientations lists: must both be null, or both the same size");
         }
         SparseArray<Rect> cropMap = new SparseArray<>();
-        boolean unknown = false;
-        if (crops != null && crops.size() != 0) {
+        if (crops != null && !crops.isEmpty()) {
             for (int i = 0; i < crops.size(); i++) {
                 Rect crop = crops.get(i);
                 int width = crop.width(), height = crop.height();
@@ -2943,22 +2950,13 @@
                     throw new IllegalArgumentException("Invalid crop rect supplied: " + crop);
                 }
                 int orientation = screenOrientations[i];
-                if (orientation == ORIENTATION_UNKNOWN) {
-                    if (currentOrientation == ORIENTATION_UNKNOWN) {
-                        throw new IllegalArgumentException(
-                                "Invalid orientation: " + ORIENTATION_UNKNOWN);
-                    }
-                    unknown = true;
-                    orientation = currentOrientation;
+                if (orientation == ORIENTATION_UNKNOWN && cropMap.size() > 1) {
+                    throw new IllegalArgumentException("Invalid crops supplied: the UNKNOWN"
+                            + "screen orientation should only be used in a singleton map");
                 }
                 cropMap.put(orientation, crop);
             }
         }
-        if (unknown && cropMap.size() > 1) {
-            throw new IllegalArgumentException("Invalid crops supplied: the UNKNOWN screen "
-                    + "orientation should only be used in a singleton map (in which case it"
-                    + "represents the current orientation of the default display)");
-        }
         return cropMap;
     }
 
@@ -2975,7 +2973,6 @@
         WallpaperData lockWP = new WallpaperData(userId, FLAG_LOCK);
         lockWP.wallpaperId = sysWP.wallpaperId;
         lockWP.cropHint.set(sysWP.cropHint);
-        lockWP.mSupportsMultiCrop = sysWP.mSupportsMultiCrop;
         if (sysWP.mCropHints != null) {
             lockWP.mCropHints = sysWP.mCropHints.clone();
         }
@@ -3096,7 +3093,6 @@
             final long ident = Binder.clearCallingIdentity();
 
             try {
-                newWallpaper.mSupportsMultiCrop = mImageWallpaper.equals(name);
                 newWallpaper.imageWallpaperPending = false;
                 newWallpaper.mWhich = which;
                 newWallpaper.mSystemWasBoth = systemIsBoth;
diff --git a/services/core/java/com/android/server/wearable/RemoteWearableSensingService.java b/services/core/java/com/android/server/wearable/RemoteWearableSensingService.java
index e230b95..6776f26 100644
--- a/services/core/java/com/android/server/wearable/RemoteWearableSensingService.java
+++ b/services/core/java/com/android/server/wearable/RemoteWearableSensingService.java
@@ -20,6 +20,7 @@
 import static android.content.Context.BIND_INCLUDE_CAPABILITIES;
 
 import android.app.wearable.Flags;
+import android.app.wearable.IWearableSensingCallback;
 import android.app.wearable.WearableSensingManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -75,10 +76,14 @@
      * Provides a secure connection to the wearable.
      *
      * @param secureWearableConnection The secure connection to the wearable
-     * @param callback The callback for service status
+     * @param wearableSensingCallback The callback for requests such as openFile from the
+     *     WearableSensingService.
+     * @param statusCallback The callback for service status
      */
     public void provideSecureConnection(
-            ParcelFileDescriptor secureWearableConnection, RemoteCallback callback) {
+            ParcelFileDescriptor secureWearableConnection,
+            IWearableSensingCallback wearableSensingCallback,
+            RemoteCallback statusCallback) {
         if (DEBUG) {
             Slog.i(TAG, "#provideSecureConnection");
         }
@@ -87,7 +92,8 @@
                     TAG,
                     "FLAG_ENABLE_RESTART_WSS_PROCESS is disabled. Do not attempt to restart the"
                         + " WearableSensingService process");
-            provideSecureConnectionInternal(secureWearableConnection, callback);
+            provideSecureConnectionInternal(
+                    secureWearableConnection, wearableSensingCallback, statusCallback);
             return;
         }
         synchronized (mSecureConnectionLock) {
@@ -105,30 +111,37 @@
                             WearableSensingManager.STATUS_CHANNEL_ERROR);
                 }
                 mNextSecureConnectionContext =
-                        new SecureWearableConnectionContext(secureWearableConnection, callback);
+                        new SecureWearableConnectionContext(
+                                secureWearableConnection, wearableSensingCallback, statusCallback);
                 return;
             }
             if (!mSecureConnectionProvided) {
                 // no need to kill the process
-                provideSecureConnectionInternal(secureWearableConnection, callback);
+                provideSecureConnectionInternal(
+                        secureWearableConnection, wearableSensingCallback, statusCallback);
                 mSecureConnectionProvided = true;
                 return;
             }
             mNextSecureConnectionContext =
-                    new SecureWearableConnectionContext(secureWearableConnection, callback);
+                    new SecureWearableConnectionContext(
+                            secureWearableConnection, wearableSensingCallback, statusCallback);
             // Killing the process causes the binder to die. #binderDied will then be triggered
             killWearableSensingServiceProcess();
         }
     }
 
     private void provideSecureConnectionInternal(
-            ParcelFileDescriptor secureWearableConnection, RemoteCallback callback) {
+            ParcelFileDescriptor secureWearableConnection,
+            IWearableSensingCallback wearableSensingCallback,
+            RemoteCallback statusCallback) {
         Slog.d(TAG, "Providing secure wearable connection.");
         var unused =
                 post(
                         service -> {
                             service.provideSecureConnection(
-                                    secureWearableConnection, callback);
+                                    secureWearableConnection,
+                                    wearableSensingCallback,
+                                    statusCallback);
                             try {
                                 // close the local fd after it has been sent to the WSS process
                                 secureWearableConnection.close();
@@ -146,6 +159,7 @@
                 // This will call #post, which will recreate the process and bind to it
                 provideSecureConnectionInternal(
                         mNextSecureConnectionContext.mSecureConnection,
+                        mNextSecureConnectionContext.mWearableSensingCallback,
                         mNextSecureConnectionContext.mStatusCallback);
                 mNextSecureConnectionContext = null;
             } else {
@@ -164,23 +178,29 @@
      * Provides the implementation a data stream to the wearable.
      *
      * @param parcelFileDescriptor The data stream to the wearable
+     * @param wearableSensingCallback The callback for requests such as openFile from the
+     *     WearableSensingService.
      * @param callback The callback for service status
      */
-    public void provideDataStream(ParcelFileDescriptor parcelFileDescriptor,
+    public void provideDataStream(
+            ParcelFileDescriptor parcelFileDescriptor,
+            IWearableSensingCallback wearableSensingCallback,
             RemoteCallback callback) {
         if (DEBUG) {
             Slog.i(TAG, "Providing data stream.");
         }
-        var unused = post(
-                service -> {
-                    service.provideDataStream(parcelFileDescriptor, callback);
-                    try {
-                        // close the local fd after it has been sent to the WSS process
-                        parcelFileDescriptor.close();
-                    } catch (IOException ex) {
-                        Slog.w(TAG, "Unable to close the local parcelFileDescriptor.", ex);
-                    }
-                });
+        var unused =
+                post(
+                        service -> {
+                            service.provideDataStream(
+                                    parcelFileDescriptor, wearableSensingCallback, callback);
+                            try {
+                                // close the local fd after it has been sent to the WSS process
+                                parcelFileDescriptor.close();
+                            } catch (IOException ex) {
+                                Slog.w(TAG, "Unable to close the local parcelFileDescriptor.", ex);
+                            }
+                        });
     }
 
     /**
@@ -308,12 +328,16 @@
 
     private static class SecureWearableConnectionContext {
         final ParcelFileDescriptor mSecureConnection;
+        final IWearableSensingCallback mWearableSensingCallback;
         final RemoteCallback mStatusCallback;
 
         SecureWearableConnectionContext(
-                ParcelFileDescriptor secureWearableConnection, RemoteCallback statusCallback) {
-            this.mSecureConnection = secureWearableConnection;
-            this.mStatusCallback = statusCallback;
+                ParcelFileDescriptor secureWearableConnection,
+                IWearableSensingCallback wearableSensingCallback,
+                RemoteCallback statusCallback) {
+            mSecureConnection = secureWearableConnection;
+            mWearableSensingCallback = wearableSensingCallback;
+            mStatusCallback = statusCallback;
         }
     }
 }
diff --git a/services/core/java/com/android/server/wearable/WearableSensingManagerPerUserService.java b/services/core/java/com/android/server/wearable/WearableSensingManagerPerUserService.java
index 34b9fe96..eb170b7 100644
--- a/services/core/java/com/android/server/wearable/WearableSensingManagerPerUserService.java
+++ b/services/core/java/com/android/server/wearable/WearableSensingManagerPerUserService.java
@@ -25,10 +25,12 @@
 import android.app.AppGlobals;
 import android.app.ambientcontext.AmbientContextEvent;
 import android.app.wearable.Flags;
+import android.app.wearable.IWearableSensingCallback;
 import android.app.wearable.WearableSensingManager;
 import android.companion.CompanionDeviceManager;
 import android.content.ComponentName;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ServiceInfo;
 import android.os.Binder;
 import android.os.Bundle;
@@ -46,6 +48,7 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.infra.AndroidFuture;
 import com.android.server.LocalServices;
 import com.android.server.infra.AbstractPerUserSystemService;
 
@@ -61,12 +64,17 @@
                 WearableSensingManagerService> {
     private static final String TAG = WearableSensingManagerPerUserService.class.getSimpleName();
 
+    private final PackageManagerInternal mPackageManagerInternal;
+
     @Nullable
     @VisibleForTesting
     RemoteWearableSensingService mRemoteService;
 
     @Nullable private VoiceInteractionManagerInternal mVoiceInteractionManagerInternal;
+
+    @GuardedBy("mLock")
     private ComponentName mComponentName;
+
     private final Object mSecureChannelLock = new Object();
 
     @GuardedBy("mSecureChannelLock")
@@ -75,6 +83,7 @@
     WearableSensingManagerPerUserService(
             @NonNull WearableSensingManagerService master, Object lock, @UserIdInt int userId) {
         super(master, lock, userId);
+        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
     }
 
     public static void notifyStatusCallback(RemoteCallback statusCallback, int statusCode) {
@@ -190,14 +199,19 @@
      * service.
      */
     public void onProvideConnection(
-            ParcelFileDescriptor wearableConnection, RemoteCallback callback) {
+            ParcelFileDescriptor wearableConnection,
+            IWearableSensingCallback wearableSensingCallback,
+            RemoteCallback statusCallback) {
         Slog.i(TAG, "onProvideConnection in per user service.");
+        final IWearableSensingCallback wrappedWearableSensingCallback;
         synchronized (mLock) {
             if (!setUpServiceIfNeeded()) {
                 Slog.w(TAG, "Detection service is not available at this moment.");
-                notifyStatusCallback(callback, WearableSensingManager.STATUS_SERVICE_UNAVAILABLE);
+                notifyStatusCallback(
+                        statusCallback, WearableSensingManager.STATUS_SERVICE_UNAVAILABLE);
                 return;
             }
+            wrappedWearableSensingCallback = wrapWearableSensingCallback(wearableSensingCallback);
         }
         synchronized (mSecureChannelLock) {
             if (mSecureChannel != null) {
@@ -218,7 +232,9 @@
                                         synchronized (mLock) {
                                             ensureRemoteServiceInitiated();
                                             mRemoteService.provideSecureConnection(
-                                                    secureTransport, callback);
+                                                    secureTransport,
+                                                    wrappedWearableSensingCallback,
+                                                    statusCallback);
                                         }
                                     }
 
@@ -237,7 +253,7 @@
                                         }
                                         if (Flags.enableProvideWearableConnectionApi()) {
                                             notifyStatusCallback(
-                                                    callback,
+                                                    statusCallback,
                                                     WearableSensingManager.STATUS_CHANNEL_ERROR);
                                         }
                                     }
@@ -246,7 +262,8 @@
             } catch (IOException ex) {
                 Slog.e(TAG, "Unable to create the secure channel.", ex);
                 if (Flags.enableProvideWearableConnectionApi()) {
-                    notifyStatusCallback(callback, WearableSensingManager.STATUS_CHANNEL_ERROR);
+                    notifyStatusCallback(
+                            statusCallback, WearableSensingManager.STATUS_CHANNEL_ERROR);
                 }
             }
         }
@@ -257,17 +274,22 @@
      */
     public void onProvideDataStream(
             ParcelFileDescriptor parcelFileDescriptor,
-            RemoteCallback callback) {
+            @Nullable IWearableSensingCallback wearableSensingCallback,
+            RemoteCallback statusCallback) {
         Slog.i(TAG, "onProvideDataStream in per user service.");
         synchronized (mLock) {
             if (!setUpServiceIfNeeded()) {
                 Slog.w(TAG, "Detection service is not available at this moment.");
-                notifyStatusCallback(callback, WearableSensingManager.STATUS_SERVICE_UNAVAILABLE);
+                notifyStatusCallback(
+                        statusCallback, WearableSensingManager.STATUS_SERVICE_UNAVAILABLE);
                 return;
             }
             Slog.i(TAG, "calling over to remote servvice.");
             ensureRemoteServiceInitiated();
-            mRemoteService.provideDataStream(parcelFileDescriptor, callback);
+            mRemoteService.provideDataStream(
+                    parcelFileDescriptor,
+                    wrapWearableSensingCallback(wearableSensingCallback),
+                    statusCallback);
         }
     }
 
@@ -456,4 +478,37 @@
             }
         };
     }
+
+    @GuardedBy("mLock")
+    private @Nullable IWearableSensingCallback wrapWearableSensingCallback(
+            IWearableSensingCallback callbackFromAppProcess) {
+        if (callbackFromAppProcess == null) {
+            return null;
+        }
+        if (mComponentName == null) {
+            Slog.w(TAG, "Cannot create WearableSensingCallback because mComponentName is null.");
+            return null;
+        }
+        if (Binder.getCallingUid()
+                != mPackageManagerInternal.getPackageUid(
+                        mComponentName.getPackageName(), /* flags= */ 0, mUserId)) {
+            Slog.d(
+                    TAG,
+                    "Caller does not belong to the package that provides the WearableSensingService"
+                            + " implementation. Do not forward WearableSensingCallback to"
+                            + " WearableSensingService.");
+            return null;
+        }
+        return new IWearableSensingCallback.Stub() {
+            @Override
+            public void openFile(
+                    String filename,
+                    AndroidFuture<ParcelFileDescriptor> futureFromWearableSensingService)
+                    throws RemoteException {
+                // TODO(b/331395522): Intercept the PFD received from the app process and verify it
+                // is read-only
+                callbackFromAppProcess.openFile(filename, futureFromWearableSensingService);
+            }
+        };
+    }
 }
diff --git a/services/core/java/com/android/server/wearable/WearableSensingManagerService.java b/services/core/java/com/android/server/wearable/WearableSensingManagerService.java
index 8742ab1..110100a 100644
--- a/services/core/java/com/android/server/wearable/WearableSensingManagerService.java
+++ b/services/core/java/com/android/server/wearable/WearableSensingManagerService.java
@@ -20,11 +20,13 @@
 
 import android.Manifest;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.ActivityOptions;
 import android.app.BroadcastOptions;
 import android.app.PendingIntent;
 import android.app.ambientcontext.AmbientContextEvent;
+import android.app.wearable.IWearableSensingCallback;
 import android.app.wearable.IWearableSensingManager;
 import android.app.wearable.WearableSensingDataRequest;
 import android.app.wearable.WearableSensingManager;
@@ -213,21 +215,37 @@
         return null;
     }
 
+    /**
+     * Provides a data stream to the WearableSensingService.
+     *
+     * <p>This method is only called from adb command via {@link WearableSensingShellCommand}.
+     */
     @VisibleForTesting
-    void provideDataStream(@UserIdInt int userId, ParcelFileDescriptor parcelFileDescriptor,
+    void provideDataStream(
+            @UserIdInt int userId,
+            ParcelFileDescriptor parcelFileDescriptor,
             RemoteCallback callback) {
         synchronized (mLock) {
             final WearableSensingManagerPerUserService mService = getServiceForUserLocked(userId);
             if (mService != null) {
-                mService.onProvideDataStream(parcelFileDescriptor, callback);
+                mService.onProvideDataStream(
+                        parcelFileDescriptor, /* wearableSensingCallback= */ null, callback);
             } else {
                 Slog.w(TAG, "Service not available.");
             }
         }
     }
 
+    /**
+     * Provides data to the WearableSensingService.
+     *
+     * <p>This method is only called from adb command via {@link WearableSensingShellCommand}.
+     */
     @VisibleForTesting
-    void provideData(@UserIdInt int userId, PersistableBundle data, SharedMemory sharedMemory,
+    void provideData(
+            @UserIdInt int userId,
+            PersistableBundle data,
+            SharedMemory sharedMemory,
             RemoteCallback callback) {
         synchronized (mLock) {
             final WearableSensingManagerPerUserService mService = getServiceForUserLocked(userId);
@@ -400,40 +418,48 @@
 
         @Override
         public void provideConnection(
-                ParcelFileDescriptor wearableConnection, RemoteCallback callback) {
+                ParcelFileDescriptor wearableConnection,
+                IWearableSensingCallback wearableSensingCallback,
+                RemoteCallback statusCallback) {
             Slog.i(TAG, "WearableSensingManagerInternal provideConnection.");
             Objects.requireNonNull(wearableConnection);
-            Objects.requireNonNull(callback);
+            Objects.requireNonNull(statusCallback);
             mContext.enforceCallingOrSelfPermission(
                     Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE, TAG);
             if (!mIsServiceEnabled) {
                 Slog.w(TAG, "Service not available.");
                 WearableSensingManagerPerUserService.notifyStatusCallback(
-                        callback, WearableSensingManager.STATUS_SERVICE_UNAVAILABLE);
+                        statusCallback, WearableSensingManager.STATUS_SERVICE_UNAVAILABLE);
                 return;
             }
             callPerUserServiceIfExist(
-                    service -> service.onProvideConnection(wearableConnection, callback),
-                    callback);
+                    service ->
+                            service.onProvideConnection(
+                                    wearableConnection, wearableSensingCallback, statusCallback),
+                    statusCallback);
         }
 
         @Override
         public void provideDataStream(
-                ParcelFileDescriptor parcelFileDescriptor, RemoteCallback callback) {
+                ParcelFileDescriptor parcelFileDescriptor,
+                @Nullable IWearableSensingCallback wearableSensingCallback,
+                RemoteCallback statusCallback) {
             Slog.i(TAG, "WearableSensingManagerInternal provideDataStream.");
             Objects.requireNonNull(parcelFileDescriptor);
-            Objects.requireNonNull(callback);
+            Objects.requireNonNull(statusCallback);
             mContext.enforceCallingOrSelfPermission(
                     Manifest.permission.MANAGE_WEARABLE_SENSING_SERVICE, TAG);
             if (!mIsServiceEnabled) {
                 Slog.w(TAG, "Service not available.");
-                WearableSensingManagerPerUserService.notifyStatusCallback(callback,
-                        WearableSensingManager.STATUS_SERVICE_UNAVAILABLE);
+                WearableSensingManagerPerUserService.notifyStatusCallback(
+                        statusCallback, WearableSensingManager.STATUS_SERVICE_UNAVAILABLE);
                 return;
             }
             callPerUserServiceIfExist(
-                    service -> service.onProvideDataStream(parcelFileDescriptor, callback),
-                    callback);
+                    service ->
+                            service.onProvideDataStream(
+                                    parcelFileDescriptor, wearableSensingCallback, statusCallback),
+                    statusCallback);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java
index c6e8eb8..5e34596 100644
--- a/services/core/java/com/android/server/webkit/SystemImpl.java
+++ b/services/core/java/com/android/server/webkit/SystemImpl.java
@@ -310,8 +310,10 @@
 
         ArrayList<String> apksToPin = new ArrayList<>();
         boolean pinSharedFirst = appInfo.metaData.getBoolean("PIN_SHARED_LIBS_FIRST", true);
-        for (String sharedLib : appInfo.sharedLibraryFiles) {
-            apksToPin.add(sharedLib);
+        if (appInfo.sharedLibraryFiles != null) {
+            for (String sharedLib : appInfo.sharedLibraryFiles) {
+                apksToPin.add(sharedLib);
+            }
         }
         apksToPin.add(appInfo.sourceDir);
         if (!pinSharedFirst) {
diff --git a/services/core/java/com/android/server/webkit/flags.aconfig b/services/core/java/com/android/server/webkit/flags.aconfig
index 2afbcd6..84dc1d7 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/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 6f16d2c..2b43326 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -24,6 +24,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
+import static android.view.WindowManager.TRANSIT_FLAG_IS_RECENTS;
 
 import static com.android.internal.util.DumpUtils.dumpSparseArray;
 import static com.android.internal.util.DumpUtils.dumpSparseArrayValues;
@@ -93,6 +94,8 @@
 import android.view.ViewConfiguration;
 import android.view.WindowInfo;
 import android.view.WindowManager;
+import android.view.WindowManager.TransitionFlags;
+import android.view.WindowManager.TransitionType;
 import android.view.WindowManagerPolicyConstants;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
@@ -357,14 +360,15 @@
         // Not relevant for the window observer.
     }
 
-    void onWMTransition(int displayId, @WindowManager.TransitionType int type) {
+    void onWMTransition(int displayId, @TransitionType int type, @TransitionFlags int flags) {
         if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
-            mAccessibilityTracing.logTrace(TAG + ".onAppWindowTransition",
-                    FLAGS_MAGNIFICATION_CALLBACK, "displayId=" + displayId + "; type=" + type);
+            mAccessibilityTracing.logTrace(TAG + ".onWMTransition",
+                    FLAGS_MAGNIFICATION_CALLBACK,
+                    "displayId=" + displayId + "; type=" + type + "; flags=" + flags);
         }
         final DisplayMagnifier displayMagnifier = mDisplayMagnifiers.get(displayId);
         if (displayMagnifier != null) {
-            displayMagnifier.onWMTransition(displayId, type);
+            displayMagnifier.onWMTransition(displayId, type, flags);
         }
         // Not relevant for the window observer.
     }
@@ -574,6 +578,11 @@
     void onFocusChanged(InputTarget lastTarget, InputTarget newTarget) {
         if (lastTarget != null) {
             mFocusedWindow.remove(lastTarget.getDisplayId());
+            final DisplayMagnifier displayMagnifier =
+                    mDisplayMagnifiers.get(lastTarget.getDisplayId());
+            if (displayMagnifier != null) {
+                displayMagnifier.onFocusLost(lastTarget);
+            }
         }
         if (newTarget != null) {
             int displayId = newTarget.getDisplayId();
@@ -625,6 +634,7 @@
         private final AccessibilityControllerInternalImpl mAccessibilityTracing;
 
         private final MagnificationCallbacks mCallbacks;
+        private final UserContextChangedNotifier mUserContextChangedNotifier;
 
         private final long mLongAnimationDuration;
 
@@ -653,6 +663,7 @@
             mDisplayContent = displayContent;
             mDisplay = display;
             mHandler = new MyHandler(mService.mH.getLooper());
+            mUserContextChangedNotifier = new UserContextChangedNotifier(mHandler);
             mMagnifiedViewport = Flags.alwaysDrawMagnificationFullscreenBorder()
                     ? null : new MagnifiedViewport();
             mAccessibilityTracing =
@@ -764,40 +775,43 @@
                         + " displayId: " + displayId);
             }
             final boolean isMagnifierActivated = isFullscreenMagnificationActivated();
-            if (isMagnifierActivated) {
-                switch (transition) {
-                    case WindowManager.TRANSIT_OLD_ACTIVITY_OPEN:
-                    case WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN:
-                    case WindowManager.TRANSIT_OLD_TASK_OPEN:
-                    case WindowManager.TRANSIT_OLD_TASK_TO_FRONT:
-                    case WindowManager.TRANSIT_OLD_WALLPAPER_OPEN:
-                    case WindowManager.TRANSIT_OLD_WALLPAPER_CLOSE:
-                    case WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_OPEN: {
-                        mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_USER_CONTEXT_CHANGED);
-                    }
+            if (!isMagnifierActivated) {
+                return;
+            }
+            switch (transition) {
+                case WindowManager.TRANSIT_OLD_ACTIVITY_OPEN:
+                case WindowManager.TRANSIT_OLD_TASK_FRAGMENT_OPEN:
+                case WindowManager.TRANSIT_OLD_TASK_OPEN:
+                case WindowManager.TRANSIT_OLD_TASK_TO_FRONT:
+                case WindowManager.TRANSIT_OLD_WALLPAPER_OPEN:
+                case WindowManager.TRANSIT_OLD_WALLPAPER_CLOSE:
+                case WindowManager.TRANSIT_OLD_WALLPAPER_INTRA_OPEN: {
+                    mUserContextChangedNotifier.onAppWindowTransition(transition);
                 }
             }
         }
 
-        void onWMTransition(int displayId, @WindowManager.TransitionType int type) {
+        void onWMTransition(int displayId, @TransitionType int type, @TransitionFlags int flags) {
             if (mAccessibilityTracing.isTracingEnabled(FLAGS_MAGNIFICATION_CALLBACK)) {
                 mAccessibilityTracing.logTrace(LOG_TAG + ".onWMTransition",
-                        FLAGS_MAGNIFICATION_CALLBACK, "displayId=" + displayId + "; type=" + type);
+                        FLAGS_MAGNIFICATION_CALLBACK,
+                        "displayId=" + displayId + "; type=" + type + "; flags=" + flags);
             }
             if (DEBUG_WINDOW_TRANSITIONS) {
                 Slog.i(LOG_TAG, "Window transition: " + WindowManager.transitTypeToString(type)
                         + " displayId: " + displayId);
             }
             final boolean isMagnifierActivated = isFullscreenMagnificationActivated();
-            if (isMagnifierActivated) {
-                // All opening/closing situations.
-                switch (type) {
-                    case WindowManager.TRANSIT_OPEN:
-                    case WindowManager.TRANSIT_TO_FRONT:
-                    case WindowManager.TRANSIT_CLOSE:
-                    case WindowManager.TRANSIT_TO_BACK:
-                        mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_USER_CONTEXT_CHANGED);
-                }
+            if (!isMagnifierActivated) {
+                return;
+            }
+            // All opening/closing situations.
+            switch (type) {
+                case WindowManager.TRANSIT_OPEN:
+                case WindowManager.TRANSIT_TO_FRONT:
+                case WindowManager.TRANSIT_CLOSE:
+                case WindowManager.TRANSIT_TO_BACK:
+                    mUserContextChangedNotifier.onWMTransition(type, flags);
             }
         }
 
@@ -813,13 +827,14 @@
                         + " displayId: " + windowState.getDisplayId());
             }
             final boolean isMagnifierActivated = isFullscreenMagnificationActivated();
+            if (!isMagnifierActivated || !windowState.shouldMagnify()) {
+                return;
+            }
+            mUserContextChangedNotifier.onWindowTransition(windowState, transition);
             final int type = windowState.mAttrs.type;
             switch (transition) {
                 case WindowManagerPolicy.TRANSIT_ENTER:
                 case WindowManagerPolicy.TRANSIT_SHOW: {
-                    if (!isMagnifierActivated || !windowState.shouldMagnify()) {
-                        break;
-                    }
                     switch (type) {
                         case WindowManager.LayoutParams.TYPE_APPLICATION:
                         case WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION:
@@ -859,6 +874,14 @@
             }
         }
 
+        void onFocusLost(InputTarget target) {
+            final boolean isMagnifierActivated = isFullscreenMagnificationActivated();
+            if (!isMagnifierActivated) {
+                return;
+            }
+            mUserContextChangedNotifier.onFocusLost(target);
+        }
+
         void getMagnifiedFrameInContentCoords(Rect rect) {
             mMagnificationRegion.getBounds(rect);
             rect.offset((int) -mMagnificationSpec.offsetX, (int) -mMagnificationSpec.offsetY);
@@ -1584,6 +1607,65 @@
                 }
             }
         }
+
+        private class UserContextChangedNotifier {
+
+            private final Handler mHandler;
+
+            private boolean mHasDelayedNotificationForRecentsToFrontTransition;
+
+            UserContextChangedNotifier(Handler handler) {
+                mHandler = handler;
+            }
+
+            void onAppWindowTransition(int transition) {
+                sendUserContextChangedNotification();
+            }
+
+            // For b/324949652, if the onWMTransition callback is triggered when the finger down
+            // event on navigation bar to bring the recents window to front, we'll delay the
+            // notifying of the context changed, then send it if there is a following onFocusChanged
+            // callback triggered. Before the onFocusChanged, if there are some other transitions
+            // causing the notifying, or the recents/home window is removed, then we won't need the
+            // delayed notification anymore.
+            void onWMTransition(@TransitionType int type, @TransitionFlags int flags) {
+                if (Flags.delayNotificationToMagnificationWhenRecentsWindowToFrontTransition()
+                        && type == WindowManager.TRANSIT_TO_FRONT
+                        && (flags & TRANSIT_FLAG_IS_RECENTS) != 0) {
+                    // Delay the recents to front transition notification then send after if needed.
+                    mHasDelayedNotificationForRecentsToFrontTransition = true;
+                } else {
+                    sendUserContextChangedNotification();
+                }
+            }
+
+            void onWindowTransition(WindowState windowState, int transition) {
+                // If there is a delayed notification for recents to front transition but the
+                // home/recents window has been removed from screen, the delayed notification is not
+                // needed anymore.
+                if (transition == WindowManagerPolicy.TRANSIT_EXIT
+                        && windowState.isActivityTypeHomeOrRecents()
+                        && mHasDelayedNotificationForRecentsToFrontTransition) {
+                    mHasDelayedNotificationForRecentsToFrontTransition = false;
+                }
+            }
+
+            void onFocusLost(InputTarget target) {
+                // If there is a delayed notification for recents to front transition and
+                // onFocusLost is triggered, we assume that the users leave current window to
+                // the home/recents window, thus we'll need to send the delayed notification.
+                if (mHasDelayedNotificationForRecentsToFrontTransition) {
+                    sendUserContextChangedNotification();
+                }
+            }
+
+            private void sendUserContextChangedNotification() {
+                // Since the context changed will be notified, the delayed notification is
+                // not needed anymore.
+                mHasDelayedNotificationForRecentsToFrontTransition = false;
+                mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_USER_CONTEXT_CHANGED);
+            }
+        }
     }
 
     static boolean isUntouchableNavigationBar(WindowState windowState,
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index 981c4c0..fe4522a 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -1254,14 +1254,16 @@
     private static void executeMultiWindowFullscreenRequest(int fullscreenRequest, Task requester) {
         final int targetWindowingMode;
         if (fullscreenRequest == FULLSCREEN_MODE_REQUEST_ENTER) {
-            requester.mMultiWindowRestoreWindowingMode =
-                    requester.getRequestedOverrideWindowingMode();
+            final int restoreWindowingMode = requester.getRequestedOverrideWindowingMode();
             targetWindowingMode = WINDOWING_MODE_FULLSCREEN;
+            requester.setWindowingMode(targetWindowingMode);
+            // The restore windowing mode must be set after the windowing mode is set since
+            // Task#setWindowingMode resets the restore windowing mode to WINDOWING_MODE_INVALID.
+            requester.mMultiWindowRestoreWindowingMode = restoreWindowingMode;
         } else {
             targetWindowingMode = requester.mMultiWindowRestoreWindowingMode;
-            requester.mMultiWindowRestoreWindowingMode = INVALID_WINDOWING_MODE;
+            requester.setWindowingMode(targetWindowingMode);
         }
-        requester.setWindowingMode(targetWindowingMode);
         if (targetWindowingMode == WINDOWING_MODE_FULLSCREEN) {
             requester.setBounds(null);
         }
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index baf274d..4036d55 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -819,12 +819,6 @@
     @Nullable
     private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio;
 
-    // Bounds populated in resolveAspectRatioRestriction when this activity is letterboxed for
-    // aspect ratio. If not null, they are used as parent container in
-    // resolveSizeCompatModeConfiguration and in a constructor of CompatDisplayInsets.
-    @Nullable
-    private Rect mLetterboxBoundsForAspectRatio;
-
     // Whether the activity is eligible to be letterboxed for fixed orientation with respect to its
     // requested orientation, even when it's letterbox for another reason (e.g., size compat mode)
     // and therefore #isLetterboxedForFixedOrientationAndAspectRatio returns false.
@@ -3204,10 +3198,18 @@
         if (!Flags.activityWindowInfoFlag() || !isAttached()) {
             return mTmpActivityWindowInfo;
         }
-        mTmpActivityWindowInfo.set(
-                isEmbeddedInHostContainer(),
-                getTask().getBounds(),
-                getTaskFragment().getBounds());
+        if (isFixedRotationTransforming()) {
+            // Fixed rotation only applied to fullscreen activity, thus using the activity bounds
+            // for Task/TaskFragment so that it is "pre-rotated" and in sync with the Configuration
+            // update.
+            final Rect bounds = getBounds();
+            mTmpActivityWindowInfo.set(false /* isEmbedded */, bounds, bounds);
+        } else {
+            mTmpActivityWindowInfo.set(
+                    isEmbeddedInHostContainer(),
+                    getTask().getBounds(),
+                    getTaskFragment().getBounds());
+        }
         return mTmpActivityWindowInfo;
     }
 
@@ -8427,14 +8429,10 @@
                     fullConfig.windowConfiguration.getRotation());
         }
 
-        final Rect letterboxedContainerBounds =
-                mLetterboxBoundsForFixedOrientationAndAspectRatio != null
-                ? mLetterboxBoundsForFixedOrientationAndAspectRatio
-                : mLetterboxBoundsForAspectRatio;
-
         // The role of CompatDisplayInsets is like the override bounds.
         mCompatDisplayInsets =
-                new CompatDisplayInsets(mDisplayContent, this, letterboxedContainerBounds);
+                new CompatDisplayInsets(
+                        mDisplayContent, this, mLetterboxBoundsForFixedOrientationAndAspectRatio);
     }
 
     private void clearSizeCompatModeAttributes() {
@@ -8506,7 +8504,6 @@
         mIsAspectRatioApplied = false;
         mIsEligibleForFixedOrientationLetterbox = false;
         mLetterboxBoundsForFixedOrientationAndAspectRatio = null;
-        mLetterboxBoundsForAspectRatio = null;
 
         // Can't use resolvedConfig.windowConfiguration.getWindowingMode() because it can be
         // different from windowing mode of the task (PiP) during transition from fullscreen to PiP
@@ -8545,11 +8542,9 @@
                 getTaskFragment().computeConfigResourceOverrides(resolvedConfig,
                         newParentConfiguration);
             }
-        }
         // If activity in fullscreen mode is letterboxed because of fixed orientation then bounds
-        // are already calculated in resolveFixedOrientationConfiguration, or if in size compat
-        // mode, it should already be calculated in resolveSizeCompatModeConfiguration
-        if (!isLetterboxedForFixedOrientationAndAspectRatio() && !mInSizeCompatModeForBounds) {
+        // are already calculated in resolveFixedOrientationConfiguration.
+        } else if (!isLetterboxedForFixedOrientationAndAspectRatio()) {
             resolveAspectRatioRestriction(newParentConfiguration);
         }
 
@@ -9043,8 +9038,7 @@
         }
         final CompatDisplayInsets compatDisplayInsets = getCompatDisplayInsets();
 
-        if (compatDisplayInsets != null
-                && !compatDisplayInsets.mIsInFixedOrientationOrAspectRatioLetterbox) {
+        if (compatDisplayInsets != null && !compatDisplayInsets.mIsInFixedOrientationLetterbox) {
             // App prefers to keep its original size.
             // If the size compat is from previous fixed orientation letterboxing, we may want to
             // have fixed orientation letterbox again, otherwise it will show the size compat
@@ -9176,7 +9170,6 @@
             // restrict, the bounds should be the requested override bounds.
             getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration,
                     getFixedRotationTransformDisplayInfo());
-            mLetterboxBoundsForAspectRatio = new Rect(resolvedBounds);
         }
     }
 
@@ -10741,10 +10734,10 @@
         /** Whether the {@link Task} windowingMode represents a floating window*/
         final boolean mIsFloating;
         /**
-         * Whether is letterboxed because of fixed orientation or aspect ratio when the
-         * unresizable activity is first shown.
+         * Whether is letterboxed because of fixed orientation when the unresizable activity is
+         * first shown.
          */
-        final boolean mIsInFixedOrientationOrAspectRatioLetterbox;
+        final boolean mIsInFixedOrientationLetterbox;
         /**
          * The nonDecorInsets for each rotation. Includes the navigation bar and cutout insets. It
          * is used to compute the appBounds.
@@ -10759,7 +10752,7 @@
 
         /** Constructs the environment to simulate the bounds behavior of the given container. */
         CompatDisplayInsets(DisplayContent display, ActivityRecord container,
-                @Nullable Rect letterboxedContainerBounds) {
+                @Nullable Rect fixedOrientationBounds) {
             mOriginalRotation = display.getRotation();
             mIsFloating = container.getWindowConfiguration().tasksAreFloating();
             mOriginalRequestedOrientation = container.getRequestedConfigurationOrientation();
@@ -10774,21 +10767,22 @@
                     mNonDecorInsets[rotation] = emptyRect;
                     mStableInsets[rotation] = emptyRect;
                 }
-                mIsInFixedOrientationOrAspectRatioLetterbox = false;
+                mIsInFixedOrientationLetterbox = false;
                 return;
             }
 
             final Task task = container.getTask();
 
-            mIsInFixedOrientationOrAspectRatioLetterbox = letterboxedContainerBounds != null;
+            mIsInFixedOrientationLetterbox = fixedOrientationBounds != null;
+
             // Store the bounds of the Task for the non-resizable activity to use in size compat
             // mode so that the activity will not be resized regardless the windowing mode it is
             // currently in.
-            // When an activity needs to be letterboxed because of fixed orientation or aspect
-            // ratio, use resolved bounds instead of task bounds since the activity will be
-            // displayed within these even if it is in size compat mode.
-            final Rect filledContainerBounds = mIsInFixedOrientationOrAspectRatioLetterbox
-                    ? letterboxedContainerBounds
+            // When an activity needs to be letterboxed because of fixed orientation, use fixed
+            // orientation bounds instead of task bounds since the activity will be displayed
+            // within these even if it is in size compat mode.
+            final Rect filledContainerBounds = mIsInFixedOrientationLetterbox
+                    ? fixedOrientationBounds
                     : task != null ? task.getBounds() : display.getBounds();
             final int filledContainerRotation = task != null
                     ? task.getConfiguration().windowConfiguration.getRotation()
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 38f0587a..354cab3 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2160,19 +2160,6 @@
         return rect;
     }
 
-    @Override
-    public ActivityManager.TaskDescription getTaskDescription(int id) {
-        synchronized (mGlobalLock) {
-            enforceTaskPermission("getTaskDescription()");
-            final Task tr = mRootWindowContainer.anyTaskForId(id,
-                    MATCH_ATTACHED_TASK_OR_RECENT_TASKS);
-            if (tr != null) {
-                return tr.getTaskDescription();
-            }
-        }
-        return null;
-    }
-
     /**
      * Sets the locusId for a particular activity.
      *
@@ -3072,8 +3059,33 @@
 
     @Override
     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
-        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
-                userId, "getTaskDescriptionIcon");
+        final int callingUid = Binder.getCallingUid();
+        // Verify that the caller can make the request for the given userId
+        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
+                "getTaskDescriptionIcon");
+        synchronized (mGlobalLock) {
+            // Verify that the caller can make the request for given icon file path
+            final ActivityRecord matchingActivity = mRootWindowContainer.getActivity(
+                    r -> {
+                        if (r.taskDescription == null
+                                || r.taskDescription.getIconFilename() == null) {
+                            return false;
+                        }
+                        return r.taskDescription.getIconFilename().equals(filePath);
+                    });
+            if (matchingActivity == null || (matchingActivity.getUid() != callingUid)) {
+                // Caller UID doesn't match the requested Activity's UID, check if caller is
+                // privileged
+                try {
+                    enforceActivityTaskPermission("getTaskDescriptionIcon");
+                } catch (SecurityException e) {
+                    Slog.w(TAG, "getTaskDescriptionIcon(): request (callingUid=" + callingUid
+                            + ", filePath=" + filePath + ", user=" + userId + ") doesn't match any "
+                            + "activity");
+                    throw e;
+                }
+            }
+        }
 
         final File passedIconFile = new File(filePath);
         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
@@ -3303,6 +3315,13 @@
         return false;
     }
 
+    /**
+     * An instance method that's easier for mocking in tests.
+     */
+    void enforceActivityTaskPermission(String func) {
+        enforceTaskPermission(func);
+    }
+
     static void enforceTaskPermission(String func) {
         if (checkCallingPermission(MANAGE_ACTIVITY_TASKS) == PackageManager.PERMISSION_GRANTED) {
             return;
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 5184e49..c2b9128 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -96,7 +96,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 import static com.android.server.wm.WindowManagerInternal.AppTransitionListener;
-import static com.android.server.wm.WindowManagerInternal.KeyguardExitAnimationStartListener;
 import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_AFTER_ANIM;
 import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_NONE;
 
@@ -105,7 +104,6 @@
 import android.annotation.Nullable;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -117,7 +115,6 @@
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
 import android.os.SystemClock;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.util.Pair;
 import android.util.Slog;
@@ -137,6 +134,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.TransitionAnimation;
+import com.android.internal.protolog.common.LogLevel;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.DumpUtils.Dump;
 import com.android.internal.util.function.pooled.PooledLambda;
@@ -244,7 +242,7 @@
         mHandler = new Handler(service.mH.getLooper());
         mDisplayContent = displayContent;
         mTransitionAnimation = new TransitionAnimation(
-                context, ProtoLog.isEnabled(WM_DEBUG_ANIM), TAG);
+                context, ProtoLog.isEnabled(WM_DEBUG_ANIM, LogLevel.DEBUG), TAG);
 
         final TypedArray windowStyle = mContext.getTheme().obtainStyledAttributes(
                 com.android.internal.R.styleable.Window);
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 7144445..f6681c5 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -359,6 +359,7 @@
                         mAnimationHandler.prepareAnimation(
                                 backType,
                                 adapter,
+                                mNavigationMonitor,
                                 currentTask,
                                 prevTask,
                                 currentActivity,
@@ -667,7 +668,8 @@
         mAnimationHandler.markWindowHasDrawn(openActivity);
     }
 
-    private class NavigationMonitor {
+    @VisibleForTesting
+    class NavigationMonitor {
         // The window which triggering the back navigation.
         private WindowState mNavigatingWindow;
         private RemoteCallback mObserver;
@@ -1492,28 +1494,31 @@
         ScheduleAnimationBuilder prepareAnimation(
                 int backType,
                 BackAnimationAdapter adapter,
+                NavigationMonitor monitor,
                 Task currentTask,
                 Task previousTask,
                 ActivityRecord currentActivity,
                 ArrayList<ActivityRecord> previousActivity,
                 WindowContainer removedWindowContainer) {
+            final ScheduleAnimationBuilder builder =
+                    new ScheduleAnimationBuilder(backType, adapter, monitor);
             switch (backType) {
                 case BackNavigationInfo.TYPE_RETURN_TO_HOME:
-                    return new ScheduleAnimationBuilder(backType, adapter)
+                    return builder
                             .setIsLaunchBehind(true)
                             .setComposeTarget(currentTask, previousTask);
                 case BackNavigationInfo.TYPE_CROSS_ACTIVITY:
                     ActivityRecord[] prevActs = new ActivityRecord[previousActivity.size()];
                     prevActs = previousActivity.toArray(prevActs);
-                    return new ScheduleAnimationBuilder(backType, adapter)
+                    return builder
                             .setComposeTarget(currentActivity, prevActs)
                             .setIsLaunchBehind(false);
                 case BackNavigationInfo.TYPE_CROSS_TASK:
-                    return new ScheduleAnimationBuilder(backType, adapter)
+                    return builder
                             .setComposeTarget(currentTask, previousTask)
                             .setIsLaunchBehind(false);
                 case BackNavigationInfo.TYPE_DIALOG_CLOSE:
-                    return new ScheduleAnimationBuilder(backType, adapter)
+                    return builder
                             .setComposeTarget(removedWindowContainer, currentActivity)
                             .setIsLaunchBehind(false);
             }
@@ -1523,13 +1528,16 @@
         class ScheduleAnimationBuilder {
             final int mType;
             final BackAnimationAdapter mBackAnimationAdapter;
+            final NavigationMonitor mNavigationMonitor;
             WindowContainer mCloseTarget;
             WindowContainer[] mOpenTargets;
             boolean mIsLaunchBehind;
 
-            ScheduleAnimationBuilder(int type, BackAnimationAdapter backAnimationAdapter) {
+            ScheduleAnimationBuilder(int type, BackAnimationAdapter adapter,
+                    NavigationMonitor monitor) {
                 mType = type;
-                mBackAnimationAdapter = backAnimationAdapter;
+                mBackAnimationAdapter = adapter;
+                mNavigationMonitor = monitor;
             }
 
             ScheduleAnimationBuilder setComposeTarget(@NonNull WindowContainer close,
@@ -1610,8 +1618,13 @@
 
                 return () -> {
                     try {
-                        mBackAnimationAdapter.getRunner().onAnimationStart(
-                                targets, null, null, callback);
+                        if (hasTargetDetached() || !validateAnimationTargets(targets)) {
+                            mNavigationMonitor.cancelBackNavigating("cancelAnimation");
+                            mBackAnimationAdapter.getRunner().onAnimationCancelled();
+                        } else {
+                            mBackAnimationAdapter.getRunner().onAnimationStart(
+                                    targets, null, null, callback);
+                        }
                     } catch (RemoteException e) {
                         e.printStackTrace();
                     }
@@ -1641,6 +1654,21 @@
     }
 
     /**
+     * Validate animation targets.
+     */
+    private static boolean validateAnimationTargets(RemoteAnimationTarget[] apps) {
+        if (apps == null || apps.length == 0) {
+            return false;
+        }
+        for (int i = apps.length - 1; i >= 0; --i) {
+            if (!apps[i].leash.isValid()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
      * Finds next opening activity(ies) based on open targets, which could be:
      * 1. If the open window is Task, then the open activity can either be an activity, or
      * two activities inside two TaskFragments
diff --git a/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java b/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
index a29cb60..ca5f26a 100644
--- a/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
+++ b/services/core/java/com/android/server/wm/DeferredDisplayUpdater.java
@@ -26,6 +26,10 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.graphics.Rect;
+import android.os.Message;
+import android.os.Trace;
+import android.util.Log;
+import android.util.Slog;
 import android.view.DisplayInfo;
 import android.window.DisplayAreaInfo;
 import android.window.TransitionRequestInfo;
@@ -35,6 +39,7 @@
 import com.android.internal.display.BrightnessSynchronizer;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.server.wm.utils.DisplayInfoOverrides.DisplayInfoFieldsUpdater;
+import com.android.window.flags.Flags;
 
 import java.util.Arrays;
 import java.util.Objects;
@@ -65,6 +70,12 @@
         WM_OVERRIDE_FIELDS.setFields(out, override);
     };
 
+    private static final String TAG = "DeferredDisplayUpdater";
+
+    private static final String TRACE_TAG_WAIT_FOR_TRANSITION =
+            "Screen unblock: wait for transition";
+    private static final int WAIT_FOR_TRANSITION_TIMEOUT = 1000;
+
     private final DisplayContent mDisplayContent;
 
     @NonNull
@@ -88,6 +99,18 @@
     @NonNull
     private final DisplayInfo mOutputDisplayInfo = new DisplayInfo();
 
+    /** Whether {@link #mScreenUnblocker} should wait for transition to be ready. */
+    private boolean mShouldWaitForTransitionWhenScreenOn;
+
+    /** The message to notify PhoneWindowManager#finishWindowsDrawn. */
+    @Nullable
+    private Message mScreenUnblocker;
+
+    private final Runnable mScreenUnblockTimeoutRunnable = () -> {
+        Slog.e(TAG, "Timeout waiting for the display switch transition to start");
+        continueScreenUnblocking();
+    };
+
     public DeferredDisplayUpdater(@NonNull DisplayContent displayContent) {
         mDisplayContent = displayContent;
         mNonOverrideDisplayInfo.copyFrom(mDisplayContent.getDisplayInfo());
@@ -248,6 +271,7 @@
                 getCurrentDisplayChange(fromRotation, startBounds);
         displayChange.setPhysicalDisplayChanged(true);
 
+        transition.addTransactionCompletedListener(this::continueScreenUnblocking);
         mDisplayContent.mTransitionController.requestStartTransition(transition,
                 /* startTask= */ null, /* remoteTransition= */ null, displayChange);
 
@@ -277,6 +301,58 @@
         return !Objects.equals(first.uniqueId, second.uniqueId);
     }
 
+    @Override
+    public void onDisplayContentDisplayPropertiesPostChanged(int previousRotation, int newRotation,
+            DisplayAreaInfo newDisplayAreaInfo) {
+        // Unblock immediately in case there is no transition. This is unlikely to happen.
+        if (mScreenUnblocker != null && !mDisplayContent.mTransitionController.inTransition()) {
+            mScreenUnblocker.sendToTarget();
+            mScreenUnblocker = null;
+        }
+    }
+
+    @Override
+    public void onDisplaySwitching(boolean switching) {
+        mShouldWaitForTransitionWhenScreenOn = switching;
+    }
+
+    @Override
+    public boolean waitForTransition(@NonNull Message screenUnblocker) {
+        if (!Flags.waitForTransitionOnDisplaySwitch()) return false;
+        if (!mShouldWaitForTransitionWhenScreenOn) {
+            return false;
+        }
+        mScreenUnblocker = screenUnblocker;
+        if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
+            Trace.beginAsyncSection(TRACE_TAG_WAIT_FOR_TRANSITION, screenUnblocker.hashCode());
+        }
+
+        mDisplayContent.mWmService.mH.removeCallbacks(mScreenUnblockTimeoutRunnable);
+        mDisplayContent.mWmService.mH.postDelayed(mScreenUnblockTimeoutRunnable,
+                WAIT_FOR_TRANSITION_TIMEOUT);
+        return true;
+    }
+
+    /**
+     * Continues the screen unblocking flow, could be called either on a binder thread as
+     * a result of surface transaction completed listener or from {@link WindowManagerService#mH}
+     * handler in case of timeout
+     */
+    private void continueScreenUnblocking() {
+        synchronized (mDisplayContent.mWmService.mGlobalLock) {
+            mShouldWaitForTransitionWhenScreenOn = false;
+            mDisplayContent.mWmService.mH.removeCallbacks(mScreenUnblockTimeoutRunnable);
+            if (mScreenUnblocker == null) {
+                return;
+            }
+            mScreenUnblocker.sendToTarget();
+            if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
+                Trace.endAsyncSection(TRACE_TAG_WAIT_FOR_TRANSITION, mScreenUnblocker.hashCode());
+            }
+            mScreenUnblocker = null;
+        }
+    }
+
     /**
      * Diff result: fields are the same
      */
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index fe280cb..cde3e68 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -470,7 +470,7 @@
     private final DisplayRotation mDisplayRotation;
     @Nullable final DisplayRotationCompatPolicy mDisplayRotationCompatPolicy;
     DisplayFrames mDisplayFrames;
-    private final DisplayUpdater mDisplayUpdater;
+    final DisplayUpdater mDisplayUpdater;
 
     private boolean mInTouchMode;
 
@@ -2705,7 +2705,11 @@
      * Returns true if the specified UID has access to this display.
      */
     boolean hasAccess(int uid) {
-        return mDisplay.hasAccess(uid);
+        int userId = UserHandle.getUserId(uid);
+        boolean isUserVisibleOnDisplay = mWmService.mUmInternal.isUserVisible(
+                userId, mDisplayId);
+        return mDisplay.hasAccess(uid)
+                && (userId == UserHandle.USER_SYSTEM || isUserVisibleOnDisplay);
     }
 
     boolean isPrivate() {
@@ -4562,7 +4566,12 @@
             }
         }
 
-        void attachAndShow(Transaction t) {
+        /**
+         * Attaches the snapshot of IME (a snapshot will be taken if there wasn't one) to the IME
+         * target task and shows it. If the given {@param anyTargetTask} is true, the snapshot won't
+         * be skipped by the activity type of IME target task.
+         */
+        void attachAndShow(Transaction t, boolean anyTargetTask) {
             final DisplayContent dc = mImeTarget.getDisplayContent();
             // Prepare IME screenshot for the target if it allows to attach into.
             final Task task = mImeTarget.getTask();
@@ -4570,7 +4579,9 @@
             final boolean renewImeSurface = mImeSurface == null
                     || mImeSurface.getWidth() != dc.mInputMethodWindow.getFrame().width()
                     || mImeSurface.getHeight() != dc.mInputMethodWindow.getFrame().height();
-            if (task != null && !task.isActivityTypeHomeOrRecents()) {
+            // The exclusion of home/recents is an optimization for regular task switch because
+            // home/recents won't appear in recents task.
+            if (task != null && (anyTargetTask || !task.isActivityTypeHomeOrRecents())) {
                 ScreenCapture.ScreenshotHardwareBuffer imeBuffer = renewImeSurface
                         ? dc.mWmService.mTaskSnapshotController.snapshotImeFromAttachedTask(task)
                         : null;
@@ -4638,7 +4649,9 @@
         removeImeSurfaceImmediately();
         mImeScreenshot = new ImeScreenshot(
                 mWmService.mSurfaceControlFactory.apply(null), imeTarget);
-        mImeScreenshot.attachAndShow(t);
+        // If the caller requests to hide IME, then allow to show IME snapshot for any target task.
+        // So IME won't look like suddenly disappeared. It usually happens when turning off screen.
+        mImeScreenshot.attachAndShow(t, hideImeWindow /* anyTargetTask */);
         if (mInputMethodWindow != null && hideImeWindow) {
             // Hide the IME window when deciding to show IME snapshot on demand.
             // InsetsController will make IME visible again before animating it.
@@ -6997,7 +7010,7 @@
             // by finishing the recents animation and moving it to top. That also avoids flickering
             // due to wait for previous activity to be paused if it supports PiP that ignores the
             // effect of resume-while-pausing.
-            if (r == null || r == mAnimatingRecents) {
+            if (r == null || r == mAnimatingRecents || r.getDisplayId() != mDisplayId) {
                 return;
             }
             if (mAnimatingRecents != null && mRecentsWillBeTop) {
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 16f7373..a5037ea 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -779,6 +779,11 @@
         return mLidState;
     }
 
+    private void onDisplaySwitchFinished() {
+        mDisplayContent.mWallpaperController.onDisplaySwitchFinished();
+        mDisplayContent.mDisplayUpdater.onDisplaySwitching(false);
+    }
+
     public void setAwake(boolean awake) {
         synchronized (mLock) {
             if (awake == mAwake) {
@@ -797,7 +802,7 @@
             mService.mAtmService.mKeyguardController.updateDeferTransitionForAod(
                     mAwake /* waiting */);
             if (!awake) {
-                mDisplayContent.mWallpaperController.onDisplaySwitchFinished();
+                onDisplaySwitchFinished();
             }
         }
     }
@@ -866,7 +871,7 @@
 
     /** It is called after {@link #finishScreenTurningOn}. This runs on PowerManager's thread. */
     public void screenTurnedOn() {
-        mDisplayContent.mWallpaperController.onDisplaySwitchFinished();
+        onDisplaySwitchFinished();
     }
 
     public void screenTurnedOff() {
@@ -2187,6 +2192,11 @@
                 mDisplayContent.mTransitionController.getCollectingTransitionId();
     }
 
+    /** If this is called, expect that there will be an onDisplayChanged about unique id. */
+    public void onDisplaySwitchStart() {
+        mDisplayContent.mDisplayUpdater.onDisplaySwitching(true);
+    }
+
     @NavigationBarPosition
     int navigationBarPosition(int displayRotation) {
         if (mNavigationBar != null) {
diff --git a/services/core/java/com/android/server/wm/DisplayUpdater.java b/services/core/java/com/android/server/wm/DisplayUpdater.java
index e611177..918b180 100644
--- a/services/core/java/com/android/server/wm/DisplayUpdater.java
+++ b/services/core/java/com/android/server/wm/DisplayUpdater.java
@@ -17,6 +17,7 @@
 package com.android.server.wm;
 
 import android.annotation.NonNull;
+import android.os.Message;
 import android.view.Surface;
 import android.window.DisplayAreaInfo;
 
@@ -49,4 +50,16 @@
             @Surface.Rotation int previousRotation, @Surface.Rotation int newRotation,
             @NonNull DisplayAreaInfo newDisplayAreaInfo) {
     }
+
+    /**
+     * Called with {@code true} when physical display is going to switch. And {@code false} when
+     * the display is turned on or the device goes to sleep.
+     */
+    default void onDisplaySwitching(boolean switching) {
+    }
+
+    /** Returns {@code true} if the transition will control when to turn on the screen. */
+    default boolean waitForTransition(@NonNull Message screenUnBlocker) {
+        return false;
+    }
 }
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 8c4f9ef..2dbb370 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -67,8 +67,9 @@
     /** @see #setServerVisible(boolean) */
     private boolean mServerVisible;
 
-    ImeInsetsSourceProvider(InsetsSource source,
-            InsetsStateController stateController, DisplayContent displayContent) {
+    ImeInsetsSourceProvider(@NonNull InsetsSource source,
+            @NonNull InsetsStateController stateController,
+            @NonNull DisplayContent displayContent) {
         super(source, stateController, displayContent);
     }
 
@@ -230,7 +231,7 @@
         if (mImeRequesterStatsToken != null) {
             // Cancel the pre-existing stats token, if any.
             // Log state on pre-existing request cancel.
-            logShowImePostLayoutState();
+            logShowImePostLayoutState(false /* aborted */);
             ImeTracker.forLogging().onCancelled(
                     mImeRequesterStatsToken, ImeTracker.PHASE_WM_SHOW_IME_RUNNER);
         }
@@ -310,7 +311,7 @@
         ProtoLog.d(WM_DEBUG_IME, "abortShowImePostLayout");
         if (mImeRequesterStatsToken != null) {
             // Log state on abort.
-            logShowImePostLayoutState();
+            logShowImePostLayoutState(true /* aborted */);
             ImeTracker.forLogging().onFailed(
                     mImeRequesterStatsToken, ImeTracker.PHASE_WM_ABORT_SHOW_IME_POST_LAYOUT);
             mImeRequesterStatsToken = null;
@@ -333,11 +334,30 @@
         //  actual IME target.
         final InsetsControlTarget dcTarget = mDisplayContent.getImeTarget(IME_TARGET_LAYERING);
         if (dcTarget == null || mImeRequester == null) {
+            // Not ready to show if there is no IME layering target, or no IME requester.
             return false;
         }
-        // Not ready to show if there is no IME control target.
-        final InsetsControlTarget controlTarget = mDisplayContent.getImeTarget(IME_TARGET_CONTROL);
+        final InsetsControlTarget controlTarget = getControlTarget();
         if (controlTarget == null) {
+            // Not ready to show if there is no IME control target.
+            return false;
+        }
+        if (controlTarget != mDisplayContent.getImeTarget(IME_TARGET_CONTROL)) {
+            // Not ready to show if control target does not match the one in DisplayContent.
+            return false;
+        }
+        if (!mServerVisible || mFrozen) {
+            // Not ready to show if the window container is not available and considered visible.
+            // If frozen, the server visibility is not set until unfrozen.
+            return false;
+        }
+        if (mStateController.hasPendingControls(controlTarget)) {
+            // Not ready to show if control target has pending controls.
+            return false;
+        }
+        if (getLeash(controlTarget) == null) {
+            // Not ready to show if control target has no source control leash (or leash is not
+            // ready for dispatching).
             return false;
         }
 
@@ -353,35 +373,56 @@
     }
 
     /**
-     * Logs the current state required for scheduleShowImePostLayout's runnable to be triggered.
+     * Logs the current state required for showImePostLayout to be triggered.
+     *
+     * @param aborted whether the showImePostLayout was aborted or cancelled.
      */
-    private void logShowImePostLayoutState() {
+    private void logShowImePostLayoutState(boolean aborted) {
         final var windowState = mWindowContainer != null ? mWindowContainer.asWindowState() : null;
         final var dcTarget = mDisplayContent.getImeTarget(IME_TARGET_LAYERING);
-        final var controlTarget = mDisplayContent.getImeTarget(IME_TARGET_CONTROL);
+        final var controlTarget = getControlTarget();
         final var sb = new StringBuilder();
-        sb.append("mWindowContainer: ").append(mWindowContainer);
-        sb.append(" windowState: ").append(windowState);
+        sb.append("showImePostLayout ").append(aborted ? "aborted" : "cancelled");
+        sb.append(", mWindowContainer is: ");
+        sb.append(mWindowContainer != null ? "non-null" : "null");
+        sb.append(", windowState: ").append(windowState);
         if (windowState != null) {
-            sb.append(" windowState.isDrawn(): ").append(windowState.isDrawn());
-            sb.append(" windowState.mGivenInsetsPending: ").append(windowState.mGivenInsetsPending);
+            sb.append(", windowState.isDrawn(): ");
+            sb.append(windowState.isDrawn());
+            sb.append(", windowState.mGivenInsetsPending: ");
+            sb.append(windowState.mGivenInsetsPending);
         }
-        sb.append(" mIsImeLayoutDrawn: ").append(mIsImeLayoutDrawn);
-        sb.append(" mShowImeRunner: ").append(mShowImeRunner);
-        sb.append(" mImeRequester: ").append(mImeRequester);
-        sb.append(" dcTarget: ").append(dcTarget);
-        sb.append(" controlTarget: ").append(controlTarget);
-        sb.append(" isReadyToShowIme(): ").append(isReadyToShowIme());
+        sb.append(", mIsImeLayoutDrawn: ").append(mIsImeLayoutDrawn);
+        sb.append(", mShowImeRunner: ").append(mShowImeRunner);
+        sb.append(", mImeRequester: ").append(mImeRequester);
+        sb.append(", dcTarget: ").append(dcTarget);
+        sb.append(", controlTarget: ").append(controlTarget);
+        sb.append("\n");
+        sb.append("isReadyToShowIme(): ").append(isReadyToShowIme());
         if (mImeRequester != null && dcTarget != null && controlTarget != null) {
-            sb.append(" isImeLayeringTarget: ");
+            sb.append(", controlTarget == DisplayContent.controlTarget: ");
+            sb.append(controlTarget == mDisplayContent.getImeTarget(IME_TARGET_CONTROL));
+            sb.append(", hasPendingControls: ");
+            sb.append(mStateController.hasPendingControls(controlTarget));
+            sb.append(", serverVisible: ");
+            sb.append(mServerVisible);
+            sb.append(", frozen: ");
+            sb.append(mFrozen);
+            sb.append(", leash is: ");
+            sb.append(getLeash(controlTarget) != null ? "non-null" : "null");
+            sb.append(", control is: ");
+            sb.append(mControl != null ? "non-null" : "null");
+            sb.append(", mIsLeashReadyForDispatching: ");
+            sb.append(mIsLeashReadyForDispatching);
+            sb.append(", isImeLayeringTarget: ");
             sb.append(isImeLayeringTarget(mImeRequester, dcTarget));
-            sb.append(" isAboveImeLayeringTarget: ");
+            sb.append(", isAboveImeLayeringTarget: ");
             sb.append(isAboveImeLayeringTarget(mImeRequester, dcTarget));
-            sb.append(" isImeFallbackTarget: ");
+            sb.append(", isImeFallbackTarget: ");
             sb.append(isImeFallbackTarget(mImeRequester));
-            sb.append(" isImeInputTarget: ");
+            sb.append(", isImeInputTarget: ");
             sb.append(isImeInputTarget(mImeRequester));
-            sb.append(" sameAsImeControlTarget: ");
+            sb.append(", sameAsImeControlTarget: ");
             sb.append(sameAsImeControlTarget());
         }
         Slog.d(TAG, sb.toString());
diff --git a/services/core/java/com/android/server/wm/InputConfigAdapter.java b/services/core/java/com/android/server/wm/InputConfigAdapter.java
index 2dcde4e..ef1b02d 100644
--- a/services/core/java/com/android/server/wm/InputConfigAdapter.java
+++ b/services/core/java/com/android/server/wm/InputConfigAdapter.java
@@ -56,7 +56,10 @@
                     InputConfig.DISABLE_USER_ACTIVITY, false /* inverted */),
             new FlagMapping(
                     LayoutParams.INPUT_FEATURE_SPY,
-                    InputConfig.SPY, false /* inverted */));
+                    InputConfig.SPY, false /* inverted */),
+            new FlagMapping(
+                    LayoutParams.INPUT_FEATURE_SENSITIVE_FOR_TRACING,
+                    InputConfig.SENSITIVE_FOR_TRACING, false /* inverted */));
 
     @InputConfigFlags
     private static final int INPUT_FEATURE_TO_CONFIG_MASK =
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 83f44d2..a8cbc62 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -64,15 +64,16 @@
 
     private static final Rect EMPTY_RECT = new Rect();
 
-    protected final DisplayContent mDisplayContent;
     protected final @NonNull InsetsSource mSource;
-    protected WindowContainer mWindowContainer;
+    protected final @NonNull DisplayContent mDisplayContent;
+    protected final @NonNull InsetsStateController mStateController;
+    protected @Nullable WindowContainer mWindowContainer;
+    protected @Nullable InsetsSourceControl mControl;
+    protected boolean mIsLeashReadyForDispatching;
 
     private final Rect mTmpRect = new Rect();
-    private final InsetsStateController mStateController;
     private final InsetsSourceControl mFakeControl;
     private final Consumer<Transaction> mSetLeashPositionConsumer;
-    private @Nullable InsetsSourceControl mControl;
     private @Nullable InsetsControlTarget mControlTarget;
     private @Nullable InsetsControlTarget mPendingControlTarget;
     private @Nullable InsetsControlTarget mFakeControlTarget;
@@ -82,7 +83,6 @@
     private SparseArray<TriFunction<DisplayFrames, WindowContainer, Rect, Integer>>
             mOverrideFrameProviders;
     private final SparseArray<Rect> mOverrideFrames = new SparseArray<Rect>();
-    private boolean mIsLeashReadyForDispatching;
     private final Rect mSourceFrame = new Rect();
     private final Rect mLastSourceFrame = new Rect();
     private @NonNull Insets mInsetsHint = Insets.NONE;
@@ -114,8 +114,9 @@
      */
     private boolean mCropToProvidingInsets = false;
 
-    InsetsSourceProvider(InsetsSource source, InsetsStateController stateController,
-            DisplayContent displayContent) {
+    InsetsSourceProvider(@NonNull InsetsSource source,
+            @NonNull InsetsStateController stateController,
+            @NonNull DisplayContent displayContent) {
         mClientVisible = (WindowInsets.Type.defaultVisible() & source.getType()) != 0;
         mSource = source;
         mDisplayContent = displayContent;
@@ -560,7 +561,7 @@
         mDisplayContent.mWmService.mWindowPlacerLocked.requestTraversal();
     }
 
-    @VisibleForTesting
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
     void setServerVisible(boolean serverVisible) {
         mServerVisible = serverVisible;
         updateSourceFrameForServerVisibility();
@@ -575,6 +576,14 @@
                 mServerVisible, mClientVisible);
     }
 
+    /**
+     * Gets the source control for the given control target. If this is the provider's control
+     * target, but the leash is not ready for dispatching, a new source control object with the
+     * leash set to {@code null} is returned.
+     *
+     * @param target the control target to get the source control for.
+     */
+    @Nullable
     InsetsSourceControl getControl(InsetsControlTarget target) {
         if (target == mControlTarget) {
             if (!mIsLeashReadyForDispatching && mControl != null) {
@@ -593,10 +602,25 @@
         return null;
     }
 
+    /**
+     * Gets the leash of the source control for the given control target. If this is not the
+     * provider's control target, or the leash is not ready for dispatching, this will
+     * return {@code null}.
+     *
+     * @param target the control target to get the source control leash for.
+     */
+    @Nullable
+    protected SurfaceControl getLeash(@NonNull InsetsControlTarget target) {
+        return target == mControlTarget && mIsLeashReadyForDispatching && mControl != null
+                ? mControl.getLeash() : null;
+    }
+
+    @Nullable
     InsetsControlTarget getControlTarget() {
         return mControlTarget;
     }
 
+    @Nullable
     InsetsControlTarget getFakeControlTarget() {
         return mFakeControlTarget;
     }
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 6b9fcf4..3a04bcd 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -388,6 +388,9 @@
                 onRequestedVisibleTypesChanged(newControlTargets.valueAt(i));
             }
             newControlTargets.clear();
+            // Check for and try to run the scheduled show IME request (if it exists), as we
+            // now applied the surface transaction and notified the target of the new control.
+            getImeSourceProvider().checkShowImePostLayout();
         });
     }
 
@@ -395,6 +398,15 @@
         mDisplayContent.notifyInsetsChanged(mDispatchInsetsChanged);
     }
 
+    /**
+     * Checks if the control target has pending controls.
+     *
+     * @param target the control target to check.
+     */
+    boolean hasPendingControls(@NonNull InsetsControlTarget target) {
+        return mPendingControlChanged.contains(target);
+    }
+
     void dump(String prefix, PrintWriter pw) {
         pw.println(prefix + "WindowInsetsStateController");
         prefix = prefix + "  ";
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 3ef6eeb..63bbb31 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -44,6 +44,7 @@
 import android.view.WindowManager;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.LogLevel;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.FastPrintWriter;
 import com.android.server.wm.SurfaceAnimator.AnimationType;
@@ -209,7 +210,7 @@
                 Slog.e(TAG, "Failed to start remote animation", e);
                 onAnimationFinished();
             }
-            if (ProtoLog.isEnabled(WM_DEBUG_REMOTE_ANIMATIONS)) {
+            if (ProtoLog.isEnabled(WM_DEBUG_REMOTE_ANIMATIONS, LogLevel.DEBUG)) {
                 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation(): Notify animation start:");
                 writeStartDebugStatement();
             }
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index d66005f..9dba8c6 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -31,6 +31,7 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_OCCLUDING;
 import static android.view.WindowManager.TRANSIT_NONE;
 import static android.view.WindowManager.TRANSIT_PIP;
 import static android.view.WindowManager.TRANSIT_SLEEP;
@@ -2496,15 +2497,17 @@
                 // Use NONE if keyguard is not showing.
                 int transit = TRANSIT_NONE;
                 Task startTask = null;
+                int flags = 0;
+                if (display.isKeyguardOccluded()) {
+                    startTask = display.getTaskOccludingKeyguard();
+                    flags = TRANSIT_FLAG_KEYGUARD_OCCLUDING;
+                    transit = WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
+                }
                 if (wasSleeping) {
                     transit = TRANSIT_WAKE;
-                } else if (display.isKeyguardOccluded()) {
-                    // The display was awake so this is resuming activity for occluding keyguard.
-                    transit = WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
-                    startTask = display.getTaskOccludingKeyguard();
                 }
                 display.mTransitionController.requestStartTransition(
-                        display.mTransitionController.createTransition(transit),
+                        display.mTransitionController.createTransition(transit, flags),
                         startTask, null /* remoteTransition */, null /* displayChange */);
             }
             // Set the sleeping state of the root tasks on the display.
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimator.java b/services/core/java/com/android/server/wm/SurfaceAnimator.java
index d67684c..c632714 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimator.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimator.java
@@ -32,6 +32,7 @@
 import android.view.SurfaceControl.Transaction;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.LogLevel;
 import com.android.internal.protolog.common.ProtoLog;
 
 import java.io.PrintWriter;
@@ -192,7 +193,7 @@
             return;
         }
         mAnimation.startAnimation(mLeash, t, type, mInnerAnimationFinishedCallback);
-        if (ProtoLog.isEnabled(WM_DEBUG_ANIM)) {
+        if (ProtoLog.isEnabled(WM_DEBUG_ANIM, LogLevel.DEBUG)) {
             StringWriter sw = new StringWriter();
             PrintWriter pw = new PrintWriter(sw);
             mAnimation.dump(pw, "");
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 6f1c834..d79d113 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1277,8 +1277,9 @@
             final ActivityRecord top = topRunningActivity();
             final ActivityRecord resumedActivity = getResumedActivity();
             if (resumedActivity != null
-                    && (top.getTaskFragment() != this || !canBeResumed(resuming))) {
-                // Pausing the resumed activity because it is occluded by other task fragment.
+                    && (top == null || top.getTaskFragment() != this || !canBeResumed(resuming))) {
+                // Pausing the resumed activity because it is occluded by other task fragment, or
+                // should not be remained in resumed state.
                 if (startPausing(false /* uiSleeping*/, resuming, reason)) {
                     someActivityPaused[0]++;
                 }
@@ -4681,9 +4682,10 @@
 
     @Override
     public void setWindowingMode(int windowingMode) {
-        // Calling Task#setWindowingMode() for leaf task since this is the a specialization of
+        // Calling Task#setWindowingMode() for leaf task since this is a specialization of
         // {@link #setWindowingMode(int)} for root task.
         if (!isRootTask()) {
+            mMultiWindowRestoreWindowingMode = INVALID_WINDOWING_MODE;
             super.setWindowingMode(windowingMode);
             return;
         }
@@ -4727,6 +4729,9 @@
             return;
         }
 
+        // Reset multi-window restore windowing mode.
+        mMultiWindowRestoreWindowingMode = INVALID_WINDOWING_MODE;
+
         final ActivityRecord topActivity = getTopNonFinishingActivity();
 
         // For now, assume that the root task's windowing mode is what will actually be used
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 319e2b0..1b380aa 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -112,6 +112,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.Executor;
 import java.util.function.Predicate;
 
 /**
@@ -233,6 +234,9 @@
      */
     private ArrayList<Task> mTransientHideTasks;
 
+    @VisibleForTesting
+    ArrayList<Runnable> mTransactionCompletedListeners = null;
+
     /** Custom activity-level animation options and callbacks. */
     private TransitionInfo.AnimationOptions mOverrideOptions;
     private IRemoteCallback mClientAnimationStartCallback = null;
@@ -1640,6 +1644,14 @@
         commitVisibleActivities(transaction);
         commitVisibleWallpapers();
 
+        if (mTransactionCompletedListeners != null) {
+            for (int i = 0; i < mTransactionCompletedListeners.size(); i++) {
+                final Runnable listener = mTransactionCompletedListeners.get(i);
+                transaction.addTransactionCompletedListener(Runnable::run,
+                        (stats) -> listener.run());
+            }
+        }
+
         // Fall-back to the default display if there isn't one participating.
         final DisplayContent primaryDisplay = !mTargetDisplays.isEmpty() ? mTargetDisplays.get(0)
                 : mController.mAtm.mRootWindowContainer.getDefaultDisplay();
@@ -1814,7 +1826,7 @@
                 final AccessibilityController accessibilityController =
                         dc.mWmService.mAccessibilityController;
                 if (accessibilityController.hasCallbacks()) {
-                    accessibilityController.onWMTransition(dc.getDisplayId(), mType);
+                    accessibilityController.onWMTransition(dc.getDisplayId(), mType, mFlags);
                 }
             }
         } else {
@@ -1862,6 +1874,17 @@
     }
 
     /**
+     * Adds a listener that will be executed after the start transaction of this transition
+     * is presented on the screen, the listener will be executed on a binder thread
+     */
+    void addTransactionCompletedListener(Runnable listener) {
+        if (mTransactionCompletedListeners == null) {
+            mTransactionCompletedListeners = new ArrayList<>();
+        }
+        mTransactionCompletedListeners.add(listener);
+    }
+
+    /**
      * Checks if the transition contains order changes.
      *
      * This is a shallow check that doesn't account for collection in parallel, unlike
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index ac03a1b..222abc3 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -300,7 +300,7 @@
      * Creates a transition. It can immediately collect participants.
      */
     @NonNull
-    private Transition createTransition(@WindowManager.TransitionType int type,
+    Transition createTransition(@WindowManager.TransitionType int type,
             @WindowManager.TransitionFlags int flags) {
         if (mTransitionPlayer == null) {
             throw new IllegalStateException("Shell Transitions not enabled");
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index a2f6fb4..c8cb934 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -22,7 +22,6 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
 
 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WALLPAPER;
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index e01842c..90ac576 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -113,6 +113,7 @@
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.graphics.ColorUtils;
+import com.android.internal.protolog.common.LogLevel;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.ToBooleanFunction;
 import com.android.server.wm.SurfaceAnimator.Animatable;
@@ -3286,10 +3287,6 @@
 
             if (isTaskTransitOld(transit) && getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
                 animationRunnerBuilder.setTaskBackgroundColor(getTaskAnimationBackgroundColor());
-                // TODO: Remove when we migrate to shell (b/202383002)
-                if (mWmService.mTaskTransitionSpec != null) {
-                    animationRunnerBuilder.hideInsetSourceViewOverflows();
-                }
             }
 
             // Check if the animation requests to show background color for Activity and embedded
@@ -3409,7 +3406,7 @@
                 // ActivityOption#makeCustomAnimation or WindowManager#overridePendingTransition.
                 a.restrictDuration(MAX_APP_TRANSITION_DURATION);
             }
-            if (ProtoLog.isEnabled(WM_DEBUG_ANIM)) {
+            if (ProtoLog.isEnabled(WM_DEBUG_ANIM, LogLevel.DEBUG)) {
                 ProtoLog.i(WM_DEBUG_ANIM, "Loaded animation %s for %s, duration: %d, stack=%s",
                         a, this, ((a != null) ? a.getDuration() : 0), Debug.getCallers(20));
             }
@@ -4255,27 +4252,6 @@
             }
         }
 
-        private void hideInsetSourceViewOverflows() {
-            final SparseArray<InsetsSourceProvider> providers =
-                    getDisplayContent().getInsetsStateController().getSourceProviders();
-            for (int i = providers.size(); i >= 0; i--) {
-                final InsetsSourceProvider insetProvider = providers.valueAt(i);
-                if (!insetProvider.getSource().hasFlags(InsetsSource.FLAG_INSETS_ROUNDED_CORNER)) {
-                    return;
-                }
-
-                // Will apply it immediately to current leash and to all future inset animations
-                // until we disable it.
-                insetProvider.setCropToProvidingInsetsBounds(getPendingTransaction());
-
-                // Only clear the size restriction of the inset once the surface animation is over
-                // and not if it's canceled to be replace by another animation.
-                mOnAnimationFinished.add(() -> {
-                    insetProvider.removeCropToProvidingInsetsBounds(getPendingTransaction());
-                });
-            }
-        }
-
         private IAnimationStarter build() {
             return (Transaction t, AnimationAdapter adapter, boolean hidden,
                     @AnimationType int type, @Nullable AnimationAdapter snapshotAnim) -> {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index f09ef96..2e72121 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -43,11 +43,13 @@
 import static android.os.Process.myPid;
 import static android.os.Process.myUid;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.permission.flags.Flags.sensitiveContentImprovements;
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
 import static android.provider.Settings.Global.DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH;
+import static android.service.dreams.Flags.dreamHandlesConfirmKeys;
 import static android.view.ContentRecordingSession.RECORD_CONTENT_TASK;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
@@ -65,6 +67,7 @@
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
 import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
 import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
+import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SENSITIVE_FOR_TRACING;
 import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY;
 import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
@@ -305,6 +308,7 @@
 import android.view.displayhash.DisplayHash;
 import android.view.displayhash.VerifiedDisplayHash;
 import android.view.inputmethod.ImeTracker;
+import android.widget.Toast;
 import android.window.ActivityWindowInfo;
 import android.window.AddToSurfaceSyncGroupResult;
 import android.window.ClientWindowFrames;
@@ -1718,8 +1722,8 @@
             final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
             displayPolicy.adjustWindowParamsLw(win, win.mAttrs);
             attrs.flags = sanitizeFlagSlippery(attrs.flags, win.getName(), callingUid, callingPid);
-            attrs.inputFeatures = sanitizeSpyWindow(attrs.inputFeatures, win.getName(), callingUid,
-                    callingPid);
+            attrs.inputFeatures = sanitizeInputFeatures(attrs.inputFeatures, win.getName(),
+                    callingUid, callingPid, win.isTrustedOverlay());
             win.setRequestedVisibleTypes(requestedVisibleTypes);
 
             res = displayPolicy.validateAddingWindowLw(attrs, callingPid, callingUid);
@@ -2289,8 +2293,8 @@
             if (attrs != null) {
                 displayPolicy.adjustWindowParamsLw(win, attrs);
                 attrs.flags = sanitizeFlagSlippery(attrs.flags, win.getName(), uid, pid);
-                attrs.inputFeatures = sanitizeSpyWindow(attrs.inputFeatures, win.getName(), uid,
-                        pid);
+                attrs.inputFeatures = sanitizeInputFeatures(attrs.inputFeatures, win.getName(), uid,
+                        pid, win.isTrustedOverlay());
                 int disableFlags =
                         (attrs.systemUiVisibility | attrs.subtreeSystemUiVisibility) & DISABLE_MASK;
                 if (disableFlags != 0 && !hasStatusBarPermission(pid, uid)) {
@@ -2581,14 +2585,18 @@
             }
 
             if (outFrames != null && outMergedConfiguration != null) {
+                final boolean shouldReportActivityWindowInfo = outBundle != null
+                        && win.mLastReportedActivityWindowInfo != null;
+                final ActivityWindowInfo outActivityWindowInfo = shouldReportActivityWindowInfo
+                        ? new ActivityWindowInfo()
+                        : null;
+
                 win.fillClientWindowFramesAndConfiguration(outFrames, outMergedConfiguration,
-                        false /* useLatestConfig */, shouldRelayout);
-                if (Flags.activityWindowInfoFlag() && outBundle != null
-                        && win.mActivityRecord != null) {
-                    final ActivityWindowInfo activityWindowInfo = win.mActivityRecord
-                            .getActivityWindowInfo();
+                        outActivityWindowInfo, false /* useLatestConfig */, shouldRelayout);
+
+                if (shouldReportActivityWindowInfo) {
                     outBundle.putParcelable(IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO,
-                            activityWindowInfo);
+                            outActivityWindowInfo);
                 }
 
                 // Set resize-handled here because the values are sent back to the client.
@@ -3420,7 +3428,7 @@
         if (!checkCallingPermission(permission.CONTROL_KEYGUARD, "dismissKeyguard")) {
             throw new SecurityException("Requires CONTROL_KEYGUARD permission");
         }
-        if (mAtmService.mKeyguardController.isShowingDream()) {
+        if (!dreamHandlesConfirmKeys() && mAtmService.mKeyguardController.isShowingDream()) {
             mAtmService.mTaskSupervisor.wakeUp("leaveDream");
         }
         synchronized (mGlobalLock) {
@@ -8069,6 +8077,10 @@
             }
             boolean allWindowsDrawn = false;
             synchronized (mGlobalLock) {
+                if (mRoot.getDefaultDisplay().mDisplayUpdater.waitForTransition(message)) {
+                    // Use the ready-to-play of transition as the signal.
+                    return;
+                }
                 container.waitForAllWindowsDrawn();
                 mWindowPlacerLocked.requestTraversal();
                 mH.removeMessages(H.WAITING_FOR_DRAWN_TIMEOUT, container);
@@ -8721,6 +8733,15 @@
                         mSensitiveContentPackages.addBlockScreenCaptureForApps(packageInfos);
                 if (modified) {
                     WindowManagerService.this.refreshScreenCaptureDisabled();
+                    if (sensitiveContentImprovements()) {
+                        // TODO(b/331842561): Combine this traversal with the one inside
+                        // refreshScreenCaptureDisabled above.
+                        mRoot.forAllWindows((w) -> {
+                            if (w.isVisible()) {
+                                WindowManagerService.this.showToastIfBlockingScreenCapture(w);
+                            }
+                        }, /* traverseTopToBottom= */ true);
+                    }
                 }
             }
         }
@@ -9105,18 +9126,26 @@
     }
 
     /**
-     * You need MONITOR_INPUT permission to be able to set INPUT_FEATURE_SPY.
+     * Ensure the caller has the right permissions to be able to set the requested input features.
      */
-    private int sanitizeSpyWindow(int inputFeatures, String windowName, int callingUid,
-            int callingPid) {
-        if ((inputFeatures & INPUT_FEATURE_SPY) == 0) {
-            return inputFeatures;
+    private int sanitizeInputFeatures(int inputFeatures, String windowName, int callingUid,
+            int callingPid, boolean isTrustedOverlay) {
+        // You need MONITOR_INPUT permission to be able to set INPUT_FEATURE_SPY.
+        if ((inputFeatures & INPUT_FEATURE_SPY) != 0) {
+            final int permissionResult = mContext.checkPermission(
+                    permission.MONITOR_INPUT, callingPid, callingUid);
+            if (permissionResult != PackageManager.PERMISSION_GRANTED) {
+                throw new IllegalArgumentException(
+                        "Cannot use INPUT_FEATURE_SPY from '" + windowName
+                                + "' because it doesn't the have MONITOR_INPUT permission");
+            }
         }
-        final int permissionResult = mContext.checkPermission(
-                permission.MONITOR_INPUT, callingPid, callingUid);
-        if (permissionResult != PackageManager.PERMISSION_GRANTED) {
-            throw new IllegalArgumentException("Cannot use INPUT_FEATURE_SPY from '" + windowName
-                    + "' because it doesn't the have MONITOR_INPUT permission");
+
+        // You can only use INPUT_FEATURE_SENSITIVE_FOR_TRACING on a trusted overlay.
+        if ((inputFeatures & INPUT_FEATURE_SENSITIVE_FOR_TRACING) != 0 && !isTrustedOverlay) {
+            Slog.w(TAG, "Removing INPUT_FEATURE_SENSITIVE_FOR_TRACING from '" + windowName
+                    + "' because it isn't a trusted overlay");
+            return inputFeatures & ~INPUT_FEATURE_SENSITIVE_FOR_TRACING;
         }
         return inputFeatures;
     }
@@ -9194,8 +9223,10 @@
         h.setWindowToken(clientToken);
         h.name = name;
 
+        final boolean isTrustedOverlay = (privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0;
         flags = sanitizeFlagSlippery(flags, name, callingUid, callingPid);
-        inputFeatures = sanitizeSpyWindow(inputFeatures, name, callingUid, callingPid);
+        inputFeatures = sanitizeInputFeatures(inputFeatures, name, callingUid, callingPid,
+                isTrustedOverlay);
 
         final int sanitizedLpFlags =
                 (flags & (FLAG_NOT_TOUCHABLE | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE))
@@ -9232,7 +9263,7 @@
 
         final SurfaceControl.Transaction t = mTransactionFactory.get();
         //  Check private trusted overlay flag to set trustedOverlay field of input window handle.
-        h.setTrustedOverlay(t, surface, (privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0);
+        h.setTrustedOverlay(t, surface, isTrustedOverlay);
         t.setInputWindowInfo(surface, h);
         t.apply();
         t.close();
@@ -10119,4 +10150,28 @@
     boolean getDisableSecureWindows() {
         return mDisableSecureWindows;
     }
+
+    /**
+     * Called to notify WMS that the specified window has become visible. This shows a Toast if the
+     * window is deemed to hold sensitive content.
+     */
+    void onWindowVisible(@NonNull WindowState w) {
+        showToastIfBlockingScreenCapture(w);
+    }
+
+    /**
+     * Shows a Toast if the specified window is
+     * {@link LocalService#addBlockScreenCaptureForApps(ArraySet) blocked} from screen capture based
+     * on sensitive content protections.
+     */
+    private void showToastIfBlockingScreenCapture(@NonNull WindowState w) {
+        // TODO(b/323580163): Check if already shown and update shown state.
+        if (mSensitiveContentPackages.shouldBlockScreenCaptureForApp(w.getOwningPackage(),
+                w.getOwningUid(), w.getWindowToken())) {
+            Toast.makeText(mContext, Looper.getMainLooper(),
+                            mContext.getString(R.string.screen_not_shared_sensitive_content),
+                            Toast.LENGTH_SHORT)
+                    .show();
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 37b2d0e..7a0245b 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -28,6 +28,7 @@
 import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
 import static android.os.PowerManager.DRAW_WAKE_LOCK;
 import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.permission.flags.Flags.sensitiveContentImprovements;
 import static android.view.SurfaceControl.Transaction;
 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
 import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
@@ -246,6 +247,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.policy.KeyInterceptionInfo;
+import com.android.internal.protolog.common.LogLevel;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.internal.util.FrameworkStatsLog;
 import com.android.internal.util.ToBooleanFunction;
@@ -421,6 +423,13 @@
      */
     private final MergedConfiguration mLastReportedConfiguration = new MergedConfiguration();
 
+    /**
+     * Similar to {@link #mLastReportedConfiguration}, used to store last reported to client
+     * ActivityWindowInfo. {@code null} if this is not an Activity window.
+     */
+    @Nullable
+    final ActivityWindowInfo mLastReportedActivityWindowInfo;
+
     /** @see #isLastConfigReportedToClient() */
     private boolean mLastConfigReportedToClient;
 
@@ -1080,6 +1089,9 @@
         mPolicy = mWmService.mPolicy;
         mContext = mWmService.mContext;
         mForceSeamlesslyRotate = token.mRoundedCornerOverlay;
+        mLastReportedActivityWindowInfo = Flags.activityWindowInfoFlag() && mActivityRecord != null
+                ? new ActivityWindowInfo()
+                : null;
         mInputWindowHandle = new InputWindowHandleWrapper(new InputWindowHandle(
                 mActivityRecord != null
                         ? mActivityRecord.getInputApplicationHandle(false /* update */) : null,
@@ -2127,6 +2139,9 @@
                 }
             }
             setDisplayLayoutNeeded();
+            if (sensitiveContentImprovements() && visible) {
+                mWmService.onWindowVisible(this);
+            }
         }
     }
 
@@ -3603,12 +3618,15 @@
      *
      * @param outFrames The frames that will be sent to the client.
      * @param outMergedConfiguration The configuration that will be sent to the client.
+     * @param outActivityWindowInfo The ActivityWindowInfo that will be sent to the client if set.
+     *                              {@code null} if this is not activity window.
      * @param useLatestConfig Whether to use the latest configuration.
      * @param relayoutVisible Whether to consider visibility to use the latest configuration.
      */
-    void fillClientWindowFramesAndConfiguration(ClientWindowFrames outFrames,
-            MergedConfiguration outMergedConfiguration, boolean useLatestConfig,
-            boolean relayoutVisible) {
+    void fillClientWindowFramesAndConfiguration(@NonNull ClientWindowFrames outFrames,
+            @NonNull MergedConfiguration outMergedConfiguration,
+            @Nullable ActivityWindowInfo outActivityWindowInfo,
+            boolean useLatestConfig, boolean relayoutVisible) {
         outFrames.frame.set(mWindowFrames.mCompatFrame);
         outFrames.displayFrame.set(mWindowFrames.mDisplayFrame);
         if (mInvGlobalScale != 1f) {
@@ -3638,8 +3656,15 @@
             if (outMergedConfiguration != mLastReportedConfiguration) {
                 mLastReportedConfiguration.setTo(outMergedConfiguration);
             }
+            if (outActivityWindowInfo != null && mLastReportedActivityWindowInfo != null) {
+                outActivityWindowInfo.set(mActivityRecord.getActivityWindowInfo());
+                mLastReportedActivityWindowInfo.set(outActivityWindowInfo);
+            }
         } else {
             outMergedConfiguration.setTo(mLastReportedConfiguration);
+            if (outActivityWindowInfo != null && mLastReportedActivityWindowInfo != null) {
+                outActivityWindowInfo.set(mLastReportedActivityWindowInfo);
+            }
         }
         mLastConfigReportedToClient = true;
     }
@@ -3676,10 +3701,22 @@
         mDragResizingChangeReported = true;
         mWindowFrames.clearReportResizeHints();
 
+        // App window resize may trigger Activity#onConfigurationChanged, so we need to update
+        // ActivityWindowInfo as well.
+        final IBinder activityToken;
+        final ActivityWindowInfo activityWindowInfo;
+        if (mLastReportedActivityWindowInfo != null) {
+            activityToken = mActivityRecord.token;
+            activityWindowInfo = mLastReportedActivityWindowInfo;
+        } else {
+            activityToken = null;
+            activityWindowInfo = null;
+        }
+
         final int prevRotation = mLastReportedConfiguration
                 .getMergedConfiguration().windowConfiguration.getRotation();
         fillClientWindowFramesAndConfiguration(mClientWindowFrames, mLastReportedConfiguration,
-                true /* useLatestConfig */, false /* relayoutVisible */);
+                activityWindowInfo, true /* useLatestConfig */, false /* relayoutVisible */);
         final boolean syncRedraw = shouldSendRedrawForSync();
         final boolean syncWithBuffers = syncRedraw && shouldSyncWithBuffers();
         final boolean reportDraw = syncRedraw || drawPending;
@@ -3697,18 +3734,6 @@
 
         markRedrawForSyncReported();
 
-        // App window resize may trigger Activity#onConfigurationChanged, so we need to update
-        // ActivityWindowInfo as well.
-        final IBinder activityToken;
-        final ActivityWindowInfo activityWindowInfo;
-        if (Flags.activityWindowInfoFlag() && mActivityRecord != null) {
-            activityToken = mActivityRecord.token;
-            activityWindowInfo = mActivityRecord.getActivityWindowInfo();
-        } else {
-            activityToken = null;
-            activityWindowInfo = null;
-        }
-
         if (Flags.bundleClientTransactionFlag()) {
             getProcess().scheduleClientTransactionItem(
                     WindowStateResizeItem.obtain(mClient, mClientWindowFrames, reportDraw,
@@ -4132,6 +4157,10 @@
             }
             pw.println(prefix + "mFullConfiguration=" + getConfiguration());
             pw.println(prefix + "mLastReportedConfiguration=" + getLastReportedConfiguration());
+            if (mLastReportedActivityWindowInfo != null) {
+                pw.println(prefix + "mLastReportedActivityWindowInfo="
+                        + mLastReportedActivityWindowInfo);
+            }
         }
         pw.println(prefix + "mHasSurface=" + mHasSurface
                 + " isReadyForDisplay()=" + isReadyForDisplay()
@@ -4711,7 +4740,7 @@
     }
 
     void onExitAnimationDone() {
-        if (ProtoLog.isEnabled(WM_DEBUG_ANIM)) {
+        if (ProtoLog.isEnabled(WM_DEBUG_ANIM, LogLevel.VERBOSE)) {
             final AnimationAdapter animationAdapter = mSurfaceAnimator.getAnimation();
             StringWriter sw = new StringWriter();
             if (animationAdapter != null) {
@@ -4949,8 +4978,15 @@
                 displayInfo.appWidth, displayInfo.appHeight);
         anim.restrictDuration(MAX_ANIMATION_DURATION);
         anim.scaleCurrentDuration(mWmService.getWindowAnimationScaleLocked());
+        final Point position = new Point();
+        if (com.android.window.flags.Flags.removePrepareSurfaceInPlacement()) {
+            transformFrameToSurfacePosition(mWindowFrames.mFrame.left, mWindowFrames.mFrame.top,
+                    position);
+        } else {
+            position.set(mSurfacePosition);
+        }
         final AnimationAdapter adapter = new LocalAnimationAdapter(
-                new WindowAnimationSpec(anim, mSurfacePosition, false /* canSkipFirstFrame */,
+                new WindowAnimationSpec(anim, position, false /* canSkipFirstFrame */,
                         0 /* windowCornerRadius */),
                 mWmService.mSurfaceAnimationRunner);
         startAnimation(getPendingTransaction(), adapter);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index a242d42..6fd7aa0 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -61,6 +61,7 @@
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 
+import com.android.internal.protolog.common.LogLevel;
 import com.android.internal.protolog.common.ProtoLog;
 import com.android.server.policy.WindowManagerPolicy;
 
@@ -586,7 +587,7 @@
                             mWin.mAttrs, attr, TRANSIT_OLD_NONE);
                 }
             }
-            if (ProtoLog.isEnabled(WM_DEBUG_ANIM)) {
+            if (ProtoLog.isEnabled(WM_DEBUG_ANIM, LogLevel.VERBOSE)) {
                 ProtoLog.v(WM_DEBUG_ANIM, "applyAnimation: win=%s"
                         + " anim=%d attr=0x%x a=%s transit=%d type=%d isEntrance=%b Callers %s",
                         this, anim, attr, a, transit, mAttrType, isEntrance, Debug.getCallers(20));
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index 755a7f8..8598023 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -114,7 +114,7 @@
                 <xs:element type="sensorDetails" name="screenOffBrightnessSensor">
                     <xs:annotation name="final"/>
                 </xs:element>
-                <xs:element type="sensorDetails" name="proxSensor">
+                <xs:element type="sensorDetails" name="proxSensor" maxOccurs="2">
                     <xs:annotation name="final"/>
                 </xs:element>
                 <xs:element type="sensorDetails" name="tempSensor">
@@ -478,6 +478,7 @@
     </xs:simpleType>
 
     <xs:complexType name="sensorDetails">
+        <xs:attribute name="featureFlag" type="xs:string" use="optional"/>
         <xs:sequence>
             <xs:element type="xs:string" name="type" minOccurs="0" maxOccurs="1">
                 <xs:annotation name="nullable"/>
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index 4fa77d9..4ce4cc3 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -117,7 +117,7 @@
     method public com.android.server.display.config.LuxThrottling getLuxThrottling();
     method @Nullable public final String getName();
     method public com.android.server.display.config.PowerThrottlingConfig getPowerThrottlingConfig();
-    method public final com.android.server.display.config.SensorDetails getProxSensor();
+    method public final java.util.List<com.android.server.display.config.SensorDetails> getProxSensor();
     method public com.android.server.display.config.DisplayQuirks getQuirks();
     method public com.android.server.display.config.RefreshRateConfigs getRefreshRate();
     method public final java.math.BigDecimal getScreenBrightnessCapForWearBedtimeMode();
@@ -154,7 +154,6 @@
     method public void setLuxThrottling(com.android.server.display.config.LuxThrottling);
     method public final void setName(@Nullable String);
     method public void setPowerThrottlingConfig(com.android.server.display.config.PowerThrottlingConfig);
-    method public final void setProxSensor(com.android.server.display.config.SensorDetails);
     method public void setQuirks(com.android.server.display.config.DisplayQuirks);
     method public void setRefreshRate(com.android.server.display.config.RefreshRateConfigs);
     method public final void setScreenBrightnessCapForWearBedtimeMode(java.math.BigDecimal);
@@ -405,10 +404,12 @@
 
   public class SensorDetails {
     ctor public SensorDetails();
+    method public String getFeatureFlag();
     method @Nullable public final String getName();
     method @Nullable public final com.android.server.display.config.RefreshRateRange getRefreshRate();
     method @Nullable public final com.android.server.display.config.NonNegativeFloatToFloatMap getSupportedModes();
     method @Nullable public final String getType();
+    method public void setFeatureFlag(String);
     method public final void setName(@Nullable String);
     method public final void setRefreshRate(@Nullable com.android.server.display.config.RefreshRateRange);
     method public final void setSupportedModes(@Nullable com.android.server.display.config.NonNegativeFloatToFloatMap);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BundlePolicySerializer.java b/services/devicepolicy/java/com/android/server/devicepolicy/BundlePolicySerializer.java
index 82f9aad..d24afabe 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BundlePolicySerializer.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BundlePolicySerializer.java
@@ -92,7 +92,7 @@
                 while (count > 0 && (type = parser.next()) != XmlPullParser.END_DOCUMENT) {
                     if (type == XmlPullParser.START_TAG
                             && parser.getName().equals(TAG_VALUE)) {
-                        values.add(parser.nextText().trim());
+                        values.add(parser.nextText());
                         count--;
                     }
                 }
@@ -111,7 +111,7 @@
                 restrictions.putParcelableArray(key,
                         bundleList.toArray(new Bundle[bundleList.size()]));
             } else {
-                String value = parser.nextText().trim();
+                String value = parser.nextText();
                 if (ATTR_TYPE_BOOLEAN.equals(valType)) {
                     restrictions.putBoolean(key, Boolean.parseBoolean(value));
                 } else if (ATTR_TYPE_INTEGER.equals(valType)) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
index 28fe5df..f39d019 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java
@@ -1640,6 +1640,10 @@
                     mAdminPolicySize.get(admin.getUserId()).get(admin) - sizeOf(
                             policyState.getPoliciesSetByAdmins().get(admin)));
         }
+        if (!mAdminPolicySize.contains(admin.getUserId())
+                || !mAdminPolicySize.get(admin.getUserId()).containsKey(admin)) {
+            return;
+        }
         if (mAdminPolicySize.get(admin.getUserId()).get(admin) <= 0) {
             mAdminPolicySize.get(admin.getUserId()).remove(admin);
         }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 318042e..3dd7b54 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -727,7 +727,6 @@
 
         SYSTEM_SETTINGS_ALLOWLIST = new ArraySet<>();
         SYSTEM_SETTINGS_ALLOWLIST.add(Settings.System.SCREEN_BRIGHTNESS);
-        SYSTEM_SETTINGS_ALLOWLIST.add(Settings.System.SCREEN_BRIGHTNESS_FLOAT);
         SYSTEM_SETTINGS_ALLOWLIST.add(Settings.System.SCREEN_BRIGHTNESS_MODE);
         SYSTEM_SETTINGS_ALLOWLIST.add(Settings.System.SCREEN_OFF_TIMEOUT);
 
@@ -11510,10 +11509,17 @@
 
     @Override
     public void setApplicationRestrictions(ComponentName who, String callerPackage,
-            String packageName, Bundle restrictions) {
+            String packageName, Bundle restrictions, boolean parent) {
         final CallerIdentity caller = getCallerIdentity(who, callerPackage);
         checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_APPLICATION_RESTRICTIONS);
 
+        // This check is eventually made in UMS, checking here to fail early.
+        String validationResult =
+                FrameworkParsingPackageUtils.validateName(packageName, false, false);
+        if (validationResult != null) {
+            throw new IllegalArgumentException("Invalid package name: " + validationResult);
+        }
+
         if (isUnicornFlagEnabled()) {
             EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
                     who,
@@ -11521,12 +11527,6 @@
                     caller.getPackageName(),
                     caller.getUserId()
             );
-            // This check is eventually made in UMS, checking here to fail early.
-            String validationResult =
-                    FrameworkParsingPackageUtils.validateName(packageName, false, false);
-            if (validationResult != null) {
-                throw new IllegalArgumentException("Invalid package name: " + validationResult);
-            }
 
             if (restrictions == null || restrictions.isEmpty()) {
                 mDevicePolicyEngine.removeLocalPolicy(
@@ -11542,6 +11542,57 @@
             }
             setBackwardsCompatibleAppRestrictions(
                     caller, packageName, restrictions, caller.getUserHandle());
+        } else if (Flags.dmrhCanSetAppRestriction()) {
+            final boolean isRoleHolder;
+            if (who != null) {
+                // DO or PO
+                Preconditions.checkCallAuthorization(
+                        (isProfileOwner(caller) || isDefaultDeviceOwner(caller)));
+                Preconditions.checkCallAuthorization(!parent,
+                        "DO or PO cannot call this on parent");
+                // Caller has opted to be treated as DPC (by passing a non-null who), so don't
+                // consider it as the DMRH, even if the caller is both the DPC and the DMRH.
+                isRoleHolder = false;
+            } else {
+                // Delegates, or the DMRH. Only DMRH can call this on COPE parent
+                isRoleHolder = isCallerDevicePolicyManagementRoleHolder(caller);
+                if (parent) {
+                    Preconditions.checkCallAuthorization(isRoleHolder);
+                    Preconditions.checkState(isOrganizationOwnedDeviceWithManagedProfile(),
+                            "Role Holder can only operate parent app restriction on COPE devices");
+                } else {
+                    Preconditions.checkCallAuthorization(isRoleHolder
+                            || isCallerDelegate(caller, DELEGATION_APP_RESTRICTIONS));
+                }
+            }
+            // DMRH caller uses policy engine, others still use legacy code path
+            if (isRoleHolder) {
+                EnforcingAdmin enforcingAdmin = getEnforcingAdminForCaller(/* who */ null,
+                        caller.getPackageName());
+                int affectedUserId = parent
+                        ? getProfileParentId(caller.getUserId()) : caller.getUserId();
+                if (restrictions == null || restrictions.isEmpty()) {
+                    mDevicePolicyEngine.removeLocalPolicy(
+                            PolicyDefinition.APPLICATION_RESTRICTIONS(packageName),
+                            enforcingAdmin,
+                            affectedUserId);
+                } else {
+                    mDevicePolicyEngine.setLocalPolicy(
+                            PolicyDefinition.APPLICATION_RESTRICTIONS(packageName),
+                            enforcingAdmin,
+                            new BundlePolicyValue(restrictions),
+                            affectedUserId);
+                }
+                Intent changeIntent = new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
+                changeIntent.setPackage(packageName);
+                changeIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                mContext.sendBroadcastAsUser(changeIntent, UserHandle.of(affectedUserId));
+            } else {
+                mInjector.binderWithCleanCallingIdentity(() -> {
+                    mUserManager.setApplicationRestrictions(packageName, restrictions,
+                            caller.getUserHandle());
+                });
+            }
         } else {
             Preconditions.checkCallAuthorization((caller.hasAdminComponent()
                     && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
@@ -12873,7 +12924,7 @@
 
     @Override
     public Bundle getApplicationRestrictions(ComponentName who, String callerPackage,
-            String packageName) {
+            String packageName, boolean parent) {
         final CallerIdentity caller = getCallerIdentity(who, callerPackage);
 
         if (isUnicornFlagEnabled()) {
@@ -12892,6 +12943,50 @@
                 return Bundle.EMPTY;
             }
             return policies.get(enforcingAdmin).getValue();
+        } else if (Flags.dmrhCanSetAppRestriction()) {
+            final boolean isRoleHolder;
+            if (who != null) {
+                // Caller is DO or PO. They cannot call this on parent
+                Preconditions.checkCallAuthorization(!parent
+                        && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)));
+                // Caller has opted to be treated as DPC (by passing a non-null who), so don't
+                // consider it as the DMRH, even if the caller is both the DPC and the DMRH.
+                isRoleHolder = false;
+            } else {
+                // Caller is delegates or the DMRH. Only DMRH can call this on parent
+                isRoleHolder = isCallerDevicePolicyManagementRoleHolder(caller);
+                if (parent) {
+                    Preconditions.checkCallAuthorization(isRoleHolder);
+                    Preconditions.checkState(isOrganizationOwnedDeviceWithManagedProfile(),
+                            "Role Holder can only operate parent app restriction on COPE devices");
+                } else {
+                    Preconditions.checkCallAuthorization(isRoleHolder
+                            || isCallerDelegate(caller, DELEGATION_APP_RESTRICTIONS));
+                }
+            }
+            if (isRoleHolder) {
+                EnforcingAdmin enforcingAdmin = getEnforcingAdminForCaller(/* who */ null,
+                        caller.getPackageName());
+                int affectedUserId = parent
+                        ? getProfileParentId(caller.getUserId()) : caller.getUserId();
+                LinkedHashMap<EnforcingAdmin, PolicyValue<Bundle>> policies =
+                        mDevicePolicyEngine.getLocalPoliciesSetByAdmins(
+                                PolicyDefinition.APPLICATION_RESTRICTIONS(packageName),
+                                affectedUserId);
+                if (!policies.containsKey(enforcingAdmin)) {
+                    return Bundle.EMPTY;
+                }
+                return policies.get(enforcingAdmin).getValue();
+            } else {
+                return mInjector.binderWithCleanCallingIdentity(() -> {
+                    Bundle bundle = mUserManager.getApplicationRestrictions(packageName,
+                            caller.getUserHandle());
+                    // if no restrictions were saved, mUserManager.getApplicationRestrictions
+                    // returns null, but DPM method should return an empty Bundle as per JavaDoc
+                    return bundle != null ? bundle : Bundle.EMPTY;
+                });
+            }
+
         } else {
             Preconditions.checkCallAuthorization((caller.hasAdminComponent()
                     && (isProfileOwner(caller) || isDefaultDeviceOwner(caller)))
@@ -15812,19 +15907,16 @@
             for (EnforcingAdmin admin : policies.keySet()) {
                 restrictions.add(policies.get(admin).getValue());
             }
-            if (!restrictions.isEmpty()) {
-                return restrictions;
-            }
 
             return mInjector.binderWithCleanCallingIdentity(() -> {
-                // Could be a device that has a DPC that hasn't migrated yet, so just return any
+                // Could be a device that has a DPC that hasn't migrated yet, so also return any
                 // restrictions saved in userManager.
                 Bundle bundle = mUserManager.getApplicationRestrictions(
                         packageName, UserHandle.of(userId));
-                if (bundle == null || bundle.isEmpty()) {
-                    return new ArrayList<>();
+                if (bundle != null && !bundle.isEmpty()) {
+                    restrictions.add(bundle);
                 }
-                return List.of(bundle);
+                return restrictions;
             });
         }
 
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/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e202bbf..0a7f49d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -324,8 +324,6 @@
             "com.android.server.job.JobSchedulerService";
     private static final String LOCK_SETTINGS_SERVICE_CLASS =
             "com.android.server.locksettings.LockSettingsService$Lifecycle";
-    private static final String RESOURCE_ECONOMY_SERVICE_CLASS =
-            "com.android.server.tare.InternalResourceService";
     private static final String STORAGE_MANAGER_SERVICE_CLASS =
             "com.android.server.StorageManagerService$Lifecycle";
     private static final String STORAGE_STATS_SERVICE_CLASS =
@@ -1640,11 +1638,6 @@
             }
 
             // TODO(aml-jobscheduler): Think about how to do it properly.
-            t.traceBegin("StartResourceEconomy");
-            mSystemServiceManager.startService(RESOURCE_ECONOMY_SERVICE_CLASS);
-            t.traceEnd();
-
-            // TODO(aml-jobscheduler): Think about how to do it properly.
             t.traceBegin("StartAlarmManagerService");
             mSystemServiceManager.startService(ALARM_MANAGER_SERVICE_CLASS);
             t.traceEnd();
diff --git a/services/java/com/android/server/flags.aconfig b/services/java/com/android/server/flags.aconfig
index 4b578af..854bc0f 100644
--- a/services/java/com/android/server/flags.aconfig
+++ b/services/java/com/android/server/flags.aconfig
@@ -1,4 +1,5 @@
 package: "android.server"
+container: "system"
 
 flag {
      namespace: "system_performance"
diff --git a/services/permission/TEST_MAPPING b/services/permission/TEST_MAPPING
index 00bfcd3..4de4a56 100644
--- a/services/permission/TEST_MAPPING
+++ b/services/permission/TEST_MAPPING
@@ -103,6 +103,28 @@
                     "include-filter": "android.permission.cts.PermissionMaxSdkVersionTest"
                 }
             ]
+        },
+        {
+            "name": "CtsVirtualDevicesAudioTestCases",
+            "options": [
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "include-filter": "android.virtualdevice.cts.audio.VirtualAudioPermissionTest"
+                }
+            ]
+        },
+        {
+            "name": "CtsVirtualDevicesAppLaunchTestCases",
+            "options": [
+                {
+                    "exclude-annotation": "androidx.test.filters.FlakyTest"
+                },
+                {
+                    "include-filter": "android.virtualdevice.cts.applaunch.VirtualDevicePermissionTest"
+                }
+            ]
         }
     ],
     "imports": [
diff --git a/services/permission/java/com/android/server/permission/access/AccessPolicy.kt b/services/permission/java/com/android/server/permission/access/AccessPolicy.kt
index 36bea7d..3675834 100644
--- a/services/permission/java/com/android/server/permission/access/AccessPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/AccessPolicy.kt
@@ -16,6 +16,7 @@
 
 package com.android.server.permission.access
 
+import android.permission.flags.Flags
 import android.util.Slog
 import com.android.modules.utils.BinaryXmlPullParser
 import com.android.modules.utils.BinaryXmlSerializer
@@ -78,6 +79,9 @@
             setPackageStates(packageStates)
             setDisabledSystemPackageStates(disabledSystemPackageStates)
             packageStates.forEach { (_, packageState) ->
+                if (Flags.ignoreApexPermissions() && packageState.isApex) {
+                    return@forEach
+                }
                 mutateAppIdPackageNames()
                     .mutateOrPut(packageState.appId) { MutableIndexedListSet() }
                     .add(packageState.packageName)
@@ -103,6 +107,9 @@
         newState.mutateUserStatesNoWrite()[userId] = MutableUserState()
         forEachSchemePolicy { with(it) { onUserAdded(userId) } }
         newState.externalState.packageStates.forEach { (_, packageState) ->
+            if (Flags.ignoreApexPermissions() && packageState.isApex) {
+                return@forEach
+            }
             upgradePackageVersion(packageState, userId)
         }
     }
@@ -126,6 +133,9 @@
             setPackageStates(packageStates)
             setDisabledSystemPackageStates(disabledSystemPackageStates)
             packageStates.forEach { (packageName, packageState) ->
+                if (Flags.ignoreApexPermissions() && packageState.isApex) {
+                    return@forEach
+                }
                 if (packageState.volumeUuid == volumeUuid) {
                     // The APK for a package on a mounted storage volume may still be unavailable
                     // due to APK being deleted, e.g. after an OTA.
@@ -151,6 +161,9 @@
             with(it) { onStorageVolumeMounted(volumeUuid, packageNames, isSystemUpdated) }
         }
         packageStates.forEach { (_, packageState) ->
+            if (Flags.ignoreApexPermissions() && packageState.isApex) {
+                return@forEach
+            }
             if (packageState.volumeUuid == volumeUuid) {
                 newState.userStates.forEachIndexed { _, userId, _ ->
                     upgradePackageVersion(packageState, userId)
diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
index 47fd970..63fb468 100644
--- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
@@ -81,6 +81,9 @@
 
     override fun MutateStateScope.onUserAdded(userId: Int) {
         newState.externalState.packageStates.forEach { (_, packageState) ->
+            if (Flags.ignoreApexPermissions() && packageState.isApex) {
+                return@forEach
+            }
             evaluateAllPermissionStatesForPackageAndUser(packageState, userId, null)
         }
         newState.externalState.appIdPackageNames.forEachIndexed { _, appId, _ ->
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 b32c544..11893e7 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
@@ -1445,6 +1445,9 @@
         val packageStates = packageManagerLocal.withUnfilteredSnapshot().use { it.packageStates }
         service.mutateState {
             packageStates.forEach { (packageName, packageState) ->
+                if (Flags.ignoreApexPermissions() && packageState.isApex) {
+                    return@forEach
+                }
                 val androidPackage = packageState.androidPackage ?: return@forEach
                 androidPackage.requestedPermissions.forEach { permissionName ->
                     updatePermissionFlags(
@@ -1877,6 +1880,9 @@
         packageManagerLocal.withUnfilteredSnapshot().use { snapshot ->
             service.mutateState {
                 snapshot.packageStates.forEach { (_, packageState) ->
+                    if (Flags.ignoreApexPermissions() && packageState.isApex) {
+                        return@forEach
+                    }
                     with(policy) { resetRuntimePermissions(packageState.packageName, userId) }
                     with(devicePolicy) { resetRuntimePermissions(packageState.packageName, userId) }
                 }
@@ -1918,8 +1924,11 @@
         }
 
         packageManagerLocal.withUnfilteredSnapshot().use { snapshot ->
-            snapshot.packageStates.forEach packageStates@{ (_, packageState) ->
-                val androidPackage = packageState.androidPackage ?: return@packageStates
+            snapshot.packageStates.forEach { (_, packageState) ->
+                if (Flags.ignoreApexPermissions() && packageState.isApex) {
+                    return@forEach
+                }
+                val androidPackage = packageState.androidPackage ?: return@forEach
                 if (permissionName in androidPackage.requestedPermissions) {
                     packageNames += androidPackage.packageName
                 }
@@ -1934,6 +1943,9 @@
         val permissions = service.getState { with(policy) { getPermissions() } }
         packageManagerLocal.withUnfilteredSnapshot().use { snapshot ->
             snapshot.packageStates.forEach packageStates@{ (_, packageState) ->
+                if (Flags.ignoreApexPermissions() && packageState.isApex) {
+                    return@packageStates
+                }
                 val androidPackage = packageState.androidPackage ?: return@packageStates
                 androidPackage.requestedPermissions.forEach requestedPermissions@{ permissionName ->
                     val permission = permissions[permissionName] ?: return@requestedPermissions
@@ -2060,6 +2072,9 @@
 
         val appIdPackageNames = MutableIndexedMap<Int, MutableIndexedSet<String>>()
         packageStates.forEach { (_, packageState) ->
+            if (Flags.ignoreApexPermissions() && packageState.isApex) {
+                return@forEach
+            }
             appIdPackageNames
                 .getOrPut(packageState.appId) { MutableIndexedSet() }
                 .add(packageState.packageName)
@@ -2313,6 +2328,10 @@
         isInstantApp: Boolean,
         oldPackage: AndroidPackage?
     ) {
+        if (Flags.ignoreApexPermissions() && packageState.isApex) {
+            return
+        }
+
         synchronized(storageVolumeLock) {
             // Accumulating the package names here because we want to maintain the same call order
             // of onPackageAdded() and reuse this order in onStorageVolumeAdded(). We need the
@@ -2339,6 +2358,10 @@
         params: PermissionManagerServiceInternal.PackageInstalledParams,
         userId: Int
     ) {
+        if (Flags.ignoreApexPermissions() && androidPackage.isApex) {
+            return
+        }
+
         if (params === PermissionManagerServiceInternal.PackageInstalledParams.DEFAULT) {
             // TODO: We should actually stop calling onPackageInstalled() when we are passing
             //  PackageInstalledParams.DEFAULT in InstallPackageHelper, because there's actually no
@@ -2391,6 +2414,10 @@
         sharedUserPkgs: List<AndroidPackage>,
         userId: Int
     ) {
+        if (Flags.ignoreApexPermissions() && packageState.isApex) {
+            return
+        }
+
         val userIds =
             if (userId == UserHandle.USER_ALL) {
                 userManagerService.userIdsIncludingPreCreated
diff --git a/services/tests/VpnTests/java/com/android/server/VpnManagerServiceTest.java b/services/tests/VpnTests/java/com/android/server/VpnManagerServiceTest.java
index ecc70e3..8495de4 100644
--- a/services/tests/VpnTests/java/com/android/server/VpnManagerServiceTest.java
+++ b/services/tests/VpnTests/java/com/android/server/VpnManagerServiceTest.java
@@ -397,4 +397,35 @@
         // Even lockdown is enabled but no Vpn is created for SECONDARY_USER.
         assertNull(mService.getVpnLockdownAllowlist(SECONDARY_USER.id));
     }
+
+    @Test
+    public void testGetFromVpnProfileStore() {
+        final String name = Credentials.VPN + TEST_VPN_PKG;
+        mService.getFromVpnProfileStore(name);
+        verify(mVpnProfileStore).get(name);
+    }
+
+    @Test
+    public void testPutIntoVpnProfileStore() {
+        final String name = Credentials.VPN + TEST_VPN_PKG;
+        final VpnProfile vpnProfile = new VpnProfile(TEST_VPN_PKG);
+        final byte[] encodedProfile = vpnProfile.encode();
+
+        mService.putIntoVpnProfileStore(name, encodedProfile);
+        verify(mVpnProfileStore).put(name, encodedProfile);
+    }
+
+    @Test
+    public void testRemoveFromVpnProfileStore() {
+        final String name = Credentials.VPN + TEST_VPN_PKG;
+        mService.removeFromVpnProfileStore(name);
+        verify(mVpnProfileStore).remove(name);
+    }
+
+    @Test
+    public void testListFromVpnProfileStore() {
+        final String name = Credentials.VPN + TEST_VPN_PKG;
+        mService.listFromVpnProfileStore(name);
+        verify(mVpnProfileStore).list(name);
+    }
 }
diff --git a/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
index 54de64e..64253e1 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/AutomaticBrightnessControllerTest.java
@@ -53,6 +53,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.display.brightness.clamper.BrightnessClamperController;
+import com.android.server.display.config.HysteresisLevels;
 import com.android.server.testutils.OffsettableClock;
 
 import org.junit.After;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 494a667..b80d44f 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -55,6 +55,7 @@
 
 import com.android.internal.R;
 import com.android.server.display.config.HdrBrightnessData;
+import com.android.server.display.config.HysteresisLevels;
 import com.android.server.display.config.IdleScreenRefreshRateTimeoutLuxThresholdPoint;
 import com.android.server.display.config.ThermalStatus;
 import com.android.server.display.feature.DisplayManagerFlags;
@@ -169,53 +170,57 @@
         assertArrayEquals(mDisplayDeviceConfig.getBacklight(), BRIGHTNESS, ZERO_DELTA);
 
         // Test thresholds
-        assertEquals(10, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold(),
-                ZERO_DELTA);
-        assertEquals(20, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThresholdIdle(),
-                ZERO_DELTA);
-        assertEquals(30, mDisplayDeviceConfig.getAmbientLuxDarkeningMinThreshold(), ZERO_DELTA);
-        assertEquals(40, mDisplayDeviceConfig.getAmbientLuxDarkeningMinThresholdIdle(), ZERO_DELTA);
+        HysteresisLevels ambientHysteresis = mDisplayDeviceConfig.getAmbientBrightnessHysteresis();
+        HysteresisLevels ambientIdleHysteresis =
+                mDisplayDeviceConfig.getAmbientBrightnessIdleHysteresis();
+        HysteresisLevels screenHysteresis = mDisplayDeviceConfig.getScreenBrightnessHysteresis();
+        HysteresisLevels screenIdleHysteresis =
+                mDisplayDeviceConfig.getScreenBrightnessIdleHysteresis();
+        assertEquals(10, ambientHysteresis.getMinBrightening(), ZERO_DELTA);
+        assertEquals(20, ambientIdleHysteresis.getMinBrightening(), ZERO_DELTA);
+        assertEquals(30, ambientHysteresis.getMinDarkening(), ZERO_DELTA);
+        assertEquals(40, ambientIdleHysteresis.getMinDarkening(), ZERO_DELTA);
 
-        assertEquals(0.1f, mDisplayDeviceConfig.getScreenBrighteningMinThreshold(), ZERO_DELTA);
-        assertEquals(0.2f, mDisplayDeviceConfig.getScreenBrighteningMinThresholdIdle(), ZERO_DELTA);
-        assertEquals(0.3f, mDisplayDeviceConfig.getScreenDarkeningMinThreshold(), ZERO_DELTA);
-        assertEquals(0.4f, mDisplayDeviceConfig.getScreenDarkeningMinThresholdIdle(), ZERO_DELTA);
+        assertEquals(0.1f, screenHysteresis.getMinBrightening(), ZERO_DELTA);
+        assertEquals(0.2f, screenIdleHysteresis.getMinBrightening(), ZERO_DELTA);
+        assertEquals(0.3f, screenHysteresis.getMinDarkening(), ZERO_DELTA);
+        assertEquals(0.4f, screenIdleHysteresis.getMinDarkening(), ZERO_DELTA);
 
         assertArrayEquals(new float[]{0, 0.10f, 0.20f},
-                mDisplayDeviceConfig.getScreenBrighteningLevels(), ZERO_DELTA);
-        assertArrayEquals(new float[]{9, 10, 11},
-                mDisplayDeviceConfig.getScreenBrighteningPercentages(), ZERO_DELTA);
+                screenHysteresis.getBrighteningThresholdLevels(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.09f, 0.10f, 0.11f},
+                screenHysteresis.getBrighteningThresholdsPercentages(), ZERO_DELTA);
         assertArrayEquals(new float[]{0, 0.11f, 0.21f},
-                mDisplayDeviceConfig.getScreenDarkeningLevels(), ZERO_DELTA);
-        assertArrayEquals(new float[]{11, 12, 13},
-                mDisplayDeviceConfig.getScreenDarkeningPercentages(), ZERO_DELTA);
+                screenHysteresis.getDarkeningThresholdLevels(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.11f, 0.12f, 0.13f},
+                screenHysteresis.getDarkeningThresholdsPercentages(), ZERO_DELTA);
 
         assertArrayEquals(new float[]{0, 100, 200},
-                mDisplayDeviceConfig.getAmbientBrighteningLevels(), ZERO_DELTA);
-        assertArrayEquals(new float[]{13, 14, 15},
-                mDisplayDeviceConfig.getAmbientBrighteningPercentages(), ZERO_DELTA);
+                ambientHysteresis.getBrighteningThresholdLevels(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.13f, 0.14f, 0.15f},
+                ambientHysteresis.getBrighteningThresholdsPercentages(), ZERO_DELTA);
         assertArrayEquals(new float[]{0, 300, 400},
-                mDisplayDeviceConfig.getAmbientDarkeningLevels(), ZERO_DELTA);
-        assertArrayEquals(new float[]{15, 16, 17},
-                mDisplayDeviceConfig.getAmbientDarkeningPercentages(), ZERO_DELTA);
+                ambientHysteresis.getDarkeningThresholdLevels(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.15f, 0.16f, 0.17f},
+                ambientHysteresis.getDarkeningThresholdsPercentages(), ZERO_DELTA);
 
         assertArrayEquals(new float[]{0, 0.12f, 0.22f},
-                mDisplayDeviceConfig.getScreenBrighteningLevelsIdle(), ZERO_DELTA);
-        assertArrayEquals(new float[]{17, 18, 19},
-                mDisplayDeviceConfig.getScreenBrighteningPercentagesIdle(), ZERO_DELTA);
+                screenIdleHysteresis.getBrighteningThresholdLevels(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.17f, 0.18f, 0.19f},
+                screenIdleHysteresis.getBrighteningThresholdsPercentages(), ZERO_DELTA);
         assertArrayEquals(new float[]{0, 0.13f, 0.23f},
-                mDisplayDeviceConfig.getScreenDarkeningLevelsIdle(), ZERO_DELTA);
-        assertArrayEquals(new float[]{19, 20, 21},
-                mDisplayDeviceConfig.getScreenDarkeningPercentagesIdle(), ZERO_DELTA);
+                screenIdleHysteresis.getDarkeningThresholdLevels(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.19f, 0.20f, 0.21f},
+                screenIdleHysteresis.getDarkeningThresholdsPercentages(), ZERO_DELTA);
 
         assertArrayEquals(new float[]{0, 500, 600},
-                mDisplayDeviceConfig.getAmbientBrighteningLevelsIdle(), ZERO_DELTA);
-        assertArrayEquals(new float[]{21, 22, 23},
-                mDisplayDeviceConfig.getAmbientBrighteningPercentagesIdle(), ZERO_DELTA);
+                ambientIdleHysteresis.getBrighteningThresholdLevels(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.21f, 0.22f, 0.23f},
+                ambientIdleHysteresis.getBrighteningThresholdsPercentages(), ZERO_DELTA);
         assertArrayEquals(new float[]{0, 700, 800},
-                mDisplayDeviceConfig.getAmbientDarkeningLevelsIdle(), ZERO_DELTA);
-        assertArrayEquals(new float[]{23, 24, 25},
-                mDisplayDeviceConfig.getAmbientDarkeningPercentagesIdle(), ZERO_DELTA);
+                ambientIdleHysteresis.getDarkeningThresholdLevels(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.23f, 0.24f, 0.25f},
+                ambientIdleHysteresis.getDarkeningThresholdsPercentages(), ZERO_DELTA);
 
         assertEquals(75, mDisplayDeviceConfig.getDefaultLowBlockingZoneRefreshRate());
         assertEquals(90, mDisplayDeviceConfig.getDefaultHighBlockingZoneRefreshRate());
@@ -686,55 +691,60 @@
                 new float[]{brightnessIntToFloat(50), brightnessIntToFloat(100),
                         brightnessIntToFloat(150)}, SMALL_DELTA);
 
+        HysteresisLevels ambientHysteresis = mDisplayDeviceConfig.getAmbientBrightnessHysteresis();
+        HysteresisLevels ambientIdleHysteresis =
+                mDisplayDeviceConfig.getAmbientBrightnessIdleHysteresis();
+        HysteresisLevels screenHysteresis = mDisplayDeviceConfig.getScreenBrightnessHysteresis();
+        HysteresisLevels screenIdleHysteresis =
+                mDisplayDeviceConfig.getScreenBrightnessIdleHysteresis();
         // Test thresholds
-        assertEquals(0, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThreshold(), ZERO_DELTA);
-        assertEquals(0, mDisplayDeviceConfig.getAmbientLuxBrighteningMinThresholdIdle(),
-                ZERO_DELTA);
-        assertEquals(0, mDisplayDeviceConfig.getAmbientLuxDarkeningMinThreshold(), ZERO_DELTA);
-        assertEquals(0, mDisplayDeviceConfig.getAmbientLuxDarkeningMinThresholdIdle(), ZERO_DELTA);
+        assertEquals(0, ambientHysteresis.getMinBrightening(), ZERO_DELTA);
+        assertEquals(0, ambientIdleHysteresis.getMinBrightening(), ZERO_DELTA);
+        assertEquals(0, ambientHysteresis.getMinDarkening(), ZERO_DELTA);
+        assertEquals(0, ambientIdleHysteresis.getMinDarkening(), ZERO_DELTA);
 
-        assertEquals(0, mDisplayDeviceConfig.getScreenBrighteningMinThreshold(), ZERO_DELTA);
-        assertEquals(0, mDisplayDeviceConfig.getScreenBrighteningMinThresholdIdle(), ZERO_DELTA);
-        assertEquals(0, mDisplayDeviceConfig.getScreenDarkeningMinThreshold(), ZERO_DELTA);
-        assertEquals(0, mDisplayDeviceConfig.getScreenDarkeningMinThresholdIdle(), ZERO_DELTA);
+        assertEquals(0, screenHysteresis.getMinBrightening(), ZERO_DELTA);
+        assertEquals(0, screenIdleHysteresis.getMinBrightening(), ZERO_DELTA);
+        assertEquals(0, screenHysteresis.getMinDarkening(), ZERO_DELTA);
+        assertEquals(0, screenIdleHysteresis.getMinDarkening(), ZERO_DELTA);
 
         // screen levels will be considered "old screen brightness scale"
         // and therefore will divide by 255
         assertArrayEquals(new float[]{0, 42 / 255f, 43 / 255f},
-                mDisplayDeviceConfig.getScreenBrighteningLevels(), SMALL_DELTA);
-        assertArrayEquals(new float[]{35, 36, 37},
-                mDisplayDeviceConfig.getScreenBrighteningPercentages(), ZERO_DELTA);
+                screenHysteresis.getBrighteningThresholdLevels(), SMALL_DELTA);
+        assertArrayEquals(new float[]{0.35f, 0.36f, 0.37f},
+                screenHysteresis.getBrighteningThresholdsPercentages(), ZERO_DELTA);
         assertArrayEquals(new float[]{0, 42 / 255f, 43 / 255f},
-                mDisplayDeviceConfig.getScreenDarkeningLevels(), SMALL_DELTA);
-        assertArrayEquals(new float[]{37, 38, 39},
-                mDisplayDeviceConfig.getScreenDarkeningPercentages(), ZERO_DELTA);
+                screenHysteresis.getDarkeningThresholdLevels(), SMALL_DELTA);
+        assertArrayEquals(new float[]{0.37f, 0.38f, 0.39f},
+                screenHysteresis.getDarkeningThresholdsPercentages(), ZERO_DELTA);
 
         assertArrayEquals(new float[]{0, 30, 31},
-                mDisplayDeviceConfig.getAmbientBrighteningLevels(), ZERO_DELTA);
-        assertArrayEquals(new float[]{27, 28, 29},
-                mDisplayDeviceConfig.getAmbientBrighteningPercentages(), ZERO_DELTA);
+                ambientHysteresis.getBrighteningThresholdLevels(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.27f, 0.28f, 0.29f},
+                ambientHysteresis.getBrighteningThresholdsPercentages(), ZERO_DELTA);
         assertArrayEquals(new float[]{0, 30, 31},
-                mDisplayDeviceConfig.getAmbientDarkeningLevels(), ZERO_DELTA);
-        assertArrayEquals(new float[]{29, 30, 31},
-                mDisplayDeviceConfig.getAmbientDarkeningPercentages(), ZERO_DELTA);
+                ambientHysteresis.getDarkeningThresholdLevels(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.29f, 0.30f, 0.31f},
+                ambientHysteresis.getDarkeningThresholdsPercentages(), ZERO_DELTA);
 
         assertArrayEquals(new float[]{0, 42 / 255f, 43 / 255f},
-                mDisplayDeviceConfig.getScreenBrighteningLevelsIdle(), SMALL_DELTA);
-        assertArrayEquals(new float[]{35, 36, 37},
-                mDisplayDeviceConfig.getScreenBrighteningPercentagesIdle(), ZERO_DELTA);
+                screenIdleHysteresis.getBrighteningThresholdLevels(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.35f, 0.36f, 0.37f},
+                screenIdleHysteresis.getBrighteningThresholdsPercentages(), ZERO_DELTA);
         assertArrayEquals(new float[]{0, 42 / 255f, 43 / 255f},
-                mDisplayDeviceConfig.getScreenDarkeningLevelsIdle(), SMALL_DELTA);
-        assertArrayEquals(new float[]{37, 38, 39},
-                mDisplayDeviceConfig.getScreenDarkeningPercentagesIdle(), ZERO_DELTA);
+                screenIdleHysteresis.getDarkeningThresholdLevels(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.37f, 0.38f, 0.39f},
+                screenIdleHysteresis.getDarkeningThresholdsPercentages(), ZERO_DELTA);
 
         assertArrayEquals(new float[]{0, 30, 31},
-                mDisplayDeviceConfig.getAmbientBrighteningLevelsIdle(), ZERO_DELTA);
-        assertArrayEquals(new float[]{27, 28, 29},
-                mDisplayDeviceConfig.getAmbientBrighteningPercentagesIdle(), ZERO_DELTA);
+                ambientIdleHysteresis.getBrighteningThresholdLevels(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.27f, 0.28f, 0.29f},
+                ambientIdleHysteresis.getBrighteningThresholdsPercentages(), ZERO_DELTA);
         assertArrayEquals(new float[]{0, 30, 31},
-                mDisplayDeviceConfig.getAmbientDarkeningLevelsIdle(), ZERO_DELTA);
-        assertArrayEquals(new float[]{29, 30, 31},
-                mDisplayDeviceConfig.getAmbientDarkeningPercentagesIdle(), ZERO_DELTA);
+                ambientIdleHysteresis.getDarkeningThresholdLevels(), ZERO_DELTA);
+        assertArrayEquals(new float[]{0.29f, 0.30f, 0.31f},
+                ambientIdleHysteresis.getDarkeningThresholdsPercentages(), ZERO_DELTA);
         assertEquals(mDisplayDeviceConfig.getDefaultLowBlockingZoneRefreshRate(),
                 DEFAULT_LOW_BLOCKING_ZONE_REFRESH_RATE);
         assertEquals(mDisplayDeviceConfig.getDefaultHighBlockingZoneRefreshRate(),
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java
index 1c71abc..0029674 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceTest.java
@@ -26,6 +26,7 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
+import android.view.Display;
 import android.view.SurfaceControl;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -72,6 +73,7 @@
 
     @Test
     public void testGetDisplaySurfaceDefaultSizeLocked_notRotated_anisotropyCorrection() {
+        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
         mDisplayDeviceInfo.xDpi = 0.5f;
         mDisplayDeviceInfo.yDpi = 1.0f;
         DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
@@ -81,6 +83,16 @@
     }
 
     @Test
+    public void testGetDisplaySurfaceDefaultSizeLocked_notRotated_noAnisotropyCorrection() {
+        mDisplayDeviceInfo.type = Display.TYPE_INTERNAL;
+        mDisplayDeviceInfo.xDpi = 0.5f;
+        mDisplayDeviceInfo.yDpi = 1.0f;
+        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
+                mMockDisplayAdapter, /*isAnisotropyCorrectionEnabled=*/ true);
+        assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(PORTRAIT_SIZE);
+    }
+
+    @Test
     public void testGetDisplaySurfaceDefaultSizeLocked_notRotated() {
         DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
                 mMockDisplayAdapter);
@@ -97,6 +109,7 @@
 
     @Test
     public void testGetDisplaySurfaceDefaultSizeLocked_rotation90_anisotropyCorrection() {
+        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
         mDisplayDeviceInfo.xDpi = 0.5f;
         mDisplayDeviceInfo.yDpi = 1.0f;
         DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
@@ -107,6 +120,17 @@
     }
 
     @Test
+    public void testGetDisplaySurfaceDefaultSizeLocked_rotation90_noAnisotropyCorrection() {
+        mDisplayDeviceInfo.type = Display.TYPE_INTERNAL;
+        mDisplayDeviceInfo.xDpi = 0.5f;
+        mDisplayDeviceInfo.yDpi = 1.0f;
+        DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
+                mMockDisplayAdapter, /*isAnisotropyCorrectionEnabled=*/ true);
+        displayDevice.setProjectionLocked(mMockTransaction, ROTATION_90, new Rect(), new Rect());
+        assertThat(displayDevice.getDisplaySurfaceDefaultSizeLocked()).isEqualTo(LANDSCAPE_SIZE);
+    }
+
+    @Test
     public void testGetDisplaySurfaceDefaultSizeLocked_rotation90() {
         DisplayDevice displayDevice = new FakeDisplayDevice(mDisplayDeviceInfo,
                 mMockDisplayAdapter);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
index afb87d1..de93914 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -82,6 +82,7 @@
 import com.android.server.display.brightness.clamper.BrightnessClamperController;
 import com.android.server.display.brightness.clamper.HdrClamper;
 import com.android.server.display.color.ColorDisplayService;
+import com.android.server.display.config.HysteresisLevels;
 import com.android.server.display.config.SensorData;
 import com.android.server.display.feature.DisplayManagerFlags;
 import com.android.server.display.feature.flags.Flags;
@@ -1954,6 +1955,14 @@
                 .thenReturn(BRIGHTNESS_RAMP_INCREASE_MAX_IDLE);
         when(displayDeviceConfigMock.getBrightnessRampDecreaseMaxIdleMillis())
                 .thenReturn(BRIGHTNESS_RAMP_DECREASE_MAX_IDLE);
+
+        final HysteresisLevels hysteresisLevels = mock(HysteresisLevels.class);
+        when(displayDeviceConfigMock.getAmbientBrightnessHysteresis()).thenReturn(hysteresisLevels);
+        when(displayDeviceConfigMock.getAmbientBrightnessIdleHysteresis()).thenReturn(
+                hysteresisLevels);
+        when(displayDeviceConfigMock.getScreenBrightnessHysteresis()).thenReturn(hysteresisLevels);
+        when(displayDeviceConfigMock.getScreenBrightnessIdleHysteresis()).thenReturn(
+                hysteresisLevels);
     }
 
     private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
@@ -1995,7 +2004,7 @@
 
         TestInjector injector = spy(new TestInjector(displayPowerState, animator,
                 automaticBrightnessController, wakelockController, brightnessMappingStrategy,
-                hysteresisLevels, screenOffBrightnessSensorController,
+                screenOffBrightnessSensorController,
                 hbmController, normalBrightnessModeController, hdrClamper,
                 clamperController, mDisplayManagerFlagsMock));
 
@@ -2005,6 +2014,11 @@
         final BrightnessSetting brightnessSetting = mock(BrightnessSetting.class);
         final DisplayDeviceConfig config = mock(DisplayDeviceConfig.class);
 
+        when(config.getAmbientBrightnessHysteresis()).thenReturn(hysteresisLevels);
+        when(config.getAmbientBrightnessIdleHysteresis()).thenReturn(hysteresisLevels);
+        when(config.getScreenBrightnessHysteresis()).thenReturn(hysteresisLevels);
+        when(config.getScreenBrightnessIdleHysteresis()).thenReturn(hysteresisLevels);
+
         setUpDisplay(displayId, uniqueId, display, device, config, isEnabled);
         when(config.isAutoBrightnessAvailable()).thenReturn(isAutoBrightnessAvailable);
 
@@ -2080,7 +2094,6 @@
         private final AutomaticBrightnessController mAutomaticBrightnessController;
         private final WakelockController mWakelockController;
         private final BrightnessMappingStrategy mBrightnessMappingStrategy;
-        private final HysteresisLevels mHysteresisLevels;
         private final ScreenOffBrightnessSensorController mScreenOffBrightnessSensorController;
         private final HighBrightnessModeController mHighBrightnessModeController;
 
@@ -2096,7 +2109,6 @@
                 AutomaticBrightnessController automaticBrightnessController,
                 WakelockController wakelockController,
                 BrightnessMappingStrategy brightnessMappingStrategy,
-                HysteresisLevels hysteresisLevels,
                 ScreenOffBrightnessSensorController screenOffBrightnessSensorController,
                 HighBrightnessModeController highBrightnessModeController,
                 NormalBrightnessModeController normalBrightnessModeController,
@@ -2108,7 +2120,6 @@
             mAutomaticBrightnessController = automaticBrightnessController;
             mWakelockController = wakelockController;
             mBrightnessMappingStrategy = brightnessMappingStrategy;
-            mHysteresisLevels = hysteresisLevels;
             mScreenOffBrightnessSensorController = screenOffBrightnessSensorController;
             mHighBrightnessModeController = highBrightnessModeController;
             mNormalBrightnessModeController = normalBrightnessModeController;
@@ -2186,22 +2197,6 @@
         }
 
         @Override
-        HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
-                float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
-                float[] darkeningThresholdLevels, float minDarkeningThreshold,
-                float minBrighteningThreshold) {
-            return mHysteresisLevels;
-        }
-
-        @Override
-        HysteresisLevels getHysteresisLevels(float[] brighteningThresholdsPercentages,
-                float[] darkeningThresholdsPercentages, float[] brighteningThresholdLevels,
-                float[] darkeningThresholdLevels, float minDarkeningThreshold,
-                float minBrighteningThreshold, boolean potentialOldBrightnessRange) {
-            return mHysteresisLevels;
-        }
-
-        @Override
         ScreenOffBrightnessSensorController getScreenOffBrightnessSensorController(
                 SensorManager sensorManager, Sensor lightSensor, Handler handler,
                 ScreenOffBrightnessSensorController.Clock clock, int[] sensorValueToLux,
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
index d0c7077..1a03e78 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayMapperTest.java
@@ -20,6 +20,8 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.DEFAULT_DISPLAY_GROUP;
 import static android.view.Display.FLAG_REAR;
+import static android.view.Display.STATE_OFF;
+import static android.view.Display.STATE_ON;
 import static android.view.Display.TYPE_EXTERNAL;
 import static android.view.Display.TYPE_INTERNAL;
 import static android.view.Display.TYPE_VIRTUAL;
@@ -28,6 +30,7 @@
 import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED;
 import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED;
 import static com.android.server.display.DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED;
+import static com.android.server.display.DisplayDeviceInfo.DIFF_EVERYTHING;
 import static com.android.server.display.DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY;
 import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED;
 import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_CONNECTED;
@@ -35,6 +38,9 @@
 import static com.android.server.display.LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED;
 import static com.android.server.display.layout.Layout.Display.POSITION_REAR;
 import static com.android.server.display.layout.Layout.Display.POSITION_UNKNOWN;
+import static com.android.server.utils.FoldSettingProvider.SETTING_VALUE_SELECTIVE_STAY_AWAKE;
+import static com.android.server.utils.FoldSettingProvider.SETTING_VALUE_SLEEP_ON_FOLD;
+import static com.android.server.utils.FoldSettingProvider.SETTING_VALUE_STAY_AWAKE_ON_FOLD;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -72,12 +78,17 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.internal.foldables.FoldGracePeriodProvider;
+import com.android.internal.util.test.LocalServiceKeeperRule;
+import com.android.server.LocalServices;
 import com.android.server.display.feature.DisplayManagerFlags;
 import com.android.server.display.layout.DisplayIdProducer;
 import com.android.server.display.layout.Layout;
+import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.utils.FoldSettingProvider;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -96,9 +107,13 @@
 @RunWith(AndroidJUnit4.class)
 public class LogicalDisplayMapperTest {
     private static int sUniqueTestDisplayId = 0;
+    private static final int TIMEOUT_STATE_TRANSITION_MILLIS = 500;
+    private static final int FOLD_SETTLE_DELAY = 1000;
     private static final int DEVICE_STATE_CLOSED = 0;
+    private static final int DEVICE_STATE_HALF_OPEN = 1;
     private static final int DEVICE_STATE_OPEN = 2;
     private static final int FLAG_GO_TO_SLEEP_ON_FOLD = 0;
+    private static final int FLAG_GO_TO_SLEEP_FLAG_SOFT_SLEEP = 2;
     private static int sNextNonDefaultDisplayId = DEFAULT_DISPLAY + 1;
     private static final File NON_EXISTING_FILE = new File("/non_existing_folder/should_not_exist");
 
@@ -113,14 +128,19 @@
 
     private DeviceStateToLayoutMap mDeviceStateToLayoutMapSpy;
 
+    @Rule
+    public LocalServiceKeeperRule mLocalServiceKeeperRule = new LocalServiceKeeperRule();
+
     @Mock LogicalDisplayMapper.Listener mListenerMock;
     @Mock Context mContextMock;
     @Mock FoldSettingProvider mFoldSettingProviderMock;
+    @Mock FoldGracePeriodProvider mFoldGracePeriodProvider;
     @Mock Resources mResourcesMock;
     @Mock IPowerManager mIPowerManagerMock;
     @Mock IThermalService mIThermalServiceMock;
     @Mock DisplayManagerFlags mFlagsMock;
     @Mock DisplayAdapter mDisplayAdapterMock;
+    @Mock WindowManagerPolicy mWindowManagerPolicy;
 
     @Captor ArgumentCaptor<LogicalDisplay> mDisplayCaptor;
     @Captor ArgumentCaptor<Integer> mDisplayEventCaptor;
@@ -131,6 +151,9 @@
         System.setProperty("dexmaker.share_classloader", "true");
         MockitoAnnotations.initMocks(this);
 
+        mLocalServiceKeeperRule.overrideLocalService(WindowManagerPolicy.class,
+                mWindowManagerPolicy);
+
         mDeviceStateToLayoutMapSpy =
                 spy(new DeviceStateToLayoutMap(mIdProducer, mFlagsMock, NON_EXISTING_FILE));
         mDisplayDeviceRepo = new DisplayDeviceRepository(
@@ -160,6 +183,7 @@
                 .thenReturn(Context.POWER_SERVICE);
         when(mFoldSettingProviderMock.shouldStayAwakeOnFold()).thenReturn(false);
         when(mFoldSettingProviderMock.shouldSleepOnFold()).thenReturn(false);
+        when(mFoldSettingProviderMock.shouldSelectiveStayAwakeOnFold()).thenReturn(true);
         when(mIPowerManagerMock.isInteractive()).thenReturn(true);
         when(mContextMock.getSystemService(PowerManager.class)).thenReturn(mPowerManager);
         when(mContextMock.getResources()).thenReturn(mResourcesMock);
@@ -177,9 +201,11 @@
         mLooper = new TestLooper();
         mHandler = new Handler(mLooper.getLooper());
         mLogicalDisplayMapper = new LogicalDisplayMapper(mContextMock, mFoldSettingProviderMock,
+                mFoldGracePeriodProvider,
                 mDisplayDeviceRepo,
                 mListenerMock, new DisplayManagerService.SyncRoot(), mHandler,
                 mDeviceStateToLayoutMapSpy, mFlagsMock);
+        mLogicalDisplayMapper.onWindowManagerReady();
     }
 
 
@@ -681,22 +707,185 @@
         when(mFoldSettingProviderMock.shouldSleepOnFold()).thenReturn(true);
 
         finishBootAndFoldDevice();
+        advanceTime(FOLD_SETTLE_DELAY);
 
         verify(mIPowerManagerMock, atLeastOnce()).goToSleep(anyLong(), anyInt(),
                 eq(FLAG_GO_TO_SLEEP_ON_FOLD));
     }
 
     @Test
+    public void testDeviceShouldPutToSleepWhenFoldSettingSelective() throws RemoteException {
+        when(mFoldSettingProviderMock.shouldSelectiveStayAwakeOnFold()).thenReturn(true);
+
+        finishBootAndFoldDevice();
+        advanceTime(FOLD_SETTLE_DELAY);
+
+        verify(mIPowerManagerMock, atLeastOnce()).goToSleep(anyLong(), anyInt(),
+                eq(FLAG_GO_TO_SLEEP_FLAG_SOFT_SLEEP));
+    }
+
+    @Test
     public void testDeviceShouldNotBePutToSleepWhenSleepSettingFalse() throws RemoteException {
         when(mFoldSettingProviderMock.shouldSleepOnFold()).thenReturn(false);
 
         finishBootAndFoldDevice();
+        advanceTime(FOLD_SETTLE_DELAY);
 
         verify(mIPowerManagerMock, never()).goToSleep(anyLong(), anyInt(),
                 eq(FLAG_GO_TO_SLEEP_ON_FOLD));
     }
 
     @Test
+    public void testWaitForSleepWhenFoldSettingSleep() {
+        // Test device should not be marked ready for transition immediately, when 'Continue
+        // using app on fold' set to 'Never'
+        setFoldLockBehaviorSettingValue(SETTING_VALUE_SLEEP_ON_FOLD);
+        setGracePeriodAvailability(false);
+        FoldableDisplayDevices foldableDisplayDevices = createFoldableDeviceStateToLayoutMap();
+
+        finishBootAndFoldDevice();
+        foldableDisplayDevices.mInner.setState(STATE_OFF);
+        notifyDisplayChanges(foldableDisplayDevices.mOuter);
+
+        assertDisplayDisabled(foldableDisplayDevices.mOuter);
+        assertDisplayEnabled(foldableDisplayDevices.mInner);
+    }
+
+    @Test
+    public void testSwapDeviceStateWithDelayWhenFoldSettingSleep() {
+        // Test device should be marked ready for transition after a delay when 'Continue using
+        // app on fold' set to 'Never'
+        setFoldLockBehaviorSettingValue(SETTING_VALUE_SLEEP_ON_FOLD);
+        setGracePeriodAvailability(false);
+        FoldableDisplayDevices foldableDisplayDevices = createFoldableDeviceStateToLayoutMap();
+
+        finishBootAndFoldDevice();
+        foldableDisplayDevices.mInner.setState(STATE_OFF);
+        notifyDisplayChanges(foldableDisplayDevices.mOuter);
+        advanceTime(TIMEOUT_STATE_TRANSITION_MILLIS);
+
+        assertDisplayEnabled(foldableDisplayDevices.mOuter);
+        assertDisplayDisabled(foldableDisplayDevices.mInner);
+    }
+
+    @Test
+    public void testDisplaySwappedAfterDeviceStateChange_windowManagerIsNotified() {
+        FoldableDisplayDevices foldableDisplayDevices = createFoldableDeviceStateToLayoutMap();
+        mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_OPEN);
+        mLogicalDisplayMapper.onEarlyInteractivityChange(true);
+        mLogicalDisplayMapper.onBootCompleted();
+        advanceTime(1000);
+        clearInvocations(mWindowManagerPolicy);
+
+        // Switch from 'inner' to 'outer' display (fold a foldable device)
+        mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_CLOSED);
+        // Continue folding device state transition by turning off the inner display
+        foldableDisplayDevices.mInner.setState(STATE_OFF);
+        notifyDisplayChanges(foldableDisplayDevices.mOuter);
+        advanceTime(TIMEOUT_STATE_TRANSITION_MILLIS);
+
+        verify(mWindowManagerPolicy).onDisplaySwitchStart(DEFAULT_DISPLAY);
+    }
+
+    @Test
+    public void testCreateNewLogicalDisplay_windowManagerIsNotNotifiedAboutSwitch() {
+        DisplayDevice device1 = createDisplayDevice(TYPE_EXTERNAL, 600, 800,
+                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+        when(mDeviceStateToLayoutMapSpy.size()).thenReturn(1);
+        LogicalDisplay display1 = add(device1);
+
+        assertTrue(display1.isEnabledLocked());
+
+        DisplayDevice device2 = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+        when(mDeviceStateToLayoutMapSpy.size()).thenReturn(2);
+        add(device2);
+
+        // As it is not a display switch but adding a new display, we should not notify
+        // about display switch start to window manager
+        verify(mWindowManagerPolicy, never()).onDisplaySwitchStart(anyInt());
+    }
+
+    @Test
+    public void testDoNotWaitForSleepWhenFoldSettingStayAwake() {
+        // Test device should be marked ready for transition immediately when 'Continue using app
+        // on fold' set to 'Always'
+        setFoldLockBehaviorSettingValue(SETTING_VALUE_STAY_AWAKE_ON_FOLD);
+        setGracePeriodAvailability(false);
+        FoldableDisplayDevices foldableDisplayDevices = createFoldableDeviceStateToLayoutMap();
+
+        finishBootAndFoldDevice();
+        foldableDisplayDevices.mInner.setState(STATE_OFF);
+        notifyDisplayChanges(foldableDisplayDevices.mOuter);
+
+        assertDisplayEnabled(foldableDisplayDevices.mOuter);
+        assertDisplayDisabled(foldableDisplayDevices.mInner);
+    }
+
+    @Test
+    public void testDoNotWaitForSleepWhenFoldSettingSelectiveStayAwake() {
+        // Test device should be marked ready for transition immediately when 'Continue using app
+        // on fold' set to 'Swipe up to continue'
+        setFoldLockBehaviorSettingValue(SETTING_VALUE_SELECTIVE_STAY_AWAKE);
+        setGracePeriodAvailability(true);
+        FoldableDisplayDevices foldableDisplayDevices = createFoldableDeviceStateToLayoutMap();
+
+        finishBootAndFoldDevice();
+        foldableDisplayDevices.mInner.setState(STATE_OFF);
+        notifyDisplayChanges(foldableDisplayDevices.mOuter);
+
+        assertDisplayEnabled(foldableDisplayDevices.mOuter);
+        assertDisplayDisabled(foldableDisplayDevices.mInner);
+    }
+
+    @Test
+    public void testWaitForSleepWhenGracePeriodSettingDisabled() {
+        // Test device should not be marked ready for transition immediately when 'Continue using
+        // app on fold' set to 'Swipe up to continue' but Grace Period flag is disabled
+        setFoldLockBehaviorSettingValue(SETTING_VALUE_SELECTIVE_STAY_AWAKE);
+        setGracePeriodAvailability(false);
+        FoldableDisplayDevices foldableDisplayDevices = createFoldableDeviceStateToLayoutMap();
+
+        finishBootAndFoldDevice();
+        foldableDisplayDevices.mInner.setState(STATE_OFF);
+        notifyDisplayChanges(foldableDisplayDevices.mOuter);
+
+        assertDisplayDisabled(foldableDisplayDevices.mOuter);
+        assertDisplayEnabled(foldableDisplayDevices.mInner);
+    }
+
+    @Test
+    public void testWaitForSleepWhenTransitionDisplayStaysOn() {
+        // Test device should not be marked ready for transition immediately, when 'Continue
+        // using app on fold' set to 'Always' but not all transitioning displays are OFF.
+        setFoldLockBehaviorSettingValue(SETTING_VALUE_STAY_AWAKE_ON_FOLD);
+        setGracePeriodAvailability(false);
+        FoldableDisplayDevices foldableDisplayDevices = createFoldableDeviceStateToLayoutMap();
+
+        finishBootAndFoldDevice();
+        notifyDisplayChanges(foldableDisplayDevices.mOuter);
+
+        assertDisplayDisabled(foldableDisplayDevices.mOuter);
+        assertDisplayEnabled(foldableDisplayDevices.mInner);
+    }
+
+    @Test
+    public void testSwapDeviceStateWithDelayWhenTransitionDisplayStaysOn() {
+        // Test device should be marked ready for transition after a delay, when 'Continue using
+        // app on fold' set to 'Never' but not all transitioning displays are OFF.
+        setFoldLockBehaviorSettingValue(SETTING_VALUE_SLEEP_ON_FOLD);
+        setGracePeriodAvailability(false);
+        FoldableDisplayDevices foldableDisplayDevices = createFoldableDeviceStateToLayoutMap();
+
+        finishBootAndFoldDevice();
+        notifyDisplayChanges(foldableDisplayDevices.mOuter);
+        advanceTime(TIMEOUT_STATE_TRANSITION_MILLIS);
+
+        assertDisplayEnabled(foldableDisplayDevices.mOuter);
+        assertDisplayDisabled(foldableDisplayDevices.mInner);
+    }
+
+    @Test
     public void testDeviceStateLocked() {
         DisplayDevice device1 = createDisplayDevice(TYPE_INTERNAL, 600, 800,
                 FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
@@ -950,13 +1139,77 @@
     // Helper Methods
     /////////////////
 
+    private void setGracePeriodAvailability(boolean isGracePeriodEnabled) {
+        when(mFoldGracePeriodProvider.isEnabled()).thenReturn(isGracePeriodEnabled);
+    }
+
+    private void setFoldLockBehaviorSettingValue(String foldLockBehaviorSettingValue) {
+        when(mFoldSettingProviderMock.shouldSleepOnFold()).thenReturn(false);
+        when(mFoldSettingProviderMock.shouldStayAwakeOnFold()).thenReturn(false);
+        when(mFoldSettingProviderMock.shouldSelectiveStayAwakeOnFold()).thenReturn(false);
+
+        switch (foldLockBehaviorSettingValue) {
+            case SETTING_VALUE_STAY_AWAKE_ON_FOLD:
+                when(mFoldSettingProviderMock.shouldStayAwakeOnFold()).thenReturn(true);
+                break;
+
+            case SETTING_VALUE_SLEEP_ON_FOLD:
+                when(mFoldSettingProviderMock.shouldSleepOnFold()).thenReturn(true);
+                break;
+
+            default:
+                when(mFoldSettingProviderMock.shouldSelectiveStayAwakeOnFold()).thenReturn(true);
+                break;
+        }
+    }
+
+    private FoldableDisplayDevices createFoldableDeviceStateToLayoutMap() {
+        TestDisplayDevice outer = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+        TestDisplayDevice inner = createDisplayDevice(TYPE_INTERNAL, 600, 800,
+                FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY);
+        outer.setState(STATE_OFF);
+        inner.setState(STATE_ON);
+
+        Layout layout = new Layout();
+        createDefaultDisplay(layout, outer);
+        createNonDefaultDisplay(layout, inner, /* enabled= */ false, /* group= */ null);
+        when(mDeviceStateToLayoutMapSpy.get(DEVICE_STATE_CLOSED)).thenReturn(layout);
+
+        layout = new Layout();
+        createNonDefaultDisplay(layout, outer, /* enabled= */ false, /* group= */ null);
+        createDefaultDisplay(layout, inner);
+        when(mDeviceStateToLayoutMapSpy.get(DEVICE_STATE_HALF_OPEN)).thenReturn(layout);
+        when(mDeviceStateToLayoutMapSpy.get(DEVICE_STATE_OPEN)).thenReturn(layout);
+        when(mDeviceStateToLayoutMapSpy.size()).thenReturn(4);
+
+        add(outer);
+        add(inner);
+
+        return new FoldableDisplayDevices(outer, inner);
+    }
+
     private void finishBootAndFoldDevice() {
         mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_OPEN);
+        mLogicalDisplayMapper.onEarlyInteractivityChange(true);
         advanceTime(1000);
         mLogicalDisplayMapper.onBootCompleted();
         advanceTime(1000);
         mLogicalDisplayMapper.setDeviceStateLocked(DEVICE_STATE_CLOSED);
-        advanceTime(1000);
+    }
+
+    private void notifyDisplayChanges(TestDisplayDevice displayDevice) {
+        mLogicalDisplayMapper.onDisplayDeviceChangedLocked(displayDevice, DIFF_EVERYTHING);
+    }
+
+    private void assertDisplayEnabled(DisplayDevice displayDevice) {
+        assertThat(
+                mLogicalDisplayMapper.getDisplayLocked(displayDevice).isEnabledLocked()).isTrue();
+    }
+
+    private void assertDisplayDisabled(DisplayDevice displayDevice) {
+        assertThat(
+                mLogicalDisplayMapper.getDisplayLocked(displayDevice).isEnabledLocked()).isFalse();
     }
 
     private void createDefaultDisplay(Layout layout, DisplayDevice device) {
@@ -1058,6 +1311,16 @@
         assertNotEquals(DEFAULT_DISPLAY, id(displayRemoved));
     }
 
+    private final static class FoldableDisplayDevices {
+        final TestDisplayDevice mOuter;
+        final TestDisplayDevice mInner;
+
+        FoldableDisplayDevices(TestDisplayDevice outer, TestDisplayDevice inner) {
+            this.mOuter = outer;
+            this.mInner = inner;
+        }
+    }
+
     class TestDisplayDevice extends DisplayDevice {
         private DisplayDeviceInfo mInfo;
         private DisplayDeviceInfo mSentInfo;
@@ -1083,6 +1346,16 @@
             mSentInfo = null;
         }
 
+        public void setState(int state) {
+            mState = state;
+            if (mSentInfo == null) {
+                mInfo.state = state;
+            } else {
+                mInfo.state = state;
+                mSentInfo.state = state;
+            }
+        }
+
         @Override
         public boolean hasStableUniqueId() {
             return true;
diff --git a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java
index e798aa2..779445e 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LogicalDisplayTest.java
@@ -142,8 +142,39 @@
         assertEquals(new Point(0, DISPLAY_HEIGHT / 4), mLogicalDisplay.getDisplayPosition());
     }
 
+
+    @Test
+    public void testNoLetterbox_noAnisotropyCorrectionForInternalDisplay() {
+        mDisplayDeviceInfo.type = Display.TYPE_INTERNAL;
+        mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice,
+                /*isAnisotropyCorrectionEnabled=*/ true,
+                /*isAlwaysRotateDisplayDeviceEnabled=*/ true);
+
+        // In case of Anisotropy of pixels, then the content should be rescaled so it would adjust
+        // to using the whole screen. This is because display will rescale it back to fill the
+        // screen (in case the display menu setting is set to stretch the pixels across the display)
+        mDisplayDeviceInfo.xDpi = 0.5f;
+        mDisplayDeviceInfo.yDpi = 1.0f;
+
+        mLogicalDisplay.updateLocked(mDeviceRepo);
+        var originalDisplayInfo = mLogicalDisplay.getDisplayInfoLocked();
+        // Content width not scaled
+        assertEquals(DISPLAY_WIDTH, originalDisplayInfo.logicalWidth);
+        assertEquals(DISPLAY_HEIGHT, originalDisplayInfo.logicalHeight);
+
+        SurfaceControl.Transaction t = mock(SurfaceControl.Transaction.class);
+        mLogicalDisplay.configureDisplayLocked(t, mDisplayDevice, false);
+
+        // Applications need to think that they are shown on a display with square pixels.
+        // as applications can be displayed on multiple displays simultaneously (mirrored).
+        // Content is too wide, should have become letterboxed - but it won't because of anisotropy
+        // correction
+        assertEquals(new Point(0, 0), mLogicalDisplay.getDisplayPosition());
+    }
+
     @Test
     public void testNoLetterbox_anisotropyCorrection() {
+        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
         mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice,
                 /*isAnisotropyCorrectionEnabled=*/ true,
                 /*isAlwaysRotateDisplayDeviceEnabled=*/ true);
@@ -172,6 +203,7 @@
 
     @Test
     public void testLetterbox_anisotropyCorrectionYDpi() {
+        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
         mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice,
                 /*isAnisotropyCorrectionEnabled=*/ true,
                 /*isAlwaysRotateDisplayDeviceEnabled=*/ true);
@@ -229,6 +261,7 @@
 
     @Test
     public void testPillarbox_anisotropyCorrection() {
+        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
         mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice,
                 /*isAnisotropyCorrectionEnabled=*/ true,
                 /*isAlwaysRotateDisplayDeviceEnabled=*/ true);
@@ -257,6 +290,7 @@
 
     @Test
     public void testNoPillarbox_anisotropyCorrectionYDpi() {
+        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
         mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice,
                 /*isAnisotropyCorrectionEnabled=*/ true,
                 /*isAlwaysRotateDisplayDeviceEnabled=*/ true);
@@ -318,6 +352,7 @@
 
     @Test
     public void testGetDisplayPositionAlwaysRotateDisplayEnabled() {
+        mDisplayDeviceInfo.type = Display.TYPE_EXTERNAL;
         mLogicalDisplay = new LogicalDisplay(DISPLAY_ID, LAYER_STACK, mDisplayDevice,
                 /*isAnisotropyCorrectionEnabled=*/ true,
                 /*isAlwaysRotateDisplayDeviceEnabled=*/ true);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/NormalBrightnessModeControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/NormalBrightnessModeControllerTest.java
index c379d6b..3fd3cef 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/NormalBrightnessModeControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/NormalBrightnessModeControllerTest.java
@@ -43,6 +43,11 @@
 
     private final NormalBrightnessModeController mController = new NormalBrightnessModeController();
 
+    // AutoBrightnessController sends ambientLux values *only* when auto brightness enabled.
+    // NormalBrightnessModeController is temporary disabled  if auto brightness is off,
+    // to avoid capping brightness based on stale ambient lux. Temporary disabling tests with
+    // auto brightness off and default config pres
+    // The issue is tracked here: b/322445088
     @Keep
     private static Object[][] brightnessData() {
         return new Object[][]{
@@ -59,10 +64,10 @@
                         ImmutableMap.of(99f, 0.1f, 101f, 0.2f)
                 ), 0.2f},
                 // Auto brightness - off, config only for default
-                {100, AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED, ImmutableMap.of(
-                        BrightnessLimitMapType.DEFAULT,
-                        ImmutableMap.of(99f, 0.1f, 101f, 0.2f)
-                ), 0.2f},
+                // {100, AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED, ImmutableMap.of(
+                //        BrightnessLimitMapType.DEFAULT,
+                //        ImmutableMap.of(99f, 0.1f, 101f, 0.2f)
+                // ), 0.2f},
                 // Auto brightness - off, config only for adaptive
                 {100, AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED, ImmutableMap.of(
                         BrightnessLimitMapType.ADAPTIVE,
@@ -81,12 +86,12 @@
                         ImmutableMap.of(99f, 0.3f, 101f, 0.4f)
                 ), 0.4f},
                 // Auto brightness - off, config for both
-                {100, AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED, ImmutableMap.of(
-                        BrightnessLimitMapType.DEFAULT,
-                        ImmutableMap.of(99f, 0.1f, 101f, 0.2f),
-                        BrightnessLimitMapType.ADAPTIVE,
-                        ImmutableMap.of(99f, 0.3f, 101f, 0.4f)
-                ), 0.2f},
+                // {100, AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED, ImmutableMap.of(
+                //        BrightnessLimitMapType.DEFAULT,
+                //        ImmutableMap.of(99f, 0.1f, 101f, 0.2f),
+                //        BrightnessLimitMapType.ADAPTIVE,
+                //        ImmutableMap.of(99f, 0.3f, 101f, 0.4f)
+                // ), 0.2f},
                 // Auto brightness - on, config for both, ambient high
                 {1000, AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED, ImmutableMap.of(
                         BrightnessLimitMapType.DEFAULT,
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
index 87fc7a4..39ffe5b 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
@@ -33,6 +33,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.server.display.AutomaticBrightnessController;
 import com.android.server.display.config.HdrBrightnessData;
 import com.android.server.testutils.OffsettableClock;
 import com.android.server.testutils.TestHandler;
@@ -230,6 +231,11 @@
     }
 
     private void configureClamper() {
+        // AutoBrightnessController sends ambientLux values *only* when auto brightness enabled.
+        // HdrClamper is temporary disabled  if auto brightness is off.
+        // Temporary setting AutoBrightnessState to enabled for this test
+        // The issue is tracked here: b/322445088
+        mHdrClamper.setAutoBrightnessState(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED);
         mHdrClamper.resetHdrConfig(TEST_HDR_DATA, WIDTH, HEIGHT, MIN_HDR_PERCENT, mMockBinder);
         mHdrChangeListener.onHdrVisible(true);
     }
diff --git a/services/tests/media/mediarouterservicetest/src/com/android/server/media/AudioManagerRouteControllerTest.java b/services/tests/media/mediarouterservicetest/src/com/android/server/media/AudioManagerRouteControllerTest.java
index a918be2..8bdfc50 100644
--- a/services/tests/media/mediarouterservicetest/src/com/android/server/media/AudioManagerRouteControllerTest.java
+++ b/services/tests/media/mediarouterservicetest/src/com/android/server/media/AudioManagerRouteControllerTest.java
@@ -69,6 +69,13 @@
 public class AudioManagerRouteControllerTest {
 
     private static final String FAKE_ROUTE_NAME = "fake name";
+
+    /**
+     * The number of milliseconds to wait for an asynchronous operation before failing an associated
+     * assertion.
+     */
+    private static final int ASYNC_CALL_TIMEOUTS_MS = 1000;
+
     private static final AudioDeviceInfo FAKE_AUDIO_DEVICE_INFO_BUILTIN_SPEAKER =
             createAudioDeviceInfo(
                     AudioSystem.DEVICE_OUT_SPEAKER, "name_builtin", /* address= */ null);
@@ -231,7 +238,7 @@
         MediaRoute2Info builtInSpeakerRoute =
                 getAvailableRouteWithType(MediaRoute2Info.TYPE_BUILTIN_SPEAKER);
         mControllerUnderTest.transferTo(builtInSpeakerRoute.getId());
-        verify(mMockAudioManager)
+        verify(mMockAudioManager, Mockito.timeout(ASYNC_CALL_TIMEOUTS_MS))
                 .setPreferredDeviceForStrategy(
                         mMediaAudioProductStrategy,
                         createAudioDeviceAttribute(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER));
@@ -239,7 +246,7 @@
         MediaRoute2Info wiredHeadsetRoute =
                 getAvailableRouteWithType(MediaRoute2Info.TYPE_WIRED_HEADSET);
         mControllerUnderTest.transferTo(wiredHeadsetRoute.getId());
-        verify(mMockAudioManager)
+        verify(mMockAudioManager, Mockito.timeout(ASYNC_CALL_TIMEOUTS_MS))
                 .setPreferredDeviceForStrategy(
                         mMediaAudioProductStrategy,
                         createAudioDeviceAttribute(AudioDeviceInfo.TYPE_WIRED_HEADSET));
diff --git a/services/tests/mockingservicestests/src/com/android/server/OWNERS b/services/tests/mockingservicestests/src/com/android/server/OWNERS
index f801560..0eb8639 100644
--- a/services/tests/mockingservicestests/src/com/android/server/OWNERS
+++ b/services/tests/mockingservicestests/src/com/android/server/OWNERS
@@ -1,5 +1,5 @@
 per-file *Alarm* = file:/apex/jobscheduler/OWNERS
 per-file *AppStateTracker* = file:/apex/jobscheduler/OWNERS
 per-file *DeviceIdleController* = file:/apex/jobscheduler/OWNERS
-per-file SensitiveContentProtectionManagerServiceTest.java = file:/core/java/android/permission/OWNERS
+per-file SensitiveContentProtectionManagerService* = file:/core/java/android/permission/OWNERS
 per-file RescuePartyTest.java = file:/packages/CrashRecovery/OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index 682569f..697548c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -1111,16 +1111,9 @@
 
         // mock properties in BootThreshold
         try {
-            if (Flags.recoverabilityDetection()) {
-                mSpyBootThreshold = spy(watchdog.new BootThreshold(
-                    PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT,
-                    PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS,
-                    PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT));
-            } else {
-                mSpyBootThreshold = spy(watchdog.new BootThreshold(
+            mSpyBootThreshold = spy(watchdog.new BootThreshold(
                     PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT,
                     PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS));
-            }
             mCrashRecoveryPropertiesMap = new HashMap<>();
 
             doAnswer((Answer<Integer>) invocationOnMock -> {
diff --git a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java
index 5065144..edee8cd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java
@@ -25,7 +25,6 @@
 import static org.mockito.Mockito.doCallRealMethod;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
@@ -34,6 +33,7 @@
 import android.content.pm.PackageManagerInternal;
 import android.media.projection.MediaProjectionInfo;
 import android.media.projection.MediaProjectionManager;
+import android.os.Process;
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
@@ -79,7 +79,8 @@
     private static final String NOTIFICATION_PKG_1 = "com.android.server.notification.one";
     private static final String NOTIFICATION_PKG_2 = "com.android.server.notification.two";
 
-    private static final String EXEMPTED_SCREEN_RECORDER_PACKAGE = "test.screen.recorder.package";
+    private static final String SCREEN_RECORDER_PACKAGE = "test.screen.recorder.package";
+    private static final String EXEMPTED_SCREEN_RECORDER_PACKAGE = "exempt.screen.recorder.package";
 
     private static final int NOTIFICATION_UID_1 = 5;
     private static final int NOTIFICATION_UID_2 = 6;
@@ -281,10 +282,18 @@
                 .getActiveNotifications();
     }
 
+    private MediaProjectionInfo createMediaProjectionInfo() {
+        return new MediaProjectionInfo(SCREEN_RECORDER_PACKAGE, Process.myUserHandle(), null);
+    }
+
+    private MediaProjectionInfo createExemptMediaProjectionInfo() {
+        return new MediaProjectionInfo(
+                EXEMPTED_SCREEN_RECORDER_PACKAGE, Process.myUserHandle(), null);
+    }
+
     @Test
     public void mediaProjectionOnStart_verifyExemptedRecorderPackage() {
-        MediaProjectionInfo mediaProjectionInfo = mock(MediaProjectionInfo.class);
-        when(mediaProjectionInfo.getPackageName()).thenReturn(EXEMPTED_SCREEN_RECORDER_PACKAGE);
+        MediaProjectionInfo mediaProjectionInfo = createExemptMediaProjectionInfo();
 
         mMediaProjectionCallbackCaptor.getValue().onStart(mediaProjectionInfo);
 
@@ -295,7 +304,7 @@
     public void mediaProjectionOnStart_onProjectionStart_setWmBlockedPackages() {
         ArraySet<PackageInfo> expectedBlockedPackages = setupSensitiveNotification();
 
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
 
         verify(mWindowManager).addBlockScreenCaptureForApps(expectedBlockedPackages);
     }
@@ -304,18 +313,18 @@
     public void mediaProjectionOnStart_noSensitiveNotifications_noBlockedPackages() {
         setupNoSensitiveNotifications();
 
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
     public void mediaProjectionOnStart_noNotifications_noBlockedPackages() {
         setupNoNotifications();
 
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
@@ -323,7 +332,7 @@
         ArraySet<PackageInfo> expectedBlockedPackages =
                 setupMultipleSensitiveNotificationsFromSamePackageAndUid();
 
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
 
         verify(mWindowManager).addBlockScreenCaptureForApps(expectedBlockedPackages);
     }
@@ -333,7 +342,7 @@
         ArraySet<PackageInfo> expectedBlockedPackages =
                 setupMultipleSensitiveNotificationsFromDifferentPackage();
 
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
 
         verify(mWindowManager).addBlockScreenCaptureForApps(expectedBlockedPackages);
     }
@@ -343,7 +352,7 @@
         ArraySet<PackageInfo> expectedBlockedPackages =
                 setupMultipleSensitiveNotificationsFromDifferentUid();
 
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
 
         verify(mWindowManager).addBlockScreenCaptureForApps(expectedBlockedPackages);
     }
@@ -352,7 +361,7 @@
     public void mediaProjectionOnStop_onProjectionEnd_clearWmBlockedPackages() {
         setupSensitiveNotification();
 
-        MediaProjectionInfo mediaProjectionInfo = mock(MediaProjectionInfo.class);
+        MediaProjectionInfo mediaProjectionInfo = createMediaProjectionInfo();
         mMediaProjectionCallbackCaptor.getValue().onStart(mediaProjectionInfo);
         Mockito.reset(mWindowManager);
 
@@ -365,7 +374,7 @@
     public void mediaProjectionOnStart_afterOnStop_onProjectionStart_setWmBlockedPackages() {
         ArraySet<PackageInfo> expectedBlockedPackages = setupSensitiveNotification();
 
-        MediaProjectionInfo mediaProjectionInfo = mock(MediaProjectionInfo.class);
+        MediaProjectionInfo mediaProjectionInfo = createMediaProjectionInfo();
         mMediaProjectionCallbackCaptor.getValue().onStart(mediaProjectionInfo);
         mMediaProjectionCallbackCaptor.getValue().onStop(mediaProjectionInfo);
         Mockito.reset(mWindowManager);
@@ -381,9 +390,9 @@
                 .when(mSensitiveContentProtectionManagerService.mNotificationListener)
                 .getActiveNotifications();
 
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
@@ -392,9 +401,9 @@
                 .when(mSensitiveContentProtectionManagerService.mNotificationListener)
                 .getCurrentRanking();
 
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
@@ -403,9 +412,9 @@
                 .when(mSensitiveContentProtectionManagerService.mNotificationListener)
                 .getCurrentRanking();
 
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
@@ -416,9 +425,9 @@
                 .when(mSensitiveContentProtectionManagerService.mNotificationListener)
                 .getCurrentRanking();
 
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
@@ -426,7 +435,7 @@
         mockDisabledViaDevelopOption();
         setupSensitiveNotification();
 
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
 
         verifyZeroInteractions(mWindowManager);
     }
@@ -447,8 +456,9 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
-        mMediaProjectionCallbackCaptor.getValue().onStop(mock(MediaProjectionInfo.class));
+        MediaProjectionInfo mediaProjectionInfo = createMediaProjectionInfo();
+        mMediaProjectionCallbackCaptor.getValue().onStart(mediaProjectionInfo);
+        mMediaProjectionCallbackCaptor.getValue().onStop(mediaProjectionInfo);
         Mockito.reset(mWindowManager);
 
         mSensitiveContentProtectionManagerService.mNotificationListener.onListenerConnected();
@@ -461,7 +471,7 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         ArraySet<PackageInfo> expectedBlockedPackages = setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
 
         mSensitiveContentProtectionManagerService.mNotificationListener.onListenerConnected();
@@ -472,23 +482,23 @@
     @Test
     public void nlsOnListenerConnected_noSensitiveNotifications_noBlockedPackages() {
         setupNoSensitiveNotifications();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
 
         mSensitiveContentProtectionManagerService.mNotificationListener.onListenerConnected();
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
     public void nlsOnListenerConnected_noNotifications_noBlockedPackages() {
         setupNoNotifications();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
 
         mSensitiveContentProtectionManagerService.mNotificationListener.onListenerConnected();
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
@@ -496,7 +506,7 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
         doReturn(null)
                 .when(mSensitiveContentProtectionManagerService.mNotificationListener)
@@ -504,7 +514,7 @@
 
         mSensitiveContentProtectionManagerService.mNotificationListener.onListenerConnected();
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
@@ -512,7 +522,7 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
         when(mRankingMap.getRawRankingObject(eq(NOTIFICATION_KEY_1))).thenReturn(null);
         doReturn(mRankingMap)
@@ -521,7 +531,7 @@
 
         mSensitiveContentProtectionManagerService.mNotificationListener.onListenerConnected();
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
@@ -530,7 +540,7 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         mSensitiveContentProtectionManagerService.mNotificationListener.onListenerConnected();
 
         verifyZeroInteractions(mWindowManager);
@@ -553,8 +563,9 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
-        mMediaProjectionCallbackCaptor.getValue().onStop(mock(MediaProjectionInfo.class));
+        MediaProjectionInfo mediaProjectionInfo = createMediaProjectionInfo();
+        mMediaProjectionCallbackCaptor.getValue().onStart(mediaProjectionInfo);
+        mMediaProjectionCallbackCaptor.getValue().onStop(mediaProjectionInfo);
         Mockito.reset(mWindowManager);
 
         mSensitiveContentProtectionManagerService.mNotificationListener
@@ -568,7 +579,7 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         ArraySet<PackageInfo> expectedBlockedPackages = setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
 
         mSensitiveContentProtectionManagerService.mNotificationListener
@@ -580,25 +591,25 @@
     @Test
     public void nlsOnNotificationRankingUpdate_noSensitiveNotifications_noBlockedPackages() {
         setupNoSensitiveNotifications();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
 
         mSensitiveContentProtectionManagerService.mNotificationListener
                 .onNotificationRankingUpdate(mRankingMap);
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
     public void nlsOnNotificationRankingUpdate_noNotifications_noBlockedPackages() {
         setupNoNotifications();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
 
         mSensitiveContentProtectionManagerService.mNotificationListener
                 .onNotificationRankingUpdate(mRankingMap);
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
@@ -606,13 +617,13 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
 
         mSensitiveContentProtectionManagerService.mNotificationListener
                 .onNotificationRankingUpdate(null);
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
@@ -620,7 +631,7 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
         when(mRankingMap.getRawRankingObject(eq(NOTIFICATION_KEY_1))).thenReturn(null);
         doReturn(mRankingMap)
@@ -630,7 +641,7 @@
         mSensitiveContentProtectionManagerService.mNotificationListener
                 .onNotificationRankingUpdate(mRankingMap);
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
@@ -638,7 +649,7 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
 
         doThrow(SecurityException.class)
@@ -648,7 +659,7 @@
         mSensitiveContentProtectionManagerService.mNotificationListener
                 .onNotificationRankingUpdate(mRankingMap);
 
-        verify(mWindowManager).addBlockScreenCaptureForApps(EMPTY_SET);
+        verifyZeroInteractions(mWindowManager);
     }
 
     @Test
@@ -657,7 +668,7 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         mSensitiveContentProtectionManagerService.mNotificationListener
                 .onNotificationRankingUpdate(mRankingMap);
 
@@ -681,8 +692,9 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
-        mMediaProjectionCallbackCaptor.getValue().onStop(mock(MediaProjectionInfo.class));
+        MediaProjectionInfo mediaProjectionInfo = createMediaProjectionInfo();
+        mMediaProjectionCallbackCaptor.getValue().onStart(mediaProjectionInfo);
+        mMediaProjectionCallbackCaptor.getValue().onStop(mediaProjectionInfo);
         Mockito.reset(mWindowManager);
 
         mSensitiveContentProtectionManagerService.mNotificationListener
@@ -696,7 +708,7 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
 
         mSensitiveContentProtectionManagerService.mNotificationListener
@@ -712,7 +724,7 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
 
         mSensitiveContentProtectionManagerService.mNotificationListener
@@ -726,7 +738,7 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
 
         mSensitiveContentProtectionManagerService.mNotificationListener
@@ -740,7 +752,7 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
 
         mSensitiveContentProtectionManagerService.mNotificationListener
@@ -754,7 +766,7 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         Mockito.reset(mWindowManager);
         when(mRankingMap.getRawRankingObject(eq(NOTIFICATION_KEY_1))).thenReturn(null);
 
@@ -770,7 +782,7 @@
         // Sets up mNotification1 & mRankingMap to be a sensitive notification, and mNotification2
         // as non-sensitive
         setupSensitiveNotification();
-        mMediaProjectionCallbackCaptor.getValue().onStart(mock(MediaProjectionInfo.class));
+        mMediaProjectionCallbackCaptor.getValue().onStart(createMediaProjectionInfo());
         mSensitiveContentProtectionManagerService.mNotificationListener
                 .onNotificationPosted(mNotification1, mRankingMap);
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index ce5cee0..c359412 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -69,7 +69,6 @@
 import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_EXACT_ALARMS;
 import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED;
 import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_FOR_CANCELED;
-import static com.android.server.alarm.AlarmManagerService.AlarmHandler.TARE_AFFORDABILITY_CHANGED;
 import static com.android.server.alarm.AlarmManagerService.AlarmHandler.TEMPORARY_QUOTA_CHANGED;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA;
 import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW;
@@ -126,7 +125,6 @@
 import android.app.IAlarmManager;
 import android.app.PendingIntent;
 import android.app.compat.CompatChanges;
-import android.app.tare.EconomyManager;
 import android.app.usage.UsageStatsManagerInternal;
 import android.companion.virtual.VirtualDeviceManager;
 import android.content.ContentResolver;
@@ -181,8 +179,6 @@
 import com.android.server.pm.permission.PermissionManagerService;
 import com.android.server.pm.permission.PermissionManagerServiceInternal;
 import com.android.server.pm.pkg.AndroidPackage;
-import com.android.server.tare.AlarmManagerEconomicPolicy;
-import com.android.server.tare.EconomyManagerInternal;
 import com.android.server.usage.AppStandbyInternal;
 
 import libcore.util.EmptyArray;
@@ -264,8 +260,6 @@
     @Mock
     private PowerManager.WakeLock mWakeLock;
     @Mock
-    private EconomyManagerInternal mEconomyManagerInternal;
-    @Mock
     DeviceConfig.Properties mDeviceConfigProperties;
     HashSet<String> mDeviceConfigKeys = new HashSet<>();
 
@@ -449,8 +443,6 @@
         doReturn(mIActivityManager).when(ActivityManager::getService);
         doReturn(mDeviceIdleInternal).when(
                 () -> LocalServices.getService(DeviceIdleInternal.class));
-        doReturn(mEconomyManagerInternal).when(
-                () -> LocalServices.getService(EconomyManagerInternal.class));
         doReturn(mPermissionManagerInternal).when(
                 () -> LocalServices.getService(PermissionManagerServiceInternal.class));
         doReturn(mActivityManagerInternal).when(
@@ -544,7 +536,6 @@
         mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
 
         verify(mBatteryManager).isCharging();
-        setTareEnabled(EconomyManager.ENABLED_MODE_OFF);
         mAppStandbyWindow = mService.mConstants.APP_STANDBY_WINDOW;
         mAllowWhileIdleWindow = mService.mConstants.ALLOW_WHILE_IDLE_WINDOW;
 
@@ -720,12 +711,6 @@
         mService.mConstants.onPropertiesChanged(mDeviceConfigProperties);
     }
 
-    private void setTareEnabled(int enabledMode) {
-        when(mEconomyManagerInternal.getEnabledMode(eq(AlarmManagerEconomicPolicy.POLICY_ALARM)))
-                .thenReturn(enabledMode);
-        mService.mConstants.onTareEnabledModeChanged(enabledMode);
-    }
-
     /**
      * Lowers quotas to make testing feasible. Careful while calling as this will replace any
      * existing settings for the calling test.
@@ -2101,44 +2086,6 @@
     }
 
     @Test
-    public void tareThrottling() {
-        setTareEnabled(EconomyManager.ENABLED_MODE_ON);
-        final ArgumentCaptor<EconomyManagerInternal.AffordabilityChangeListener> listenerCaptor =
-                ArgumentCaptor.forClass(EconomyManagerInternal.AffordabilityChangeListener.class);
-        final ArgumentCaptor<EconomyManagerInternal.ActionBill> billCaptor =
-                ArgumentCaptor.forClass(EconomyManagerInternal.ActionBill.class);
-
-        when(mEconomyManagerInternal
-                .canPayFor(eq(TEST_CALLING_USER), eq(TEST_CALLING_PACKAGE), billCaptor.capture()))
-                .thenReturn(false);
-
-        final PendingIntent alarmPi = getNewMockPendingIntent();
-        setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 15, alarmPi);
-        assertEquals(mNowElapsedTest + INDEFINITE_DELAY, mTestTimer.getElapsed());
-
-        final EconomyManagerInternal.ActionBill bill = billCaptor.getValue();
-        verify(mEconomyManagerInternal).registerAffordabilityChangeListener(
-                eq(TEST_CALLING_USER), eq(TEST_CALLING_PACKAGE),
-                listenerCaptor.capture(), eq(bill));
-        final EconomyManagerInternal.AffordabilityChangeListener listener =
-                listenerCaptor.getValue();
-
-        when(mEconomyManagerInternal
-                .canPayFor(eq(TEST_CALLING_USER), eq(TEST_CALLING_PACKAGE), eq(bill)))
-                .thenReturn(true);
-        listener.onAffordabilityChanged(TEST_CALLING_USER, TEST_CALLING_PACKAGE, bill, true);
-        assertAndHandleMessageSync(TARE_AFFORDABILITY_CHANGED);
-        assertEquals(mNowElapsedTest + 15, mTestTimer.getElapsed());
-
-        when(mEconomyManagerInternal
-                .canPayFor(eq(TEST_CALLING_USER), eq(TEST_CALLING_PACKAGE), eq(bill)))
-                .thenReturn(false);
-        listener.onAffordabilityChanged(TEST_CALLING_USER, TEST_CALLING_PACKAGE, bill, false);
-        assertAndHandleMessageSync(TARE_AFFORDABILITY_CHANGED);
-        assertEquals(mNowElapsedTest + INDEFINITE_DELAY, mTestTimer.getElapsed());
-    }
-
-    @Test
     public void dispatchOrder() throws Exception {
         setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 0);
 
@@ -3414,32 +3361,6 @@
     }
 
     @Test
-    public void tareEventPushed_on() throws Exception {
-        setTareEnabled(EconomyManager.ENABLED_MODE_ON);
-        runTareEventPushed();
-    }
-
-    @Test
-    public void tareEventPushed_shadow() throws Exception {
-        setTareEnabled(EconomyManager.ENABLED_MODE_SHADOW);
-        runTareEventPushed();
-    }
-
-    private void runTareEventPushed() throws Exception {
-        for (int i = 0; i < 10; i++) {
-            final int type = (i % 2 == 1) ? ELAPSED_REALTIME : ELAPSED_REALTIME_WAKEUP;
-            setTestAlarm(type, mNowElapsedTest + i, getNewMockPendingIntent());
-        }
-
-        final ArrayList<Alarm> alarms = mService.mAlarmStore.remove((alarm) -> {
-            return alarm.creatorUid == TEST_CALLING_UID;
-        });
-        mService.deliverAlarmsLocked(alarms, mNowElapsedTest);
-        verify(mEconomyManagerInternal, times(10)).noteInstantaneousEvent(
-                eq(TEST_CALLING_USER), eq(TEST_CALLING_PACKAGE), anyInt(), any());
-    }
-
-    @Test
     public void setTimeZoneImpl() {
         final long durationMs = 20000L;
         when(mActivityManagerInternal.getBootTimeTempAllowListDuration()).thenReturn(durationMs);
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java
index 246b0f04..d802b96 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmTest.java
@@ -28,7 +28,6 @@
 import static com.android.server.alarm.Alarm.NUM_POLICIES;
 import static com.android.server.alarm.Alarm.REQUESTER_POLICY_INDEX;
 import static com.android.server.alarm.AlarmManagerService.isExemptFromAppStandby;
-import static com.android.server.alarm.AlarmManagerService.isExemptFromTare;
 import static com.android.server.alarm.Constants.TEST_CALLING_PACKAGE;
 import static com.android.server.alarm.Constants.TEST_CALLING_UID;
 
@@ -196,22 +195,6 @@
     }
 
     @Test
-    public void testIsExemptFromTare() {
-        final long anything = 54321;    // Arbitrary number, doesn't matter for this test.
-
-        assertFalse("Basic alarm exempt", isExemptFromTare(
-                createDefaultAlarm(anything, anything, 0)));
-        assertFalse("FLAG_ALLOW_WHILE_IDLE_COMPAT exempt", isExemptFromTare(
-                createDefaultAlarm(anything, anything, FLAG_ALLOW_WHILE_IDLE_COMPAT)));
-        assertFalse("ALLOW_WHILE_IDLE exempt", isExemptFromTare(
-                createDefaultAlarm(anything, anything, FLAG_ALLOW_WHILE_IDLE)));
-
-        assertTrue("ALLOW_WHILE_IDLE_UNRESTRICTED not exempt", isExemptFromTare(
-                createDefaultAlarm(anything, anything, FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED)));
-        assertTrue("Alarm clock not exempt", isExemptFromTare(createAlarmClock(anything)));
-    }
-
-    @Test
     public void snapshotImmutable() {
         final Alarm a = createDefaultAlarm(0, 0, 0);
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
index 067dd3b..637c73f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
@@ -126,6 +126,7 @@
 import android.os.BatteryStatsInternal;
 import android.os.BatteryUsageStats;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.MessageQueue;
 import android.os.Process;
 import android.os.RemoteException;
@@ -321,6 +322,7 @@
     private BindServiceEventListener mBindServiceEventListener;
 
     private Context mContext = getInstrumentation().getTargetContext();
+    private Handler mDefaultHandler = new Handler(Looper.getMainLooper());
     private TestBgRestrictionInjector mInjector;
     private AppRestrictionController mBgRestrictionController;
     private AppBatteryTracker mAppBatteryTracker;
@@ -346,10 +348,6 @@
         mActivityManagerService.mConstants = mActivityManagerConstants;
         mPhoneCarrierPrivileges = new PhoneCarrierPrivileges(
                 mInjector.getTelephonyManager(), MOCK_PRIVILEGED_PACKAGES.length);
-        for (int i = 0; i < MOCK_PRIVILEGED_PACKAGES.length; i++) {
-            mPhoneCarrierPrivileges.addNewPrivilegePackages(i,
-                    MOCK_PRIVILEGED_PACKAGES[i], MOCK_PRIVILEGED_UIDS[i]);
-        }
 
         doReturn(PROCESS_STATE_FOREGROUND_SERVICE).when(mActivityManagerInternal)
                 .getUidProcessState(anyInt());
@@ -3048,6 +3046,11 @@
 
     @Test
     public void testCarrierPrivilegedAppListener() throws Exception {
+        for (int i = 0; i < MOCK_PRIVILEGED_PACKAGES.length; i++) {
+            mPhoneCarrierPrivileges.addNewPrivilegePackages(i,
+                    MOCK_PRIVILEGED_PACKAGES[i], MOCK_PRIVILEGED_UIDS[i]);
+        }
+
         final long shortMs = 1_000L;
         for (int i = 0; i < MOCK_PRIVILEGED_PACKAGES.length; i++) {
             verifyPotentialSystemExemptionReason(REASON_CARRIER_PRIVILEGED_APP,
@@ -3356,6 +3359,11 @@
         }
 
         @Override
+        Handler getDefaultHandler() {
+            return mDefaultHandler;
+        }
+
+        @Override
         boolean isTest() {
             return true;
         }
@@ -3445,6 +3453,16 @@
         IAppOpsService getIAppOpsService() {
             return BackgroundRestrictionTest.this.mIAppOpsService;
         }
+
+        @Override
+        int checkPermission(String perm, int pid, int uid) {
+            try {
+                return BackgroundRestrictionTest.this.mIActivityManager.checkPermission(
+                        perm, pid, uid);
+            } catch (RemoteException e) {
+                return PERMISSION_DENIED;
+            }
+        }
     }
 
     private class TestAppBatteryTrackerInjector extends TestBaseTrackerInjector<AppBatteryPolicy> {
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
index 1b2c0e4..97ae0bd 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
@@ -940,8 +940,7 @@
 
         final ProcessRecord receiverGreenApp = mAms.getProcessRecordLocked(PACKAGE_GREEN,
                 getUidForPackage(PACKAGE_GREEN));
-        // Modern queue always kills the target process when broadcast delivery fails, where as
-        // the legacy queue leaves the process killing task to AMS
+        // Broadcast queue always kills the target process when broadcast delivery fails.
         assertNull(receiverGreenApp);
         final ProcessRecord receiverBlueApp = mAms.getProcessRecordLocked(PACKAGE_BLUE,
                 getUidForPackage(PACKAGE_BLUE));
@@ -1054,8 +1053,6 @@
         }
 
         waitForIdle();
-        // Legacy stack does not remove registered receivers as part of
-        // cleanUpDisabledPackageReceiversLocked() call, so verify this only on modern queue.
         verifyScheduleReceiver(never(), callerApp, USER_GUEST);
         verifyScheduleRegisteredReceiver(never(), callerApp, USER_GUEST);
         for (String pkg : new String[] {
@@ -1166,8 +1163,7 @@
         final ProcessRecord receiverOrangeApp = mAms.getProcessRecordLocked(PACKAGE_ORANGE,
                 getUidForPackage(PACKAGE_ORANGE));
 
-        // Modern queue always kills the target process when broadcast delivery fails, where as
-        // the legacy queue leaves the process killing task to AMS
+        // Broadcast queue always kills the target process when broadcast delivery fails.
         assertNull(receiverGreenApp);
         verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, airplane);
         verifyScheduleReceiver(times(1), receiverYellowApp, airplane);
@@ -1210,8 +1206,6 @@
         final ProcessRecord restartedReceiverBlueApp = mAms.getProcessRecordLocked(PACKAGE_BLUE,
                 getUidForPackage(PACKAGE_BLUE));
         assertNotEquals(receiverBlueApp, restartedReceiverBlueApp);
-        // Legacy queue will always try delivering the broadcast even if the process
-        // has been killed.
         verifyScheduleReceiver(never(), receiverBlueApp, airplane);
         // Verify that the new process receives the broadcast.
         verifyScheduleReceiver(times(1), restartedReceiverBlueApp, airplane);
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
index fab7610..11f20e3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
@@ -85,7 +85,6 @@
 import com.android.server.job.controllers.ConnectivityController;
 import com.android.server.job.controllers.JobStatus;
 import com.android.server.job.controllers.QuotaController;
-import com.android.server.job.controllers.TareController;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.usage.AppStandbyInternal;
 
@@ -617,12 +616,8 @@
 
         QuotaController quotaController = mService.getQuotaController();
         spyOn(quotaController);
-        TareController tareController = mService.getTareController();
-        spyOn(tareController);
         doReturn(mService.mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS)
                 .when(quotaController).getMaxJobExecutionTimeMsLocked(any());
-        doReturn(mService.mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS)
-                .when(tareController).getMaxJobExecutionTimeMsLocked(any());
 
         grantRunUserInitiatedJobsPermission(true);
         assertEquals(mService.mConstants.RUNTIME_UI_LIMIT_MS,
@@ -655,12 +650,8 @@
 
         QuotaController quotaController = mService.getQuotaController();
         spyOn(quotaController);
-        TareController tareController = mService.getTareController();
-        spyOn(tareController);
         doReturn(mService.mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS)
                 .when(quotaController).getMaxJobExecutionTimeMsLocked(any());
-        doReturn(mService.mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS)
-                .when(tareController).getMaxJobExecutionTimeMsLocked(any());
 
         mService.mConstants.ENABLE_EXECUTION_SAFEGUARDS_UDC = false;
         mService.mConstants.EXECUTION_SAFEGUARDS_UDC_TIMEOUT_UIJ_COUNT = 2;
@@ -784,12 +775,8 @@
 
         QuotaController quotaController = mService.getQuotaController();
         spyOn(quotaController);
-        TareController tareController = mService.getTareController();
-        spyOn(tareController);
         doReturn(mService.mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS)
                 .when(quotaController).getMaxJobExecutionTimeMsLocked(any());
-        doReturn(mService.mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS)
-                .when(tareController).getMaxJobExecutionTimeMsLocked(any());
 
         mService.mConstants.ENABLE_EXECUTION_SAFEGUARDS_UDC = true;
         mService.mConstants.EXECUTION_SAFEGUARDS_UDC_TIMEOUT_UIJ_COUNT = 2;
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
index c6608e6..2d0f4b6 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
@@ -1345,13 +1345,11 @@
     private void markExpeditedQuotaApproved(JobStatus job, boolean isApproved) {
         if (job.isRequestedExpeditedJob()) {
             job.setExpeditedJobQuotaApproved(sElapsedRealtimeClock.millis(), isApproved);
-            job.setExpeditedJobTareApproved(sElapsedRealtimeClock.millis(), isApproved);
         }
     }
 
     private void markImplicitConstraintsSatisfied(JobStatus job, boolean isSatisfied) {
         job.setQuotaConstraintSatisfied(sElapsedRealtimeClock.millis(), isSatisfied);
-        job.setTareWealthConstraintSatisfied(sElapsedRealtimeClock.millis(), isSatisfied);
         job.setDeviceNotDozingConstraintSatisfied(
                 sElapsedRealtimeClock.millis(), isSatisfied, false);
         job.setBackgroundNotRestrictedConstraintSatisfied(
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/PrefetchControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/PrefetchControllerTest.java
index 1a95d66..da5cbab3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/PrefetchControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/PrefetchControllerTest.java
@@ -200,9 +200,7 @@
         js.setBackgroundNotRestrictedConstraintSatisfied(
                 sElapsedRealtimeClock.millis(), true, false);
         js.setQuotaConstraintSatisfied(sElapsedRealtimeClock.millis(), true);
-        js.setTareWealthConstraintSatisfied(sElapsedRealtimeClock.millis(), true);
         js.setExpeditedJobQuotaApproved(sElapsedRealtimeClock.millis(), true);
-        js.setExpeditedJobTareApproved(sElapsedRealtimeClock.millis(), true);
         js.setFlexibilityConstraintSatisfied(sElapsedRealtimeClock.millis(), true);
         return js;
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
index 0702764..671472d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
@@ -33,6 +33,7 @@
 import static com.android.server.job.JobSchedulerService.WORKING_INDEX;
 import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
 import static com.android.server.job.JobSchedulerService.sSystemClock;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
@@ -400,8 +401,6 @@
                 /* state */ true, /* allowlisted */false);
         js.setBackgroundNotRestrictedConstraintSatisfied(
                 sElapsedRealtimeClock.millis(), true, false);
-        js.setTareWealthConstraintSatisfied(sElapsedRealtimeClock.millis(), true);
-        js.setExpeditedJobTareApproved(sElapsedRealtimeClock.millis(), true);
         js.setFlexibilityConstraintSatisfied(sElapsedRealtimeClock.millis(), true);
         return js;
     }
@@ -1979,7 +1978,7 @@
     }
 
     @Test
-    public void testIsWithinQuotaLocked_UnderDuration_OverJobCount() {
+    public void testIsWithinQuotaLocked_UnderDuration_OverJobCountRateLimitWindow() {
         setDischarging();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         final int jobCount = mQcConstants.MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW;
@@ -2022,7 +2021,7 @@
     }
 
     @Test
-    public void testIsWithinQuotaLocked_OverDuration_OverJobCount() {
+    public void testIsWithinQuotaLocked_OverDuration_OverJobCountRateLimitWindow() {
         setDischarging();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         final int jobCount = mQcConstants.MAX_JOB_COUNT_PER_RATE_LIMITING_WINDOW;
@@ -2168,6 +2167,73 @@
     }
 
     @Test
+    public void testIsWithinQuotaLocked_UnderDuration_OverJobCountInWindow() {
+        setDischarging();
+
+        JobStatus jobRunning = createJobStatus(
+                "testIsWithinQuotaLocked_UnderDuration_OverJobCountInWindow", 1);
+        JobStatus jobPending = createJobStatus(
+                "testIsWithinQuotaLocked_UnderDuration_OverJobCountInWindow", 2);
+        setStandbyBucket(WORKING_INDEX, jobRunning, jobPending);
+
+        setDeviceConfigInt(QcConstants.KEY_MAX_JOB_COUNT_WORKING, 10);
+
+        long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - (HOUR_IN_MILLIS), 5 * MINUTE_IN_MILLIS, 9), false);
+
+        final ExecutionStats stats;
+        synchronized (mQuotaController.mLock) {
+            stats = mQuotaController.getExecutionStatsLocked(
+                    SOURCE_USER_ID, SOURCE_PACKAGE, WORKING_INDEX);
+            assertTrue(mQuotaController
+                    .isWithinQuotaLocked(SOURCE_USER_ID, SOURCE_PACKAGE, WORKING_INDEX));
+            assertEquals(10, stats.jobCountLimit);
+            assertEquals(9, stats.bgJobCountInWindow);
+        }
+
+        when(mJobSchedulerService.isCurrentlyRunningLocked(jobRunning)).thenReturn(true);
+        when(mJobSchedulerService.isCurrentlyRunningLocked(jobPending)).thenReturn(false);
+
+        InOrder inOrder = inOrder(mJobSchedulerService);
+        trackJobs(jobRunning, jobPending);
+        // UID in the background.
+        setProcessState(ActivityManager.PROCESS_STATE_SERVICE);
+        // Start the job.
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.prepareForExecutionLocked(jobRunning);
+        }
+
+        advanceElapsedClock(MINUTE_IN_MILLIS);
+        // Wait for some extra time to allow for job processing.
+        ArraySet<JobStatus> expected = new ArraySet<>();
+        expected.add(jobPending);
+        inOrder.verify(mJobSchedulerService, timeout(SECOND_IN_MILLIS).times(1))
+                .onControllerStateChanged(eq(expected));
+
+        synchronized (mQuotaController.mLock) {
+            assertTrue(mQuotaController.isWithinQuotaLocked(jobRunning));
+            assertTrue(jobRunning.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+            assertTrue(jobRunning.isReady());
+            assertFalse(mQuotaController.isWithinQuotaLocked(jobPending));
+            assertFalse(jobPending.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
+            assertFalse(jobPending.isReady());
+            assertEquals(10, stats.bgJobCountInWindow);
+        }
+
+        advanceElapsedClock(MINUTE_IN_MILLIS);
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.maybeStopTrackingJobLocked(jobRunning, null);
+        }
+
+        synchronized (mQuotaController.mLock) {
+            assertFalse(mQuotaController
+                    .isWithinQuotaLocked(SOURCE_USER_ID, SOURCE_PACKAGE, WORKING_INDEX));
+            assertEquals(10, stats.bgJobCountInWindow);
+        }
+    }
+
+    @Test
     public void testIsWithinQuotaLocked_TimingSession() {
         setDischarging();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
@@ -4652,7 +4718,7 @@
         // Handler is told to check when the quota will be consumed, not when the initial
         // remaining time is over.
         verify(handler, atLeast(1)).sendMessageDelayed(
-                argThat(msg -> msg.what == QuotaController.MSG_REACHED_QUOTA),
+                argThat(msg -> msg.what == QuotaController.MSG_REACHED_TIME_QUOTA),
                 eq(10 * SECOND_IN_MILLIS));
         verify(handler, never()).sendMessageDelayed(any(), eq(remainingTimeMs));
 
@@ -6619,7 +6685,7 @@
         // Handler is told to check when the quota will be consumed, not when the initial
         // remaining time is over.
         verify(handler, atLeast(1)).sendMessageDelayed(
-                argThat(msg -> msg.what == QuotaController.MSG_REACHED_EJ_QUOTA),
+                argThat(msg -> msg.what == QuotaController.MSG_REACHED_EJ_TIME_QUOTA),
                 eq(10 * SECOND_IN_MILLIS));
         verify(handler, never()).sendMessageDelayed(any(), eq(remainingTimeMs));
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
index 538c0ee..c9aab53 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/MockSystem.kt
@@ -166,7 +166,7 @@
             null
         }
         whenever(mocks.settings.addPackageLPw(nullable(), nullable(), nullable(), nullable(),
-                nullable(), nullable(), nullable())) {
+                nullable(), nullable(), nullable(), nullable())) {
             val name: String = getArgument(0)
             val pendingAdd = mPendingPackageAdds.firstOrNull { it.first == name }
                     ?: return@whenever null
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
index 6aa1825..759a974 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -736,9 +736,10 @@
         Mockito.clearInvocations(mKeyguardManager);
         Mockito.clearInvocations(mSpiedContext);
 
-        // Finally, set the preference to don't auto-lock
+        // Finally, set the preference to auto-lock only after device restart, which is the default
+        // behaviour
         mUms.setOrUpdateAutoLockPreferenceForPrivateProfile(
-                Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_NEVER);
+                Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_AFTER_DEVICE_RESTART);
 
         // Verify that inactivity broadcasts are unregistered and keyguard listener was removed
         Mockito.verify(mSpiedContext).unregisterReceiver(any());
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java
deleted file mode 100644
index a3917765..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/tare/AgentTest.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-import static com.android.server.tare.TareTestUtils.assertLedgersEqual;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-
-import android.app.AlarmManager;
-import android.content.Context;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.server.LocalServices;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
-
-/** Tests various aspects of the Agent. */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class AgentTest {
-    private MockitoSession mMockingSession;
-    @Mock
-    private CompleteEconomicPolicy mEconomicPolicy;
-    @Mock
-    private Analyst mAnalyst;
-    @Mock
-    private Context mContext;
-    @Mock
-    private InternalResourceService mIrs;
-
-    private Agent mAgent;
-    private Scribe mScribe;
-
-    private static class MockScribe extends Scribe {
-        MockScribe(InternalResourceService irs, Analyst analyst) {
-            super(irs, analyst);
-        }
-
-        @Override
-        void postWrite() {
-            // Do nothing
-        }
-    }
-
-    @Before
-    public void setUp() {
-        mMockingSession = mockitoSession()
-                .initMocks(this)
-                .strictness(Strictness.LENIENT)
-                .mockStatic(LocalServices.class)
-                .startMocking();
-        doReturn(mContext).when(mIrs).getContext();
-        doReturn(mEconomicPolicy).when(mIrs).getCompleteEconomicPolicyLocked();
-        doReturn(mIrs).when(mIrs).getLock();
-        doReturn(mock(AlarmManager.class)).when(mContext).getSystemService(Context.ALARM_SERVICE);
-        mScribe = new MockScribe(mIrs, mAnalyst);
-        mAgent = new Agent(mIrs, mScribe, mAnalyst);
-    }
-
-    @After
-    public void tearDown() {
-        mAgent.tearDownLocked();
-
-        if (mMockingSession != null) {
-            mMockingSession.finishMocking();
-        }
-    }
-
-    @Test
-    public void testAppRemoval() {
-        final long consumptionLimit = 1_000_000L;
-        final long remainingCakes = consumptionLimit / 2;
-        mScribe.setConsumptionLimitLocked(consumptionLimit);
-        mScribe.adjustRemainingConsumableCakesLocked(remainingCakes - consumptionLimit);
-        assertEquals(remainingCakes, mScribe.getRemainingConsumableCakesLocked());
-
-        final int userId = 0;
-        final String pkgName = "com.test";
-        final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);
-
-        doReturn(consumptionLimit).when(mIrs).getConsumptionLimitLocked();
-        doReturn(consumptionLimit).when(mEconomicPolicy)
-                .getMaxSatiatedBalance(anyInt(), anyString());
-
-        Ledger.Transaction transaction = new Ledger.Transaction(0, 0, 0, null, 5, 10);
-        mAgent.recordTransactionLocked(userId, pkgName, ledger, transaction, false);
-        assertEquals(5, ledger.getCurrentBalance());
-        assertEquals(remainingCakes - 10, mScribe.getRemainingConsumableCakesLocked());
-
-        mAgent.onPackageRemovedLocked(userId, pkgName);
-        assertEquals(remainingCakes - 10, mScribe.getRemainingConsumableCakesLocked());
-        assertLedgersEqual(new Ledger(), mScribe.getLedgerLocked(userId, pkgName));
-    }
-
-    @Test
-    public void testRecordTransaction_UnderMax() {
-        Ledger ledger = new Ledger();
-
-        doReturn(1_000_000L).when(mIrs).getConsumptionLimitLocked();
-        doReturn(1_000_000L).when(mEconomicPolicy).getMaxSatiatedBalance(anyInt(), anyString());
-
-        Ledger.Transaction transaction = new Ledger.Transaction(0, 0, 0, null, 5, 0);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(5, ledger.getCurrentBalance());
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, 995, 0);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(1000, ledger.getCurrentBalance());
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, -500, 250);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(500, ledger.getCurrentBalance());
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, 999_500L, 500);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(1_000_000L, ledger.getCurrentBalance());
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, -1_000_001L, 1000);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(-1, ledger.getCurrentBalance());
-    }
-
-    @Test
-    public void testRecordTransaction_MaxConsumptionLimit() {
-        Ledger ledger = new Ledger();
-
-        doReturn(1000L).when(mIrs).getConsumptionLimitLocked();
-        doReturn(1_000_000L).when(mEconomicPolicy).getMaxSatiatedBalance(anyInt(), anyString());
-
-        Ledger.Transaction transaction = new Ledger.Transaction(0, 0, 0, null, 5, 0);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(5, ledger.getCurrentBalance());
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, 995, 0);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(1000, ledger.getCurrentBalance());
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, -500, 250);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(500, ledger.getCurrentBalance());
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, 2000, 0);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(2500, ledger.getCurrentBalance());
-
-        // ConsumptionLimit can change as the battery level changes. Ledger balances shouldn't be
-        // affected.
-        doReturn(900L).when(mIrs).getConsumptionLimitLocked();
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, 100, 0);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(2600, ledger.getCurrentBalance());
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, -50, 50);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(2550, ledger.getCurrentBalance());
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, -200, 100);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(2350, ledger.getCurrentBalance());
-
-        doReturn(800L).when(mIrs).getConsumptionLimitLocked();
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, 100, 0);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(2450, ledger.getCurrentBalance());
-    }
-
-    @Test
-    public void testRecordTransaction_MaxSatiatedBalance() {
-        Ledger ledger = new Ledger();
-
-        doReturn(1_000_000L).when(mIrs).getConsumptionLimitLocked();
-        doReturn(1000L).when(mEconomicPolicy).getMaxSatiatedBalance(anyInt(), anyString());
-
-        Ledger.Transaction transaction = new Ledger.Transaction(0, 0, 0, null, 5, 0);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(5, ledger.getCurrentBalance());
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, 995, 0);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(1000, ledger.getCurrentBalance());
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, -500, 250);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(500, ledger.getCurrentBalance());
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, 999_500L, 1000);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(1_000, ledger.getCurrentBalance());
-
-        // Shouldn't change in normal operation, but adding test case in case it does.
-        doReturn(900L).when(mEconomicPolicy).getMaxSatiatedBalance(anyInt(), anyString());
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, 500, 0);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(1_000, ledger.getCurrentBalance());
-
-        transaction = new Ledger.Transaction(0, 0, 0, null, -1001, 500);
-        mAgent.recordTransactionLocked(0, "com.test", ledger, transaction, false);
-        assertEquals(-1, ledger.getCurrentBalance());
-    }
-}
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/AgentTrendCalculatorTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/AgentTrendCalculatorTest.java
deleted file mode 100644
index 799a7fe..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/tare/AgentTrendCalculatorTest.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.util.ArraySet;
-import android.util.SparseLongArray;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.server.tare.Agent.ActionAffordabilityNote;
-import com.android.server.tare.Agent.OngoingEvent;
-import com.android.server.tare.Agent.TrendCalculator;
-import com.android.server.tare.EconomyManagerInternal.ActionBill;
-import com.android.server.tare.EconomyManagerInternal.AffordabilityChangeListener;
-import com.android.server.tare.EconomyManagerInternal.AnticipatedAction;
-
-import libcore.util.EmptyArray;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.List;
-
-/** Tests the TrendCalculator in the Agent. */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class AgentTrendCalculatorTest {
-
-    private MockEconomicPolicy mEconomicPolicy;
-
-    private static class MockEconomicPolicy extends EconomicPolicy {
-        private final SparseLongArray mEventCosts = new SparseLongArray();
-
-        MockEconomicPolicy(InternalResourceService irs) {
-            super(irs);
-        }
-
-        @Override
-        long getMinSatiatedBalance(int userId, String pkgName) {
-            return 0;
-        }
-
-        @Override
-        long getMaxSatiatedBalance(int userId, String pkgName) {
-            return 0;
-        }
-
-        @Override
-        long getInitialSatiatedConsumptionLimit() {
-            return 0;
-        }
-
-        @Override
-        long getMinSatiatedConsumptionLimit() {
-            return 0;
-        }
-
-        @Override
-        long getMaxSatiatedConsumptionLimit() {
-            return 0;
-        }
-
-        @Override
-        int[] getCostModifiers() {
-            return EmptyArray.INT;
-        }
-
-        @Override
-        Action getAction(int actionId) {
-            if (mEventCosts.indexOfKey(actionId) < 0) {
-                return null;
-            }
-            return new Action(actionId, 0, mEventCosts.get(actionId));
-        }
-
-        @Override
-        Reward getReward(int rewardId) {
-            if (mEventCosts.indexOfKey(rewardId) < 0) {
-                return null;
-            }
-            return new Reward(rewardId, mEventCosts.get(rewardId), mEventCosts.get(rewardId),
-                    10 * mEventCosts.get(rewardId));
-        }
-    }
-
-    @Before
-    public void setUp() {
-        final InternalResourceService irs = mock(InternalResourceService.class);
-        when(irs.isVip(anyInt(), anyString(), anyLong())).thenReturn(false);
-        mEconomicPolicy = new MockEconomicPolicy(irs);
-    }
-
-    @Test
-    public void testNoOngoingEvents() {
-        TrendCalculator trendCalculator = new TrendCalculator();
-        mEconomicPolicy.mEventCosts.put(JobSchedulerEconomicPolicy.ACTION_JOB_TIMEOUT, 20);
-
-        trendCalculator.reset(0, 0, null);
-        assertEquals("Expected not to cross lower threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals("Expected not to cross upper threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossUpperThresholdMs());
-
-        ArraySet<ActionAffordabilityNote> affordabilityNotes = new ArraySet<>();
-        affordabilityNotes.add(new ActionAffordabilityNote(new ActionBill(List.of(
-                new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_TIMEOUT, 1, 0))),
-                mock(AffordabilityChangeListener.class), mEconomicPolicy));
-        for (ActionAffordabilityNote note : affordabilityNotes) {
-            note.recalculateCosts(mEconomicPolicy, 0, "com.test.app");
-        }
-
-        trendCalculator.reset(1234, 1234, affordabilityNotes);
-        assertEquals("Expected not to cross lower threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals("Expected not to cross upper threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossUpperThresholdMs());
-    }
-
-    @Test
-    public void testNoAffordabilityNotes() {
-        TrendCalculator trendCalculator = new TrendCalculator();
-
-        OngoingEvent[] events = new OngoingEvent[]{
-                new OngoingEvent(JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, "1",
-                        1, new EconomicPolicy.Cost(1, 4)),
-                new OngoingEvent(JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING, "2",
-                        2, new EconomicPolicy.Cost(3, 6)),
-                new OngoingEvent(EconomicPolicy.REWARD_TOP_ACTIVITY, "3", 3,
-                        new EconomicPolicy.Reward(EconomicPolicy.REWARD_TOP_ACTIVITY, 0, 3, 3)),
-        };
-
-        trendCalculator.reset(0, 100, null);
-        for (OngoingEvent event : events) {
-            trendCalculator.accept(event);
-        }
-        assertEquals(25_000, trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals("Expected not to cross upper threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossUpperThresholdMs());
-
-        ArraySet<ActionAffordabilityNote> affordabilityNotes = new ArraySet<>();
-        trendCalculator.reset(1234, 1234, affordabilityNotes);
-        for (OngoingEvent event : events) {
-            trendCalculator.accept(event);
-        }
-        assertEquals(308_000, trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals("Expected not to cross upper threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossUpperThresholdMs());
-    }
-
-    @Test
-    public void testNoTrendToThreshold() {
-        TrendCalculator trendCalculator = new TrendCalculator();
-        mEconomicPolicy.mEventCosts.put(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING, 10);
-
-        ArraySet<ActionAffordabilityNote> affordabilityNotes = new ArraySet<>();
-        affordabilityNotes.add(new ActionAffordabilityNote(new ActionBill(List.of(
-                new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING, 0, 1000))),
-                mock(AffordabilityChangeListener.class), mEconomicPolicy));
-        for (ActionAffordabilityNote note : affordabilityNotes) {
-            note.recalculateCosts(mEconomicPolicy, 0, "com.test.app");
-        }
-
-        // Balance is already above threshold and events are all positive delta.
-        // There should be no time to report.
-        trendCalculator.reset(1234, 1234, affordabilityNotes);
-        trendCalculator.accept(
-                new OngoingEvent(EconomicPolicy.REWARD_TOP_ACTIVITY, "1", 1,
-                        new EconomicPolicy.Reward(EconomicPolicy.REWARD_TOP_ACTIVITY, 1, 1, 1)));
-        trendCalculator.accept(
-                new OngoingEvent(EconomicPolicy.REWARD_OTHER_USER_INTERACTION, "2", 2,
-                        new EconomicPolicy.Reward(EconomicPolicy.REWARD_OTHER_USER_INTERACTION,
-                                3, 3, 3)));
-
-        assertEquals("Expected not to cross lower threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals("Expected not to cross upper threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossUpperThresholdMs());
-
-        // Balance is already below threshold and events are all negative delta.
-        // There should be no time to report.
-        trendCalculator.reset(1, 0, affordabilityNotes);
-        trendCalculator.accept(
-                new OngoingEvent(JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, "1",
-                        1, new EconomicPolicy.Cost(1, 1)));
-        trendCalculator.accept(
-                new OngoingEvent(JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING, "2",
-                        2, new EconomicPolicy.Cost(3, 3)));
-
-        assertEquals("Expected not to cross lower threshold",
-                0,
-                trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals("Expected not to cross upper threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossUpperThresholdMs());
-    }
-
-    @Test
-    public void testSimpleTrendToThreshold_Balance() {
-        TrendCalculator trendCalculator = new TrendCalculator();
-        mEconomicPolicy.mEventCosts.put(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 20);
-
-        ArraySet<ActionAffordabilityNote> affordabilityNotes = new ArraySet<>();
-        affordabilityNotes.add(new ActionAffordabilityNote(new ActionBill(List.of(
-                new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 1, 0))),
-                mock(AffordabilityChangeListener.class), mEconomicPolicy));
-        for (ActionAffordabilityNote note : affordabilityNotes) {
-            note.recalculateCosts(mEconomicPolicy, 0, "com.test.app");
-        }
-
-        // Balance is below threshold and events are all positive delta.
-        // Should report the correct time to the upper threshold.
-        trendCalculator.reset(0, 1000, affordabilityNotes);
-        trendCalculator.accept(
-                new OngoingEvent(EconomicPolicy.REWARD_TOP_ACTIVITY, "1", 1,
-                        new EconomicPolicy.Reward(EconomicPolicy.REWARD_TOP_ACTIVITY, 1, 1, 1)));
-        trendCalculator.accept(
-                new OngoingEvent(EconomicPolicy.REWARD_OTHER_USER_INTERACTION, "2", 2,
-                        new EconomicPolicy.Reward(EconomicPolicy.REWARD_OTHER_USER_INTERACTION,
-                                3, 3, 3)));
-
-        assertEquals("Expected not to cross lower threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals(5_000, trendCalculator.getTimeToCrossUpperThresholdMs());
-
-        // Balance is above the threshold and events are all negative delta.
-        // Should report the correct time to the lower threshold.
-        trendCalculator.reset(40, 100, affordabilityNotes);
-        trendCalculator.accept(
-                new OngoingEvent(JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, "1",
-                        1, new EconomicPolicy.Cost(1, 1)));
-        trendCalculator.accept(
-                new OngoingEvent(JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING, "2",
-                        2, new EconomicPolicy.Cost(3, 3)));
-
-        assertEquals(5_000, trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals("Expected not to cross upper threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossUpperThresholdMs());
-    }
-
-    @Test
-    public void testSelectCorrectThreshold_Balance() {
-        TrendCalculator trendCalculator = new TrendCalculator();
-        mEconomicPolicy.mEventCosts.put(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 20);
-        mEconomicPolicy.mEventCosts.put(JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_START, 15);
-        mEconomicPolicy.mEventCosts.put(JobSchedulerEconomicPolicy.ACTION_JOB_LOW_START, 10);
-        mEconomicPolicy.mEventCosts.put(JobSchedulerEconomicPolicy.ACTION_JOB_MIN_START, 5);
-
-        ArraySet<ActionAffordabilityNote> affordabilityNotes = new ArraySet<>();
-        affordabilityNotes.add(new ActionAffordabilityNote(new ActionBill(List.of(
-                new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 1, 0))),
-                mock(AffordabilityChangeListener.class), mEconomicPolicy));
-        affordabilityNotes.add(new ActionAffordabilityNote(new ActionBill(List.of(
-                new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_START, 1, 0))),
-                mock(AffordabilityChangeListener.class), mEconomicPolicy));
-        affordabilityNotes.add(new ActionAffordabilityNote(new ActionBill(List.of(
-                new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_LOW_START, 1, 0))),
-                mock(AffordabilityChangeListener.class), mEconomicPolicy));
-        affordabilityNotes.add(new ActionAffordabilityNote(new ActionBill(List.of(
-                new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_MIN_START, 1, 0))),
-                mock(AffordabilityChangeListener.class), mEconomicPolicy));
-        for (ActionAffordabilityNote note : affordabilityNotes) {
-            note.recalculateCosts(mEconomicPolicy, 0, "com.test.app");
-        }
-
-        // Balance is below threshold and events are all positive delta.
-        // Should report the correct time to the correct upper threshold.
-        trendCalculator.reset(0, 10_000, affordabilityNotes);
-        trendCalculator.accept(
-                new OngoingEvent(EconomicPolicy.REWARD_TOP_ACTIVITY, "1", 1,
-                        new EconomicPolicy.Reward(EconomicPolicy.REWARD_TOP_ACTIVITY, 1, 1, 1)));
-
-        assertEquals("Expected not to cross lower threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals(5_000, trendCalculator.getTimeToCrossUpperThresholdMs());
-
-        // Balance is above the threshold and events are all negative delta.
-        // Should report the correct time to the correct lower threshold.
-        trendCalculator.reset(30, 500, affordabilityNotes);
-        trendCalculator.accept(
-                new OngoingEvent(JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, "1",
-                        1, new EconomicPolicy.Cost(1, 1)));
-
-        assertEquals(10_000, trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals("Expected not to cross upper threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossUpperThresholdMs());
-    }
-
-    @Test
-    public void testTrendsToBothThresholds_Balance() {
-        TrendCalculator trendCalculator = new TrendCalculator();
-        mEconomicPolicy.mEventCosts.put(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 20);
-        mEconomicPolicy.mEventCosts.put(AlarmManagerEconomicPolicy.ACTION_ALARM_CLOCK, 50);
-
-        ArraySet<ActionAffordabilityNote> affordabilityNotes = new ArraySet<>();
-        affordabilityNotes.add(new ActionAffordabilityNote(new ActionBill(List.of(
-                new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 1, 0))),
-                mock(AffordabilityChangeListener.class), mEconomicPolicy));
-        affordabilityNotes.add(new ActionAffordabilityNote(new ActionBill(List.of(
-                new AnticipatedAction(AlarmManagerEconomicPolicy.ACTION_ALARM_CLOCK, 1, 0))),
-                mock(AffordabilityChangeListener.class), mEconomicPolicy));
-        for (ActionAffordabilityNote note : affordabilityNotes) {
-            note.recalculateCosts(mEconomicPolicy, 0, "com.test.app");
-        }
-
-        // Balance is between both thresholds and events are mixed positive/negative delta.
-        // Should report the correct time to each threshold.
-        trendCalculator.reset(35, 10_000, affordabilityNotes);
-        trendCalculator.accept(
-                new OngoingEvent(EconomicPolicy.REWARD_TOP_ACTIVITY, "1", 1,
-                        new EconomicPolicy.Reward(EconomicPolicy.REWARD_TOP_ACTIVITY, 3, 3, 3)));
-        trendCalculator.accept(
-                new OngoingEvent(EconomicPolicy.REWARD_OTHER_USER_INTERACTION, "2", 2,
-                        new EconomicPolicy.Reward(EconomicPolicy.REWARD_OTHER_USER_INTERACTION, 2,
-                                2, 2)));
-        trendCalculator.accept(
-                new OngoingEvent(JobSchedulerEconomicPolicy.ACTION_JOB_LOW_RUNNING, "3",
-                        3, new EconomicPolicy.Cost(2, 2)));
-        trendCalculator.accept(
-                new OngoingEvent(JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, "4",
-                        4, new EconomicPolicy.Cost(3, 3)));
-
-        assertEquals(3_000, trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals(3_000, trendCalculator.getTimeToCrossUpperThresholdMs());
-    }
-
-    @Test
-    public void testSimpleTrendToThreshold_ConsumptionLimit() {
-        TrendCalculator trendCalculator = new TrendCalculator();
-        mEconomicPolicy.mEventCosts.put(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 20);
-
-        ArraySet<ActionAffordabilityNote> affordabilityNotes = new ArraySet<>();
-        affordabilityNotes.add(new ActionAffordabilityNote(new ActionBill(List.of(
-                new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 1, 0))),
-                mock(AffordabilityChangeListener.class), mEconomicPolicy));
-        for (ActionAffordabilityNote note : affordabilityNotes) {
-            note.recalculateCosts(mEconomicPolicy, 0, "com.test.app");
-        }
-
-        // Events are all negative delta. Consumable credits will run out before app's balance.
-        // Should report the correct time to the lower threshold.
-        trendCalculator.reset(10000, 40, affordabilityNotes);
-        trendCalculator.accept(
-                new OngoingEvent(JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, "1",
-                        1, new EconomicPolicy.Cost(1, 10)));
-        trendCalculator.accept(
-                new OngoingEvent(JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING, "2",
-                        2, new EconomicPolicy.Cost(3, 40)));
-
-        assertEquals(10_000, trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals("Expected not to cross upper threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossUpperThresholdMs());
-    }
-
-    @Test
-    public void testSelectCorrectThreshold() {
-        TrendCalculator trendCalculator = new TrendCalculator();
-        mEconomicPolicy.mEventCosts.put(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 20);
-        mEconomicPolicy.mEventCosts.put(JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_START, 15);
-        mEconomicPolicy.mEventCosts.put(JobSchedulerEconomicPolicy.ACTION_JOB_LOW_START, 10);
-        mEconomicPolicy.mEventCosts.put(JobSchedulerEconomicPolicy.ACTION_JOB_MIN_START, 5);
-
-        ArraySet<ActionAffordabilityNote> affordabilityNotes = new ArraySet<>();
-        affordabilityNotes.add(new ActionAffordabilityNote(new ActionBill(List.of(
-                new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 1, 0))),
-                mock(AffordabilityChangeListener.class), mEconomicPolicy));
-        affordabilityNotes.add(new ActionAffordabilityNote(new ActionBill(List.of(
-                new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_START, 1, 0))),
-                mock(AffordabilityChangeListener.class), mEconomicPolicy));
-        affordabilityNotes.add(new ActionAffordabilityNote(new ActionBill(List.of(
-                new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_LOW_START, 1, 0))),
-                mock(AffordabilityChangeListener.class), mEconomicPolicy));
-        affordabilityNotes.add(new ActionAffordabilityNote(new ActionBill(List.of(
-                new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_MIN_START, 1, 0))),
-                mock(AffordabilityChangeListener.class), mEconomicPolicy));
-        for (ActionAffordabilityNote note : affordabilityNotes) {
-            note.recalculateCosts(mEconomicPolicy, 0, "com.test.app");
-        }
-
-        // Balance is above threshold, consumable credits is 0, and events are all positive delta.
-        // There should be no time to the upper threshold since consumable credits is the limiting
-        // factor.
-        trendCalculator.reset(10_000, 0, affordabilityNotes);
-        trendCalculator.accept(
-                new OngoingEvent(EconomicPolicy.REWARD_TOP_ACTIVITY, "1", 1,
-                        new EconomicPolicy.Reward(EconomicPolicy.REWARD_TOP_ACTIVITY, 1, 1, 1)));
-
-        assertEquals("Expected not to cross lower threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals("Expected not to cross upper threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossUpperThresholdMs());
-
-        // Balance is above threshold, consumable credits is low, and events are all negative delta.
-        trendCalculator.reset(10_000, 4, affordabilityNotes);
-        trendCalculator.accept(
-                new OngoingEvent(JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, "1",
-                        1, new EconomicPolicy.Cost(1, 10)));
-
-        assertEquals(4000, trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals("Expected not to cross upper threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossUpperThresholdMs());
-
-        // Balance is above threshold, consumable credits is 0, and events are all negative delta.
-        // Time to the lower threshold should be 0 since consumable credits is already 0.
-        trendCalculator.reset(10_000, 0, affordabilityNotes);
-        trendCalculator.accept(
-                new OngoingEvent(JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, "1",
-                        1, new EconomicPolicy.Cost(1, 10)));
-
-        assertEquals(0, trendCalculator.getTimeToCrossLowerThresholdMs());
-        assertEquals("Expected not to cross upper threshold",
-                TrendCalculator.WILL_NOT_CROSS_THRESHOLD,
-                trendCalculator.getTimeToCrossUpperThresholdMs());
-    }
-}
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/AlarmManagerEconomicPolicyTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/AlarmManagerEconomicPolicyTest.java
deleted file mode 100644
index 77723d7..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/tare/AlarmManagerEconomicPolicyTest.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static android.app.tare.EconomyManager.arcToCake;
-import static android.provider.Settings.Global.TARE_ALARM_MANAGER_CONSTANTS;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-
-import android.app.ActivityManager;
-import android.app.IActivityManager;
-import android.app.tare.EconomyManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.BatteryManager;
-import android.os.Looper;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.provider.DeviceConfig;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.Mock;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
-import org.mockito.stubbing.Answer;
-
-@RunWith(AndroidJUnit4.class)
-public class AlarmManagerEconomicPolicyTest {
-    private AlarmManagerEconomicPolicy mEconomicPolicy;
-    private DeviceConfig.Properties.Builder mDeviceConfigPropertiesBuilder;
-    private EconomicPolicy.Injector mInjector = new InjectorForTest();
-
-    private MockitoSession mMockingSession;
-    @Mock
-    private Context mContext;
-    @Mock
-    private InternalResourceService mIrs;
-
-    private static class InjectorForTest extends EconomicPolicy.Injector {
-        public String settingsConstant;
-
-        @Nullable
-        @Override
-        String getSettingsGlobalString(@NonNull ContentResolver resolver, @NonNull String name) {
-            return TARE_ALARM_MANAGER_CONSTANTS.equals(name) ? settingsConstant : null;
-        }
-    }
-
-    @Before
-    public void setUp() {
-        mMockingSession = mockitoSession()
-            .initMocks(this)
-            .strictness(Strictness.LENIENT)
-            .spyStatic(DeviceConfig.class)
-            .startMocking();
-
-        when(mIrs.getContext()).thenReturn(mContext);
-        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
-        when(mContext.getContentResolver()).thenReturn(mock(ContentResolver.class));
-        // Called by Modifiers.
-        when(mContext.getSystemService(BatteryManager.class))
-            .thenReturn(mock(BatteryManager.class));
-        when(mContext.getSystemService(PowerManager.class))
-            .thenReturn(mock(PowerManager.class));
-        IActivityManager activityManager = ActivityManager.getService();
-        spyOn(activityManager);
-        try {
-            doNothing().when(activityManager).registerUidObserver(any(), anyInt(), anyInt(), any());
-        } catch (RemoteException e) {
-            fail("registerUidObserver threw exception: " + e.getMessage());
-        }
-
-        mDeviceConfigPropertiesBuilder =
-                new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_TARE);
-        doAnswer(
-                (Answer<DeviceConfig.Properties>) invocationOnMock
-                        -> mDeviceConfigPropertiesBuilder.build())
-                .when(() -> DeviceConfig.getProperties(
-                        eq(DeviceConfig.NAMESPACE_TARE), ArgumentMatchers.<String>any()));
-
-        // Initialize real objects.
-        // Capture the listeners.
-        mEconomicPolicy = new AlarmManagerEconomicPolicy(mIrs, mInjector);
-    }
-
-    @After
-    public void tearDown() {
-        if (mMockingSession != null) {
-            mMockingSession.finishMocking();
-        }
-    }
-
-    private void setDeviceConfigCakes(String key, long valCakes) {
-        mDeviceConfigPropertiesBuilder.setString(key, valCakes + "c");
-        mEconomicPolicy.setup(mDeviceConfigPropertiesBuilder.build());
-    }
-
-    @Test
-    public void testDefaults() {
-        assertEquals(EconomyManager.DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getInitialSatiatedConsumptionLimit());
-        assertEquals(EconomyManager.DEFAULT_AM_MIN_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getMinSatiatedConsumptionLimit());
-        assertEquals(EconomyManager.DEFAULT_AM_MAX_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getMaxSatiatedConsumptionLimit());
-
-        final String pkgRestricted = "com.pkg.restricted";
-        when(mIrs.isPackageRestricted(anyInt(), eq(pkgRestricted))).thenReturn(true);
-        assertEquals(0, mEconomicPolicy.getMinSatiatedBalance(0, pkgRestricted));
-        assertEquals(0, mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
-
-        final String pkgExempted = "com.pkg.exempted";
-        when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
-        assertEquals(EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
-                mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
-        assertEquals(EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
-                mEconomicPolicy.getMaxSatiatedBalance(0, pkgExempted));
-
-        final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
-        when(mIrs.isHeadlessSystemApp(anyInt(), eq(pkgHeadlessSystemApp))).thenReturn(true);
-        assertEquals(EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
-                mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
-        assertEquals(EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
-                mEconomicPolicy.getMaxSatiatedBalance(0, pkgHeadlessSystemApp));
-
-        assertEquals(EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES,
-                mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
-        assertEquals(EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
-                mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
-    }
-
-    @Test
-    public void testConstantsUpdating_ValidValues() {
-        setDeviceConfigCakes(EconomyManager.KEY_AM_INITIAL_CONSUMPTION_LIMIT, arcToCake(5));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_CONSUMPTION_LIMIT, arcToCake(3));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_CONSUMPTION_LIMIT, arcToCake(25));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_SATIATED_BALANCE, arcToCake(10));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(9));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
-                arcToCake(8));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(7));
-
-        assertEquals(arcToCake(5), mEconomicPolicy.getInitialSatiatedConsumptionLimit());
-        assertEquals(arcToCake(3), mEconomicPolicy.getMinSatiatedConsumptionLimit());
-        assertEquals(arcToCake(25), mEconomicPolicy.getMaxSatiatedConsumptionLimit());
-        final String pkgRestricted = "com.pkg.restricted";
-        when(mIrs.isPackageRestricted(anyInt(), eq(pkgRestricted))).thenReturn(true);
-        assertEquals(arcToCake(0), mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
-        assertEquals(arcToCake(10), mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
-        final String pkgExempted = "com.pkg.exempted";
-        when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
-        assertEquals(arcToCake(9), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
-        final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
-        when(mIrs.isHeadlessSystemApp(anyInt(), eq(pkgHeadlessSystemApp))).thenReturn(true);
-        assertEquals(arcToCake(8), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
-        assertEquals(arcToCake(7), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
-    }
-
-    @Test
-    public void testConstantsUpdating_InvalidValues() {
-        // Test negatives.
-        setDeviceConfigCakes(EconomyManager.KEY_AM_INITIAL_CONSUMPTION_LIMIT, arcToCake(-5));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_CONSUMPTION_LIMIT, arcToCake(-5));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_CONSUMPTION_LIMIT, arcToCake(-5));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_SATIATED_BALANCE, arcToCake(-1));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(-2));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
-                arcToCake(-3));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(-3));
-
-        assertEquals(arcToCake(1), mEconomicPolicy.getInitialSatiatedConsumptionLimit());
-        assertEquals(arcToCake(1), mEconomicPolicy.getMinSatiatedConsumptionLimit());
-        assertEquals(arcToCake(1), mEconomicPolicy.getMaxSatiatedConsumptionLimit());
-        final String pkgRestricted = "com.pkg.restricted";
-        when(mIrs.isPackageRestricted(anyInt(), eq(pkgRestricted))).thenReturn(true);
-        assertEquals(arcToCake(0), mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
-        assertEquals(arcToCake(1), mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
-        final String pkgExempted = "com.pkg.exempted";
-        when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
-        assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
-        final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
-        when(mIrs.isHeadlessSystemApp(anyInt(), eq(pkgHeadlessSystemApp))).thenReturn(true);
-        assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
-        assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
-
-        // Test min+max reversed.
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_CONSUMPTION_LIMIT, arcToCake(5));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_INITIAL_CONSUMPTION_LIMIT, arcToCake(4));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_CONSUMPTION_LIMIT, arcToCake(3));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_SATIATED_BALANCE, arcToCake(10));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(11));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
-                arcToCake(12));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(13));
-
-        assertEquals(arcToCake(5), mEconomicPolicy.getInitialSatiatedConsumptionLimit());
-        assertEquals(arcToCake(5), mEconomicPolicy.getMinSatiatedConsumptionLimit());
-        assertEquals(arcToCake(5), mEconomicPolicy.getMaxSatiatedConsumptionLimit());
-        assertEquals(arcToCake(0), mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
-        assertEquals(arcToCake(13), mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
-        assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
-        assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
-        assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
-    }
-}
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/CompleteEconomicPolicyTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/CompleteEconomicPolicyTest.java
deleted file mode 100644
index c5fdb6f..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/tare/CompleteEconomicPolicyTest.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static android.app.tare.EconomyManager.arcToCake;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-
-import android.app.ActivityManager;
-import android.app.IActivityManager;
-import android.app.tare.EconomyManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.BatteryManager;
-import android.os.Looper;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.provider.DeviceConfig;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.Mock;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
-import org.mockito.stubbing.Answer;
-
-@RunWith(AndroidJUnit4.class)
-public class CompleteEconomicPolicyTest {
-    private CompleteEconomicPolicy mEconomicPolicy;
-    private DeviceConfig.Properties.Builder mDeviceConfigPropertiesBuilder;
-    private final CompleteEconomicPolicy.CompleteInjector mInjector = new InjectorForTest();
-
-    private MockitoSession mMockingSession;
-    @Mock
-    private Context mContext;
-    @Mock
-    private InternalResourceService mIrs;
-
-    private static class InjectorForTest extends CompleteEconomicPolicy.CompleteInjector {
-        public String settingsConstant;
-
-        @Nullable
-        @Override
-        String getSettingsGlobalString(@NonNull ContentResolver resolver, @NonNull String name) {
-            return settingsConstant;
-        }
-
-        @Override
-        boolean isPolicyEnabled(int policy, @Nullable DeviceConfig.Properties properties) {
-            // Use a limited set of policies so that the test doesn't need to be updated whenever
-            // a policy is added or removed.
-            if (policy == EconomicPolicy.POLICY_ALARM || policy == EconomicPolicy.POLICY_JOB) {
-                return super.isPolicyEnabled(policy, properties);
-            }
-            return false;
-        }
-    }
-
-    @Before
-    public void setUp() {
-        mMockingSession = mockitoSession()
-                .initMocks(this)
-                .strictness(Strictness.LENIENT)
-                .spyStatic(DeviceConfig.class)
-                .startMocking();
-
-        when(mIrs.getContext()).thenReturn(mContext);
-        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
-        when(mContext.getContentResolver()).thenReturn(mock(ContentResolver.class));
-        // Called by Modifiers.
-        when(mContext.getSystemService(BatteryManager.class))
-            .thenReturn(mock(BatteryManager.class));
-        when(mContext.getSystemService(PowerManager.class))
-            .thenReturn(mock(PowerManager.class));
-        IActivityManager activityManager = ActivityManager.getService();
-        spyOn(activityManager);
-        try {
-            doNothing().when(activityManager).registerUidObserver(any(), anyInt(), anyInt(), any());
-        } catch (RemoteException e) {
-            fail("registerUidObserver threw exception: " + e.getMessage());
-        }
-
-        mDeviceConfigPropertiesBuilder =
-                new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_TARE);
-        doAnswer(
-                (Answer<DeviceConfig.Properties>) invocationOnMock
-                        -> mDeviceConfigPropertiesBuilder.build())
-                .when(() -> DeviceConfig.getProperties(
-                        eq(DeviceConfig.NAMESPACE_TARE), ArgumentMatchers.<String>any()));
-        mDeviceConfigPropertiesBuilder
-                .setBoolean(EconomyManager.KEY_ENABLE_POLICY_ALARM, true)
-                .setBoolean(EconomyManager.KEY_ENABLE_POLICY_JOB_SCHEDULER, true);
-
-        // Initialize real objects.
-        // Capture the listeners.
-        mEconomicPolicy = new CompleteEconomicPolicy(mIrs, mInjector);
-        mEconomicPolicy.setup(mDeviceConfigPropertiesBuilder.build());
-    }
-
-    @After
-    public void tearDown() {
-        if (mMockingSession != null) {
-            mMockingSession.finishMocking();
-        }
-    }
-
-    private void setDeviceConfigBoolean(String key, boolean val) {
-        mDeviceConfigPropertiesBuilder.setBoolean(key, val);
-        mEconomicPolicy.setup(mDeviceConfigPropertiesBuilder.build());
-    }
-
-    private void setDeviceConfigCakes(String key, long valCakes) {
-        mDeviceConfigPropertiesBuilder.setString(key, valCakes + "c");
-        mEconomicPolicy.setup(mDeviceConfigPropertiesBuilder.build());
-    }
-
-    @Test
-    public void testDefaults() {
-        assertEquals(EconomyManager.DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES
-                + EconomyManager.DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getInitialSatiatedConsumptionLimit());
-        assertEquals(EconomyManager.DEFAULT_JS_MIN_CONSUMPTION_LIMIT_CAKES
-                + EconomyManager.DEFAULT_AM_MIN_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getMinSatiatedConsumptionLimit());
-        assertEquals(EconomyManager.DEFAULT_JS_MAX_CONSUMPTION_LIMIT_CAKES
-                + EconomyManager.DEFAULT_AM_MAX_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getMaxSatiatedConsumptionLimit());
-        final String pkgRestricted = "com.pkg.restricted";
-        when(mIrs.isPackageRestricted(anyInt(), eq(pkgRestricted))).thenReturn(true);
-        assertEquals(0, mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
-        assertEquals(EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES
-                + EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
-                mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
-        final String pkgExempted = "com.pkg.exempted";
-        when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
-        assertEquals(EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES
-                + EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
-                mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
-        assertEquals(EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES
-                + EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES,
-                mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
-    }
-
-    @Test
-    public void testConstantsUpdated() {
-        setDeviceConfigCakes(EconomyManager.KEY_JS_INITIAL_CONSUMPTION_LIMIT, arcToCake(4));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_INITIAL_CONSUMPTION_LIMIT, arcToCake(6));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_CONSUMPTION_LIMIT, arcToCake(2));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_CONSUMPTION_LIMIT, arcToCake(3));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MAX_CONSUMPTION_LIMIT, arcToCake(24));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_CONSUMPTION_LIMIT, arcToCake(26));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MAX_SATIATED_BALANCE, arcToCake(9));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MAX_SATIATED_BALANCE, arcToCake(11));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(8));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(5));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
-                arcToCake(6));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
-                arcToCake(4));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(3));
-        setDeviceConfigCakes(EconomyManager.KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(2));
-
-        assertEquals(arcToCake(10), mEconomicPolicy.getInitialSatiatedConsumptionLimit());
-        assertEquals(arcToCake(5), mEconomicPolicy.getMinSatiatedConsumptionLimit());
-        assertEquals(arcToCake(50), mEconomicPolicy.getMaxSatiatedConsumptionLimit());
-        final String pkgRestricted = "com.pkg.restricted";
-        when(mIrs.isPackageRestricted(anyInt(), eq(pkgRestricted))).thenReturn(true);
-        assertEquals(arcToCake(0), mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
-        assertEquals(arcToCake(20), mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
-        final String pkgExempted = "com.pkg.exempted";
-        when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
-        assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
-        final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
-        when(mIrs.isHeadlessSystemApp(anyInt(), eq(pkgHeadlessSystemApp))).thenReturn(true);
-        assertEquals(arcToCake(10), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
-        assertEquals(arcToCake(5), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
-    }
-
-
-    @Test
-    public void testPolicyToggling() {
-        setDeviceConfigBoolean(EconomyManager.KEY_ENABLE_POLICY_ALARM, true);
-        setDeviceConfigBoolean(EconomyManager.KEY_ENABLE_POLICY_JOB_SCHEDULER, false);
-        assertEquals(EconomyManager.DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getInitialSatiatedConsumptionLimit());
-        assertEquals(EconomyManager.DEFAULT_AM_MIN_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getMinSatiatedConsumptionLimit());
-        assertEquals(EconomyManager.DEFAULT_AM_MAX_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getMaxSatiatedConsumptionLimit());
-        final String pkgRestricted = "com.pkg.restricted";
-        when(mIrs.isPackageRestricted(anyInt(), eq(pkgRestricted))).thenReturn(true);
-        assertEquals(0, mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
-        assertEquals(EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES,
-                mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
-        final String pkgExempted = "com.pkg.exempted";
-        when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
-        assertEquals(EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
-                mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
-        assertEquals(EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES,
-                mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
-        assertNotNull(mEconomicPolicy.getAction(AlarmManagerEconomicPolicy.ACTION_ALARM_CLOCK));
-        assertNull(mEconomicPolicy.getAction(JobSchedulerEconomicPolicy.ACTION_JOB_LOW_START));
-        assertEquals(EconomicPolicy.POLICY_ALARM, mEconomicPolicy.getEnabledPolicyIds());
-        assertTrue(mEconomicPolicy.isPolicyEnabled(EconomicPolicy.POLICY_ALARM));
-        assertFalse(mEconomicPolicy.isPolicyEnabled(EconomicPolicy.POLICY_JOB));
-
-        setDeviceConfigBoolean(EconomyManager.KEY_ENABLE_POLICY_ALARM, false);
-        setDeviceConfigBoolean(EconomyManager.KEY_ENABLE_POLICY_JOB_SCHEDULER, true);
-        assertEquals(EconomyManager.DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getInitialSatiatedConsumptionLimit());
-        assertEquals(EconomyManager.DEFAULT_JS_MIN_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getMinSatiatedConsumptionLimit());
-        assertEquals(EconomyManager.DEFAULT_JS_MAX_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getMaxSatiatedConsumptionLimit());
-        when(mIrs.isPackageRestricted(anyInt(), eq(pkgRestricted))).thenReturn(true);
-        assertEquals(0, mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
-        assertEquals(EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
-                mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
-        when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
-        assertEquals(EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
-                mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
-        assertEquals(EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES,
-                mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
-        assertNull(mEconomicPolicy.getAction(AlarmManagerEconomicPolicy.ACTION_ALARM_CLOCK));
-        assertNotNull(mEconomicPolicy.getAction(JobSchedulerEconomicPolicy.ACTION_JOB_LOW_START));
-        assertEquals(EconomicPolicy.POLICY_JOB, mEconomicPolicy.getEnabledPolicyIds());
-        assertFalse(mEconomicPolicy.isPolicyEnabled(EconomicPolicy.POLICY_ALARM));
-        assertTrue(mEconomicPolicy.isPolicyEnabled(EconomicPolicy.POLICY_JOB));
-    }
-}
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/EconomicPolicyTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/EconomicPolicyTest.java
deleted file mode 100644
index 29bddfc..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/tare/EconomicPolicyTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static org.junit.Assert.assertEquals;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class EconomicPolicyTest {
-
-    @Test
-    public void testMasksDisjoint() {
-        assertEquals(-1,
-                (-1 & EconomicPolicy.MASK_TYPE)
-                        + (-1 & EconomicPolicy.MASK_POLICY)
-                        + (-1 & EconomicPolicy.MASK_EVENT));
-    }
-}
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/JobSchedulerEconomicPolicyTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/JobSchedulerEconomicPolicyTest.java
deleted file mode 100644
index d41c93b..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/tare/JobSchedulerEconomicPolicyTest.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static android.app.tare.EconomyManager.arcToCake;
-import static android.provider.Settings.Global.TARE_JOB_SCHEDULER_CONSTANTS;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-
-import android.app.ActivityManager;
-import android.app.IActivityManager;
-import android.app.tare.EconomyManager;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.BatteryManager;
-import android.os.Looper;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.provider.DeviceConfig;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
-import org.mockito.Mock;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
-import org.mockito.stubbing.Answer;
-
-@RunWith(AndroidJUnit4.class)
-public class JobSchedulerEconomicPolicyTest {
-    private JobSchedulerEconomicPolicy mEconomicPolicy;
-    private DeviceConfig.Properties.Builder mDeviceConfigPropertiesBuilder;
-    private final EconomicPolicy.Injector mInjector = new InjectorForTest();
-
-    private MockitoSession mMockingSession;
-    @Mock
-    private Context mContext;
-    @Mock
-    private InternalResourceService mIrs;
-
-    private static class InjectorForTest extends EconomicPolicy.Injector {
-        public String settingsConstant;
-
-        @Nullable
-        @Override
-        String getSettingsGlobalString(@NonNull ContentResolver resolver, @NonNull String name) {
-            return TARE_JOB_SCHEDULER_CONSTANTS.equals(name) ? settingsConstant : null;
-        }
-    }
-
-    @Before
-    public void setUp() {
-        mMockingSession = mockitoSession()
-                .initMocks(this)
-                .strictness(Strictness.LENIENT)
-                .spyStatic(DeviceConfig.class)
-                .startMocking();
-
-        when(mIrs.getContext()).thenReturn(mContext);
-        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
-        when(mContext.getContentResolver()).thenReturn(mock(ContentResolver.class));
-        // Called by Modifiers.
-        when(mContext.getSystemService(BatteryManager.class))
-            .thenReturn(mock(BatteryManager.class));
-        when(mContext.getSystemService(PowerManager.class))
-            .thenReturn(mock(PowerManager.class));
-        IActivityManager activityManager = ActivityManager.getService();
-        spyOn(activityManager);
-        try {
-            doNothing().when(activityManager).registerUidObserver(any(), anyInt(), anyInt(), any());
-        } catch (RemoteException e) {
-            fail("registerUidObserver threw exception: " + e.getMessage());
-        }
-
-        mDeviceConfigPropertiesBuilder =
-                new DeviceConfig.Properties.Builder(DeviceConfig.NAMESPACE_TARE);
-        doAnswer(
-                (Answer<DeviceConfig.Properties>) invocationOnMock
-                        -> mDeviceConfigPropertiesBuilder.build())
-                .when(() -> DeviceConfig.getProperties(
-                        eq(DeviceConfig.NAMESPACE_TARE), ArgumentMatchers.<String>any()));
-
-        // Initialize real objects.
-        // Capture the listeners.
-        mEconomicPolicy = new JobSchedulerEconomicPolicy(mIrs, mInjector);
-    }
-
-    @After
-    public void tearDown() {
-        if (mMockingSession != null) {
-            mMockingSession.finishMocking();
-        }
-    }
-
-    private void setDeviceConfigCakes(String key, long valCakes) {
-        mDeviceConfigPropertiesBuilder.setString(key, valCakes + "c");
-        mEconomicPolicy.setup(mDeviceConfigPropertiesBuilder.build());
-    }
-
-    @Test
-    public void testDefaults() {
-        assertEquals(EconomyManager.DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getInitialSatiatedConsumptionLimit());
-        assertEquals(EconomyManager.DEFAULT_JS_MIN_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getMinSatiatedConsumptionLimit());
-        assertEquals(EconomyManager.DEFAULT_JS_MAX_CONSUMPTION_LIMIT_CAKES,
-                mEconomicPolicy.getMaxSatiatedConsumptionLimit());
-
-        final String pkgRestricted = "com.pkg.restricted";
-        when(mIrs.isPackageRestricted(anyInt(), eq(pkgRestricted))).thenReturn(true);
-        assertEquals(0, mEconomicPolicy.getMinSatiatedBalance(0, pkgRestricted));
-        assertEquals(0, mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
-
-        final String pkgExempted = "com.pkg.exempted";
-        when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
-        assertEquals(EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES,
-                mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
-        assertEquals(EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
-                mEconomicPolicy.getMaxSatiatedBalance(0, pkgExempted));
-
-        final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
-        when(mIrs.isHeadlessSystemApp(anyInt(), eq(pkgHeadlessSystemApp))).thenReturn(true);
-        assertEquals(EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP_CAKES,
-                mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
-        assertEquals(EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
-                mEconomicPolicy.getMaxSatiatedBalance(0, pkgHeadlessSystemApp));
-
-        final String pkgUpdater = "com.pkg.updater";
-        when(mIrs.getAppUpdateResponsibilityCount(anyInt(), eq(pkgUpdater))).thenReturn(5);
-        assertEquals(5 * EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES
-                        + EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES,
-                mEconomicPolicy.getMinSatiatedBalance(0, pkgUpdater));
-        assertEquals(EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
-                mEconomicPolicy.getMaxSatiatedBalance(0, pkgUpdater));
-        // Make sure it doesn't suggest a min balance greater than max.
-        final int updateCount = (int) (EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES
-                / EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER_CAKES);
-        when(mIrs.getAppUpdateResponsibilityCount(anyInt(), eq(pkgUpdater)))
-                .thenReturn(updateCount);
-        assertEquals(EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
-                mEconomicPolicy.getMinSatiatedBalance(0, pkgUpdater));
-
-        assertEquals(EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES,
-                mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
-        assertEquals(EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES,
-                mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
-    }
-
-    @Test
-    public void testConstantsUpdating_ValidValues() {
-        setDeviceConfigCakes(EconomyManager.KEY_JS_INITIAL_CONSUMPTION_LIMIT, arcToCake(5));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_CONSUMPTION_LIMIT, arcToCake(2));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MAX_CONSUMPTION_LIMIT, arcToCake(25));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MAX_SATIATED_BALANCE, arcToCake(10));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(6));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
-                arcToCake(5));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(4));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER,
-                arcToCake(1));
-
-        assertEquals(arcToCake(5), mEconomicPolicy.getInitialSatiatedConsumptionLimit());
-        assertEquals(arcToCake(2), mEconomicPolicy.getMinSatiatedConsumptionLimit());
-        assertEquals(arcToCake(25), mEconomicPolicy.getMaxSatiatedConsumptionLimit());
-        final String pkgRestricted = "com.pkg.restricted";
-        when(mIrs.isPackageRestricted(anyInt(), eq(pkgRestricted))).thenReturn(true);
-        assertEquals(arcToCake(0), mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
-        assertEquals(arcToCake(10), mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
-        final String pkgExempted = "com.pkg.exempted";
-        when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
-        assertEquals(arcToCake(6), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
-        final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
-        when(mIrs.isHeadlessSystemApp(anyInt(), eq(pkgHeadlessSystemApp))).thenReturn(true);
-        assertEquals(arcToCake(5), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
-        assertEquals(arcToCake(4), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
-        final String pkgUpdater = "com.pkg.updater";
-        when(mIrs.getAppUpdateResponsibilityCount(anyInt(), eq(pkgUpdater))).thenReturn(3);
-        assertEquals(arcToCake(4) + 3 * arcToCake(1),
-                mEconomicPolicy.getMinSatiatedBalance(0, pkgUpdater));
-    }
-
-    @Test
-    public void testConstantsUpdating_InvalidValues() {
-        // Test negatives.
-        setDeviceConfigCakes(EconomyManager.KEY_JS_INITIAL_CONSUMPTION_LIMIT, arcToCake(-5));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_CONSUMPTION_LIMIT, arcToCake(-5));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MAX_CONSUMPTION_LIMIT, arcToCake(-5));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MAX_SATIATED_BALANCE, arcToCake(-1));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(-2));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
-                arcToCake(-3));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(-3));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_INCREMENT_APP_UPDATER,
-                arcToCake(-4));
-
-        assertEquals(arcToCake(1), mEconomicPolicy.getInitialSatiatedConsumptionLimit());
-        assertEquals(arcToCake(1), mEconomicPolicy.getMinSatiatedConsumptionLimit());
-        assertEquals(arcToCake(1), mEconomicPolicy.getMaxSatiatedConsumptionLimit());
-        final String pkgRestricted = "com.pkg.restricted";
-        when(mIrs.isPackageRestricted(anyInt(), eq(pkgRestricted))).thenReturn(true);
-        assertEquals(arcToCake(0), mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
-        assertEquals(arcToCake(1), mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
-        final String pkgExempted = "com.pkg.exempted";
-        when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true);
-        assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
-        final String pkgHeadlessSystemApp = "com.pkg.headless_system_app";
-        when(mIrs.isHeadlessSystemApp(anyInt(), eq(pkgHeadlessSystemApp))).thenReturn(true);
-        assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
-        assertEquals(arcToCake(0), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
-        final String pkgUpdater = "com.pkg.updater";
-        when(mIrs.getAppUpdateResponsibilityCount(anyInt(), eq(pkgUpdater))).thenReturn(5);
-        assertEquals(arcToCake(0) + 5 * arcToCake(0),
-                mEconomicPolicy.getMinSatiatedBalance(0, pkgUpdater));
-
-        // Test min+max reversed.
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_CONSUMPTION_LIMIT, arcToCake(5));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_INITIAL_CONSUMPTION_LIMIT, arcToCake(4));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MAX_CONSUMPTION_LIMIT, arcToCake(3));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MAX_SATIATED_BALANCE, arcToCake(10));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED, arcToCake(11));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_HEADLESS_SYSTEM_APP,
-                arcToCake(12));
-        setDeviceConfigCakes(EconomyManager.KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP, arcToCake(13));
-
-        assertEquals(arcToCake(5), mEconomicPolicy.getInitialSatiatedConsumptionLimit());
-        assertEquals(arcToCake(5), mEconomicPolicy.getMinSatiatedConsumptionLimit());
-        assertEquals(arcToCake(5), mEconomicPolicy.getMaxSatiatedConsumptionLimit());
-        assertEquals(arcToCake(0), mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted));
-        assertEquals(arcToCake(13), mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app"));
-        assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted));
-        assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, pkgHeadlessSystemApp));
-        assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app"));
-    }
-}
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/OWNERS b/services/tests/mockingservicestests/src/com/android/server/tare/OWNERS
deleted file mode 100644
index 217a5ed..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/tare/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include /apex/jobscheduler/service/java/com/android/server/tare/OWNERS
\ No newline at end of file
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java
deleted file mode 100644
index e81b63c..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-import static com.android.server.tare.TareTestUtils.assertLedgersEqual;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.when;
-
-import android.app.tare.EconomyManager;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.os.UserHandle;
-import android.util.Log;
-import android.util.SparseArrayMap;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.server.LocalServices;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
-import org.mockito.Mock;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Tests for various Scribe behavior, including reading and writing correctly from file.
- *
- * atest FrameworksServicesTests:ScribeTest
- */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class ScribeTest {
-    private static final String TAG = "ScribeTest";
-
-    private static final int TEST_USER_ID = 27;
-    private static final String TEST_PACKAGE = "com.android.test";
-
-    private MockitoSession mMockingSession;
-    private Scribe mScribeUnderTest;
-    private File mTestFileDir;
-    private final SparseArrayMap<String, InstalledPackageInfo> mInstalledPackages =
-            new SparseArrayMap<>();
-    private final List<Analyst.Report> mReports = new ArrayList<>();
-
-    @Mock
-    private Analyst mAnalyst;
-    @Mock
-    private InternalResourceService mIrs;
-
-    private Context getContext() {
-        return InstrumentationRegistry.getContext();
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        mMockingSession = mockitoSession()
-                .initMocks(this)
-                .strictness(Strictness.LENIENT)
-                .mockStatic(LocalServices.class)
-                .startMocking();
-        when(mIrs.getLock()).thenReturn(new Object());
-        when(mIrs.getEnabledMode()).thenReturn(EconomyManager.ENABLED_MODE_ON);
-        when(mIrs.getInstalledPackages()).thenReturn(mInstalledPackages);
-        when(mAnalyst.getReports()).thenReturn(mReports);
-        mTestFileDir = new File(getContext().getFilesDir(), "scribe_test");
-        //noinspection ResultOfMethodCallIgnored
-        mTestFileDir.mkdirs();
-        Log.d(TAG, "Saving data to '" + mTestFileDir + "'");
-        mScribeUnderTest = new Scribe(mIrs, mAnalyst, mTestFileDir);
-
-        addInstalledPackage(TEST_USER_ID, TEST_PACKAGE);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mScribeUnderTest.tearDownLocked();
-        if (mTestFileDir.exists() && !mTestFileDir.delete()) {
-            Log.w(TAG, "Failed to delete test file directory");
-        }
-        if (mMockingSession != null) {
-            mMockingSession.finishMocking();
-        }
-    }
-
-    @Test
-    public void testWritingAnalystReportsToDisk() {
-        ArgumentCaptor<List<Analyst.Report>> reportCaptor =
-                ArgumentCaptor.forClass(List.class);
-
-        InOrder inOrder = inOrder(mAnalyst);
-
-        // Empty set
-        mReports.clear();
-        mScribeUnderTest.writeImmediatelyForTesting();
-        mScribeUnderTest.loadFromDiskLocked();
-        inOrder.verify(mAnalyst).loadReports(reportCaptor.capture());
-        List<Analyst.Report> result = reportCaptor.getValue();
-        assertReportListsEqual(mReports, result);
-
-        Analyst.Report report1 = new Analyst.Report();
-        report1.cumulativeBatteryDischarge = 1;
-        report1.currentBatteryLevel = 2;
-        report1.cumulativeProfit = 3;
-        report1.numProfitableActions = 4;
-        report1.cumulativeLoss = 5;
-        report1.numUnprofitableActions = 6;
-        report1.cumulativeRewards = 7;
-        report1.numRewards = 8;
-        report1.cumulativePositiveRegulations = 9;
-        report1.numPositiveRegulations = 10;
-        report1.cumulativeNegativeRegulations = 11;
-        report1.numNegativeRegulations = 12;
-        report1.screenOffDurationMs = 13;
-        report1.screenOffDischargeMah = 14;
-        mReports.add(report1);
-        mScribeUnderTest.writeImmediatelyForTesting();
-        mScribeUnderTest.loadFromDiskLocked();
-        inOrder.verify(mAnalyst).loadReports(reportCaptor.capture());
-        result = reportCaptor.getValue();
-        assertReportListsEqual(mReports, result);
-
-        Analyst.Report report2 = new Analyst.Report();
-        report2.cumulativeBatteryDischarge = 10;
-        report2.currentBatteryLevel = 20;
-        report2.cumulativeProfit = 30;
-        report2.numProfitableActions = 40;
-        report2.cumulativeLoss = 50;
-        report2.numUnprofitableActions = 60;
-        report2.cumulativeRewards = 70;
-        report2.numRewards = 80;
-        report2.cumulativePositiveRegulations = 90;
-        report2.numPositiveRegulations = 100;
-        report2.cumulativeNegativeRegulations = 110;
-        report2.numNegativeRegulations = 120;
-        report2.screenOffDurationMs = 130;
-        report2.screenOffDischargeMah = 140;
-        mReports.add(report2);
-        mScribeUnderTest.writeImmediatelyForTesting();
-        mScribeUnderTest.loadFromDiskLocked();
-        inOrder.verify(mAnalyst).loadReports(reportCaptor.capture());
-        result = reportCaptor.getValue();
-        assertReportListsEqual(mReports, result);
-    }
-
-    @Test
-    public void testWriteHighLevelStateToDisk() {
-        long lastReclamationTime = System.currentTimeMillis();
-        long remainingConsumableCakes = 2000L;
-        long consumptionLimit = 500_000L;
-        when(mIrs.getConsumptionLimitLocked()).thenReturn(consumptionLimit);
-
-        Ledger ledger = mScribeUnderTest.getLedgerLocked(TEST_USER_ID, TEST_PACKAGE);
-        ledger.recordTransaction(
-                new Ledger.Transaction(0, 1000L, EconomicPolicy.TYPE_REWARD | 1, null, 2000, 0));
-        // Negative ledger balance shouldn't affect the total circulation value.
-        ledger = mScribeUnderTest.getLedgerLocked(TEST_USER_ID + 1, TEST_PACKAGE);
-        ledger.recordTransaction(
-                new Ledger.Transaction(0, 1000L,
-                        EconomicPolicy.TYPE_ACTION | 1, null, -5000, 3000));
-        mScribeUnderTest.setLastReclamationTimeLocked(lastReclamationTime);
-        mScribeUnderTest.setConsumptionLimitLocked(consumptionLimit);
-        mScribeUnderTest.adjustRemainingConsumableCakesLocked(
-                remainingConsumableCakes - consumptionLimit);
-
-        assertEquals(lastReclamationTime, mScribeUnderTest.getLastReclamationTimeLocked());
-        assertEquals(remainingConsumableCakes,
-                mScribeUnderTest.getRemainingConsumableCakesLocked());
-        assertEquals(consumptionLimit, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
-
-        mScribeUnderTest.writeImmediatelyForTesting();
-        mScribeUnderTest.loadFromDiskLocked();
-
-        assertEquals(lastReclamationTime, mScribeUnderTest.getLastReclamationTimeLocked());
-        assertEquals(remainingConsumableCakes,
-                mScribeUnderTest.getRemainingConsumableCakesLocked());
-        assertEquals(consumptionLimit, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
-    }
-
-    @Test
-    public void testWritingEmptyLedgerToDisk() {
-        final Ledger ogLedger = mScribeUnderTest.getLedgerLocked(TEST_USER_ID, TEST_PACKAGE);
-        mScribeUnderTest.writeImmediatelyForTesting();
-
-        mScribeUnderTest.loadFromDiskLocked();
-        assertLedgersEqual(ogLedger, mScribeUnderTest.getLedgerLocked(TEST_USER_ID, TEST_PACKAGE));
-    }
-
-    @Test
-    public void testWritingPopulatedLedgerToDisk() {
-        final Ledger ogLedger = mScribeUnderTest.getLedgerLocked(TEST_USER_ID, TEST_PACKAGE);
-        ogLedger.recordTransaction(
-                new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_REWARD | 1, null, 51, 0));
-        ogLedger.recordTransaction(
-                new Ledger.Transaction(1500, 2000,
-                        EconomicPolicy.TYPE_REWARD | 2, "green", 52, -1));
-        ogLedger.recordTransaction(
-                new Ledger.Transaction(2500, 3000, EconomicPolicy.TYPE_REWARD | 3, "blue", 3, 12));
-        mScribeUnderTest.writeImmediatelyForTesting();
-
-        mScribeUnderTest.loadFromDiskLocked();
-        assertLedgersEqual(ogLedger, mScribeUnderTest.getLedgerLocked(TEST_USER_ID, TEST_PACKAGE));
-    }
-
-    @Test
-    public void testWritingMultipleLedgersToDisk() {
-        final SparseArrayMap<String, Ledger> ledgers = new SparseArrayMap<>();
-        final int numUsers = 3;
-        final int numLedgers = 5;
-        for (int u = 0; u < numUsers; ++u) {
-            final int userId = TEST_USER_ID + u;
-            for (int l = 0; l < numLedgers; ++l) {
-                final String pkgName = TEST_PACKAGE + l;
-                addInstalledPackage(userId, pkgName);
-                final Ledger ledger = mScribeUnderTest.getLedgerLocked(userId, pkgName);
-                ledger.recordTransaction(new Ledger.Transaction(
-                        0, 1000L * u + l, EconomicPolicy.TYPE_ACTION | 1, null, -51L * u + l, 50));
-                ledger.recordTransaction(new Ledger.Transaction(
-                        1500L * u + l, 2000L * u + l,
-                        EconomicPolicy.TYPE_REWARD | 2 * u + l, "green" + u + l, 52L * u + l, 0));
-                ledger.recordTransaction(new Ledger.Transaction(
-                        2500L * u + l, 3000L * u + l,
-                        EconomicPolicy.TYPE_REWARD | 3 * u + l, "blue" + u + l, 3L * u + l, 0));
-                ledgers.add(userId, pkgName, ledger);
-            }
-        }
-        mScribeUnderTest.writeImmediatelyForTesting();
-
-        mScribeUnderTest.loadFromDiskLocked();
-        ledgers.forEach((userId, pkgName, ledger)
-                -> assertLedgersEqual(ledger, mScribeUnderTest.getLedgerLocked(userId, pkgName)));
-    }
-
-    @Test
-    public void testDiscardLedgerFromDisk() {
-        final Ledger ogLedger = mScribeUnderTest.getLedgerLocked(TEST_USER_ID, TEST_PACKAGE);
-        ogLedger.recordTransaction(
-                new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_REWARD | 1, null, 51, 1));
-        ogLedger.recordTransaction(
-                new Ledger.Transaction(1500, 2000, EconomicPolicy.TYPE_REWARD | 2, "green", 52, 0));
-        ogLedger.recordTransaction(
-                new Ledger.Transaction(2500, 3000, EconomicPolicy.TYPE_REWARD | 3, "blue", 3, 1));
-        mScribeUnderTest.writeImmediatelyForTesting();
-
-        mScribeUnderTest.loadFromDiskLocked();
-        assertLedgersEqual(ogLedger, mScribeUnderTest.getLedgerLocked(TEST_USER_ID, TEST_PACKAGE));
-
-        mScribeUnderTest.discardLedgerLocked(TEST_USER_ID, TEST_PACKAGE);
-        mScribeUnderTest.writeImmediatelyForTesting();
-
-        // Make sure there's no more saved ledger.
-        mScribeUnderTest.loadFromDiskLocked();
-        assertLedgersEqual(new Ledger(),
-                mScribeUnderTest.getLedgerLocked(TEST_USER_ID, TEST_PACKAGE));
-    }
-
-    @Test
-    public void testLoadingMissingPackageFromDisk() {
-        final String pkgName = TEST_PACKAGE + ".uninstalled";
-        final Ledger ogLedger = mScribeUnderTest.getLedgerLocked(TEST_USER_ID, pkgName);
-        ogLedger.recordTransaction(
-                new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_REGULATION | 1, null, 51, 1));
-        ogLedger.recordTransaction(
-                new Ledger.Transaction(1500, 2000, EconomicPolicy.TYPE_REWARD | 2, "green", 52, 2));
-        ogLedger.recordTransaction(
-                new Ledger.Transaction(2500, 3000, EconomicPolicy.TYPE_ACTION | 3, "blue", -3, 3));
-        mScribeUnderTest.writeImmediatelyForTesting();
-
-        // Package isn't installed, so make sure it's not saved to memory after loading.
-        mScribeUnderTest.loadFromDiskLocked();
-        assertLedgersEqual(new Ledger(), mScribeUnderTest.getLedgerLocked(TEST_USER_ID, pkgName));
-    }
-
-    @Test
-    public void testLoadingMissingUserFromDisk() {
-        final int userId = TEST_USER_ID + 1;
-        final Ledger ogLedger = mScribeUnderTest.getLedgerLocked(userId, TEST_PACKAGE);
-        ogLedger.recordTransaction(
-                new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_REWARD | 1, null, 51, 0));
-        ogLedger.recordTransaction(
-                new Ledger.Transaction(1500, 2000, EconomicPolicy.TYPE_REWARD | 2, "green", 52, 1));
-        ogLedger.recordTransaction(
-                new Ledger.Transaction(2500, 3000,
-                        EconomicPolicy.TYPE_REGULATION | 3, "blue", 3, 3));
-        mScribeUnderTest.writeImmediatelyForTesting();
-
-        // User doesn't show up with any packages, so make sure nothing is saved after loading.
-        mScribeUnderTest.loadFromDiskLocked();
-        assertLedgersEqual(new Ledger(), mScribeUnderTest.getLedgerLocked(userId, TEST_PACKAGE));
-    }
-
-    @Test
-    public void testChangingConsumable() {
-        assertEquals(0, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
-        assertEquals(0, mScribeUnderTest.getRemainingConsumableCakesLocked());
-
-        // Limit increased, so remaining value should be adjusted as well
-        mScribeUnderTest.setConsumptionLimitLocked(1000);
-        assertEquals(1000, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
-        assertEquals(1000, mScribeUnderTest.getRemainingConsumableCakesLocked());
-
-        // Limit decreased below remaining, so remaining value should be adjusted as well
-        mScribeUnderTest.setConsumptionLimitLocked(500);
-        assertEquals(500, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
-        assertEquals(500, mScribeUnderTest.getRemainingConsumableCakesLocked());
-
-        mScribeUnderTest.adjustRemainingConsumableCakesLocked(-100);
-        assertEquals(500, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
-        assertEquals(400, mScribeUnderTest.getRemainingConsumableCakesLocked());
-
-        // Limit increased, so remaining value should be adjusted by the difference as well
-        mScribeUnderTest.setConsumptionLimitLocked(1000);
-        assertEquals(1000, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
-        assertEquals(900, mScribeUnderTest.getRemainingConsumableCakesLocked());
-
-
-        // Limit decreased, but above remaining, so remaining value should left alone
-        mScribeUnderTest.setConsumptionLimitLocked(950);
-        assertEquals(950, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
-        assertEquals(900, mScribeUnderTest.getRemainingConsumableCakesLocked());
-    }
-
-    private void assertReportListsEqual(List<Analyst.Report> expected,
-            List<Analyst.Report> actual) {
-        if (expected == null) {
-            assertNull(actual);
-            return;
-        }
-        assertNotNull(actual);
-        assertEquals(expected.size(), actual.size());
-        for (int i = 0; i < expected.size(); ++i) {
-            Analyst.Report eReport = expected.get(i);
-            Analyst.Report aReport = actual.get(i);
-            if (eReport == null) {
-                assertNull(aReport);
-                continue;
-            }
-            assertNotNull(aReport);
-            assertEquals("Reports #" + i + " cumulativeBatteryDischarge are not equal",
-                    eReport.cumulativeBatteryDischarge, aReport.cumulativeBatteryDischarge);
-            assertEquals("Reports #" + i + " currentBatteryLevel are not equal",
-                    eReport.currentBatteryLevel, aReport.currentBatteryLevel);
-            assertEquals("Reports #" + i + " cumulativeProfit are not equal",
-                    eReport.cumulativeProfit, aReport.cumulativeProfit);
-            assertEquals("Reports #" + i + " numProfitableActions are not equal",
-                    eReport.numProfitableActions, aReport.numProfitableActions);
-            assertEquals("Reports #" + i + " cumulativeLoss are not equal",
-                    eReport.cumulativeLoss, aReport.cumulativeLoss);
-            assertEquals("Reports #" + i + " numUnprofitableActions are not equal",
-                    eReport.numUnprofitableActions, aReport.numUnprofitableActions);
-            assertEquals("Reports #" + i + " cumulativeRewards are not equal",
-                    eReport.cumulativeRewards, aReport.cumulativeRewards);
-            assertEquals("Reports #" + i + " numRewards are not equal",
-                    eReport.numRewards, aReport.numRewards);
-            assertEquals("Reports #" + i + " cumulativePositiveRegulations are not equal",
-                    eReport.cumulativePositiveRegulations, aReport.cumulativePositiveRegulations);
-            assertEquals("Reports #" + i + " numPositiveRegulations are not equal",
-                    eReport.numPositiveRegulations, aReport.numPositiveRegulations);
-            assertEquals("Reports #" + i + " cumulativeNegativeRegulations are not equal",
-                    eReport.cumulativeNegativeRegulations, aReport.cumulativeNegativeRegulations);
-            assertEquals("Reports #" + i + " numNegativeRegulations are not equal",
-                    eReport.numNegativeRegulations, aReport.numNegativeRegulations);
-            assertEquals("Reports #" + i + " screenOffDurationMs are not equal",
-                    eReport.screenOffDurationMs, aReport.screenOffDurationMs);
-            assertEquals("Reports #" + i + " screenOffDischargeMah are not equal",
-                    eReport.screenOffDischargeMah, aReport.screenOffDischargeMah);
-        }
-    }
-
-    private void addInstalledPackage(int userId, String pkgName) {
-        PackageInfo pkgInfo = new PackageInfo();
-        pkgInfo.packageName = pkgName;
-        ApplicationInfo applicationInfo = new ApplicationInfo();
-        applicationInfo.uid = UserHandle.getUid(userId, Math.abs(pkgName.hashCode()));
-        pkgInfo.applicationInfo = applicationInfo;
-        mInstalledPackages.add(userId, pkgName, new InstalledPackageInfo(getContext(), userId,
-                pkgInfo));
-    }
-}
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/TareTestUtils.java b/services/tests/mockingservicestests/src/com/android/server/tare/TareTestUtils.java
deleted file mode 100644
index 1e4684b..0000000
--- a/services/tests/mockingservicestests/src/com/android/server/tare/TareTestUtils.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-import android.util.SparseLongArray;
-
-import java.util.List;
-
-public class TareTestUtils {
-    static void assertLedgersEqual(Ledger expected, Ledger actual) {
-        if (expected == null) {
-            assertNull(actual);
-            return;
-        }
-        assertNotNull(actual);
-        assertEquals(expected.getCurrentBalance(), actual.getCurrentBalance());
-
-        List<Ledger.Transaction> expectedTransactions = expected.getTransactions();
-        List<Ledger.Transaction> actualTransactions = actual.getTransactions();
-        assertEquals(expectedTransactions.size(), actualTransactions.size());
-        for (int i = 0; i < expectedTransactions.size(); ++i) {
-            assertTransactionsEqual(expectedTransactions.get(i), actualTransactions.get(i));
-        }
-
-        List<Ledger.RewardBucket> expectedRewardBuckets = expected.getRewardBuckets();
-        List<Ledger.RewardBucket> actualRewardBuckets = actual.getRewardBuckets();
-        assertEquals(expectedRewardBuckets.size(), actualRewardBuckets.size());
-        for (int i = 0; i < expectedRewardBuckets.size(); ++i) {
-            assertRewardBucketsEqual(expectedRewardBuckets.get(i), actualRewardBuckets.get(i));
-        }
-    }
-
-
-    static void assertSparseLongArraysEqual(SparseLongArray expected, SparseLongArray actual) {
-        if (expected == null) {
-            assertNull(actual);
-            return;
-        }
-        assertNotNull(actual);
-        final int size = expected.size();
-        assertEquals(size, actual.size());
-        for (int i = 0; i < size; ++i) {
-            assertEquals(expected.keyAt(i), actual.keyAt(i));
-            assertEquals(expected.valueAt(i), actual.valueAt(i));
-        }
-    }
-
-    static void assertRewardBucketsEqual(Ledger.RewardBucket expected, Ledger.RewardBucket actual) {
-        if (expected == null) {
-            assertNull(actual);
-            return;
-        }
-        assertNotNull(actual);
-        assertEquals(expected.startTimeMs, actual.startTimeMs);
-        assertSparseLongArraysEqual(expected.cumulativeDelta, actual.cumulativeDelta);
-    }
-
-    static void assertTransactionsEqual(Ledger.Transaction expected, Ledger.Transaction actual) {
-        if (expected == null) {
-            assertNull(actual);
-            return;
-        }
-        assertNotNull(actual);
-        assertEquals(expected.startTimeMs, actual.startTimeMs);
-        assertEquals(expected.endTimeMs, actual.endTimeMs);
-        assertEquals(expected.eventId, actual.eventId);
-        assertEquals(expected.tag, actual.tag);
-        assertEquals(expected.delta, actual.delta);
-        assertEquals(expected.ctp, actual.ctp);
-    }
-}
diff --git a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
index b415682..0532e04 100644
--- a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
@@ -55,6 +55,7 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -63,8 +64,7 @@
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.provider.Settings;
-import android.security.Authorization;
-import android.security.authorization.IKeystoreAuthorization;
+import android.security.KeyStoreAuthorization;
 import android.service.trust.TrustAgentService;
 import android.testing.TestableContext;
 import android.view.IWindowManager;
@@ -96,7 +96,6 @@
     @Rule
     public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
             .spyStatic(ActivityManager.class)
-            .spyStatic(Authorization.class)
             .mockStatic(ServiceManager.class)
             .mockStatic(WindowManagerGlobal.class)
             .build();
@@ -126,14 +125,13 @@
     private @Mock DevicePolicyManager mDevicePolicyManager;
     private @Mock FaceManager mFaceManager;
     private @Mock FingerprintManager mFingerprintManager;
-    private @Mock IKeystoreAuthorization mKeystoreAuthorization;
+    private @Mock KeyStoreAuthorization mKeyStoreAuthorization;
     private @Mock LockPatternUtils mLockPatternUtils;
     private @Mock PackageManager mPackageManager;
     private @Mock UserManager mUserManager;
     private @Mock IWindowManager mWindowManager;
 
     private HandlerThread mHandlerThread;
-    private TrustManagerService.Injector mInjector;
     private TrustManagerService mService;
     private ITrustManager mTrustManager;
 
@@ -145,8 +143,6 @@
         when(mFaceManager.getSensorProperties()).thenReturn(List.of());
         when(mFingerprintManager.getSensorProperties()).thenReturn(List.of());
 
-        doReturn(mKeystoreAuthorization).when(() -> Authorization.getService());
-
         when(mLockPatternUtils.getDevicePolicyManager()).thenReturn(mDevicePolicyManager);
         when(mLockPatternUtils.isSecure(TEST_USER_ID)).thenReturn(true);
         when(mLockPatternUtils.getKnownTrustAgents(TEST_USER_ID)).thenReturn(mKnownTrustAgents);
@@ -193,8 +189,7 @@
 
         mHandlerThread = new HandlerThread("handler");
         mHandlerThread.start();
-        mInjector = new TrustManagerService.Injector(mLockPatternUtils, mHandlerThread.getLooper());
-        mService = new TrustManagerService(mMockContext, mInjector);
+        mService = new TrustManagerService(mMockContext, new MockInjector(mMockContext));
 
         // Get the ITrustManager from the new TrustManagerService.
         mService.onStart();
@@ -204,6 +199,27 @@
         mTrustManager = ITrustManager.Stub.asInterface(binderArgumentCaptor.getValue());
     }
 
+    private class MockInjector extends TrustManagerService.Injector {
+        MockInjector(Context context) {
+            super(context);
+        }
+
+        @Override
+        LockPatternUtils getLockPatternUtils() {
+            return mLockPatternUtils;
+        }
+
+        @Override
+        KeyStoreAuthorization getKeyStoreAuthorization() {
+            return mKeyStoreAuthorization;
+        }
+
+        @Override
+        Looper getLooper() {
+            return mHandlerThread.getLooper();
+        }
+    }
+
     @After
     public void tearDown() {
         LocalServices.removeServiceForTest(SystemServiceManager.class);
@@ -371,14 +387,14 @@
 
         when(mWindowManager.isKeyguardLocked()).thenReturn(false);
         mTrustManager.reportKeyguardShowingChanged();
-        verify(mKeystoreAuthorization).onDeviceUnlocked(PARENT_USER_ID, null);
-        verify(mKeystoreAuthorization).onDeviceUnlocked(PROFILE_USER_ID, null);
+        verify(mKeyStoreAuthorization).onDeviceUnlocked(PARENT_USER_ID, null);
+        verify(mKeyStoreAuthorization).onDeviceUnlocked(PROFILE_USER_ID, null);
 
         when(mWindowManager.isKeyguardLocked()).thenReturn(true);
         mTrustManager.reportKeyguardShowingChanged();
-        verify(mKeystoreAuthorization)
+        verify(mKeyStoreAuthorization)
                 .onDeviceLocked(eq(PARENT_USER_ID), eq(PARENT_BIOMETRIC_SIDS), eq(false));
-        verify(mKeystoreAuthorization)
+        verify(mKeyStoreAuthorization)
                 .onDeviceLocked(eq(PROFILE_USER_ID), eq(PARENT_BIOMETRIC_SIDS), eq(false));
     }
 
@@ -392,10 +408,10 @@
         setupMocksForProfile(/* unifiedChallenge= */ false);
 
         mTrustManager.setDeviceLockedForUser(PROFILE_USER_ID, false);
-        verify(mKeystoreAuthorization).onDeviceUnlocked(PROFILE_USER_ID, null);
+        verify(mKeyStoreAuthorization).onDeviceUnlocked(PROFILE_USER_ID, null);
 
         mTrustManager.setDeviceLockedForUser(PROFILE_USER_ID, true);
-        verify(mKeystoreAuthorization)
+        verify(mKeyStoreAuthorization)
                 .onDeviceLocked(eq(PROFILE_USER_ID), eq(PROFILE_BIOMETRIC_SIDS), eq(false));
     }
 
@@ -572,11 +588,11 @@
     private void verifyWeakUnlockValue(boolean expectedWeakUnlockEnabled) throws Exception {
         when(mWindowManager.isKeyguardLocked()).thenReturn(false);
         mTrustManager.reportKeyguardShowingChanged();
-        verify(mKeystoreAuthorization).onDeviceUnlocked(TEST_USER_ID, null);
+        verify(mKeyStoreAuthorization).onDeviceUnlocked(TEST_USER_ID, null);
 
         when(mWindowManager.isKeyguardLocked()).thenReturn(true);
         mTrustManager.reportKeyguardShowingChanged();
-        verify(mKeystoreAuthorization).onDeviceLocked(eq(TEST_USER_ID), any(),
+        verify(mKeyStoreAuthorization).onDeviceLocked(eq(TEST_USER_ID), any(),
                 eq(expectedWeakUnlockEnabled));
     }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperCropperTest.java b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperCropperTest.java
index 7ecc7fd..29f3720 100644
--- a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperCropperTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperCropperTest.java
@@ -235,12 +235,11 @@
         int expectedWidth = (int) (displaySize.x * (1 + WallpaperCropper.MAX_PARALLAX));
         Point expectedCropSize = new Point(expectedWidth, 1000);
         for (int mode: ALL_MODES) {
-            assertThat(WallpaperCropper.getAdjustedCrop(
-                    crop, bitmapSize, displaySize, true, false, mode))
-                    .isEqualTo(leftOf(crop, expectedCropSize));
-            assertThat(WallpaperCropper.getAdjustedCrop(
-                    crop, bitmapSize, displaySize, true, true, mode))
-                    .isEqualTo(rightOf(crop, expectedCropSize));
+            for (boolean rtl: List.of(false, true)) {
+                assertThat(WallpaperCropper.getAdjustedCrop(
+                        crop, bitmapSize, displaySize, true, rtl, mode))
+                        .isEqualTo(centerOf(crop, expectedCropSize));
+            }
         }
     }
 
@@ -362,11 +361,13 @@
     }
 
     /**
-     * Test that {@link WallpaperCropper#getCrop} follows a simple centre-align strategy when
-     * no suggested crops are provided.
+     * Test that {@link WallpaperCropper#getCrop} uses the full image when no crops are provided.
+     * If the image has more width/height ratio than the screen, keep that width for parallax up
+     * to {@link WallpaperCropper#MAX_PARALLAX}. If the crop has less width/height ratio, remove the
+     * surplus height, on both sides to keep the wallpaper centered.
      */
     @Test
-    public void testGetCrop_noSuggestedCrops_centersWallpaper() {
+    public void testGetCrop_noSuggestedCrops() {
         setUpWithDisplays(STANDARD_DISPLAY);
         Point bitmapSize = new Point(800, 1000);
         Rect bitmapRect = new Rect(0, 0, bitmapSize.x, bitmapSize.y);
@@ -374,9 +375,11 @@
 
         List<Point> displaySizes = List.of(
                 new Point(500, 1000),
+                new Point(200, 1000),
                 new Point(1000, 500));
         List<Point> expectedCropSizes = List.of(
-                new Point(500, 1000),
+                new Point(Math.min(800, (int) (500 * (1 + WallpaperCropper.MAX_PARALLAX))), 1000),
+                new Point(Math.min(800, (int) (200 * (1 + WallpaperCropper.MAX_PARALLAX))), 1000),
                 new Point(800, 400));
 
         for (int i = 0; i < displaySizes.size(); i++) {
@@ -450,7 +453,8 @@
     /**
      * Test that {@link WallpaperCropper#getCrop}, when asked for a folded crop with a suggested
      * crop only for the relative unfolded orientation, creates the folded crop at the center of the
-     * unfolded crop, by removing content on two sides to match the folded screen dimensions.
+     * unfolded crop, by removing content on two sides to match the folded screen dimensions, and
+     * then adds some width for parallax.
      * <p>
      * To simplify, in this test case all crops have the same size as the display (no zoom)
      * and are at the center of the image.
@@ -468,6 +472,7 @@
             int unfoldedTwo = getRotatedOrientation(unfoldedOne);
             Rect unfoldedCropOne = centerOf(bitmapRect, mDisplaySizes.get(unfoldedOne));
             Rect unfoldedCropTwo = centerOf(bitmapRect, mDisplaySizes.get(unfoldedTwo));
+            List<Rect> unfoldedCrops = List.of(unfoldedCropOne, unfoldedCropTwo);
             SparseArray<Rect> suggestedCrops = new SparseArray<>();
             suggestedCrops.put(unfoldedOne, unfoldedCropOne);
             suggestedCrops.put(unfoldedTwo, unfoldedCropTwo);
@@ -476,15 +481,28 @@
             int foldedTwo = getFoldedOrientation(unfoldedTwo);
             Point foldedDisplayOne = mDisplaySizes.get(foldedOne);
             Point foldedDisplayTwo = mDisplaySizes.get(foldedTwo);
+            List<Point> foldedDisplays = List.of(foldedDisplayOne, foldedDisplayTwo);
 
             for (boolean rtl : List.of(false, true)) {
-                assertThat(mWallpaperCropper.getCrop(
-                        foldedDisplayOne, bitmapSize, suggestedCrops, rtl))
-                        .isEqualTo(centerOf(unfoldedCropOne, foldedDisplayOne));
+                for (int i = 0; i < 2; i++) {
+                    Rect unfoldedCrop = unfoldedCrops.get(i);
+                    Point foldedDisplay = foldedDisplays.get(i);
+                    Rect expectedCrop = centerOf(unfoldedCrop, foldedDisplay);
+                    int maxParallax = (int) (WallpaperCropper.MAX_PARALLAX * unfoldedCrop.width());
 
-                assertThat(mWallpaperCropper.getCrop(
-                        foldedDisplayTwo, bitmapSize, suggestedCrops, rtl))
-                        .isEqualTo(centerOf(unfoldedCropTwo, foldedDisplayTwo));
+                    // the expected behaviour is that we add width for parallax until we reach
+                    // either MAX_PARALLAX or the edge of the crop for the unfolded screen.
+                    if (rtl) {
+                        expectedCrop.left = Math.max(
+                                unfoldedCrop.left, expectedCrop.left - maxParallax);
+                    } else {
+                        expectedCrop.right = Math.min(
+                                unfoldedCrop.right, unfoldedCrop.right + maxParallax);
+                    }
+                    assertThat(mWallpaperCropper.getCrop(
+                            foldedDisplay, bitmapSize, suggestedCrops, rtl))
+                            .isEqualTo(expectedCrop);
+                }
             }
         }
     }
diff --git a/services/tests/powerservicetests/AndroidManifest.xml b/services/tests/powerservicetests/AndroidManifest.xml
index 26d9eec..f7eb4ad 100644
--- a/services/tests/powerservicetests/AndroidManifest.xml
+++ b/services/tests/powerservicetests/AndroidManifest.xml
@@ -24,6 +24,7 @@
     <uses-permission android:name="android.permission.READ_DEVICE_CONFIG"/>
     <uses-permission android:name="android.permission.READ_DREAM_STATE"/>
     <uses-permission android:name="android.permission.READ_DREAM_SUPPRESSION"/>
+    <uses-permission android:name="android.permission.SCREEN_TIMEOUT_OVERRIDE"/>
     <uses-permission android:name="android.permission.STATUS_BAR_SERVICE"/>
     <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS"/>
     <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"/>
diff --git a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
index 52f28e9..67409a4 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -32,6 +32,7 @@
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -492,6 +493,12 @@
                 mIsBatterySaverSupported);
     }
 
+    private void setScreenTimeoutOverrideConfig(int screenTimeoutOverrideConfig) {
+        when(mResourcesSpy.getInteger(
+                com.android.internal.R.integer.config_screenTimeoutOverride))
+                .thenReturn(screenTimeoutOverrideConfig);
+    }
+
     @Test
     public void testCreateService_initializesNativeServiceAndSetsPowerModes() {
         PowerManagerService service = createService();
@@ -2941,6 +2948,299 @@
         assertThat(wakeLock.mDisabled).isFalse();
     }
 
+    @Test
+    public void testScreenTimeoutOverrideWakeLock() {
+        mSetFlagsRule.enableFlags(com.android.server.power.feature.flags
+                .Flags.FLAG_ENABLE_EARLY_SCREEN_TIMEOUT_DETECTOR);
+
+        setAttentiveTimeout(30000);
+        setScreenTimeoutOverrideConfig(10000);
+
+        createService();
+        startSystem();
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+        // Grab a wakelock
+        final String tag = "wakelock1";
+        final String packageName = "pkg.name";
+        final IBinder token = new Binder();
+        final int flags = PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK;
+        mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
+                null /* callback */);
+
+        // Early screen off while acquired the wake lock.
+        advanceTime(10000);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+
+        // Should not affect anything after release the wake lock.
+        mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+    }
+
+    @Test
+    public void testScreenTimeoutOverrideWakeLockOnFeatureDisable() {
+        // Feature flag is not enabled
+        mSetFlagsRule.disableFlags(com.android.server.power.feature.flags
+                .Flags.FLAG_ENABLE_EARLY_SCREEN_TIMEOUT_DETECTOR);
+
+        setAttentiveTimeout(30000);
+        setScreenTimeoutOverrideConfig(10000);
+
+        createService();
+        startSystem();
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+        // Grab a wakelock
+        final String tag = "wakelock1";
+        final String packageName = "pkg.name";
+        final IBinder token = new Binder();
+        final int flags = PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK;
+        try {
+            mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
+                    null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
+                    null /* callback */);
+        } catch (IllegalArgumentException e) {
+            return;
+        }
+
+        fail("Have to throw a IllegalArgumentException when feature is not enabled.");
+    }
+
+    @Test
+    public void testScreenTimeoutOverrideWakeLockAcquiredAfterTimeout() {
+        mSetFlagsRule.enableFlags(com.android.server.power.feature.flags
+                .Flags.FLAG_ENABLE_EARLY_SCREEN_TIMEOUT_DETECTOR);
+
+        setAttentiveTimeout(30000);
+        setScreenTimeoutOverrideConfig(10000);
+
+        createService();
+        startSystem();
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+        advanceTime(10000);
+
+        // Grab a wakelock
+        final String tag = "wakelock1";
+        final String packageName = "pkg.name";
+        final IBinder token = new Binder();
+        final int flags = PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK;
+        mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
+                null /* callback */);
+
+        // Early screen off while acquired the wake lock.
+        advanceTime(0);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+
+        // Should not affect anything after release the wake lock.
+        mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+    }
+
+    @Test
+    public void testScreenTimeoutOverrideWakeLockAcquiredAfterSleep() {
+        mSetFlagsRule.enableFlags(com.android.server.power.feature.flags
+                .Flags.FLAG_ENABLE_EARLY_SCREEN_TIMEOUT_DETECTOR);
+
+        setAttentiveTimeout(30000);
+        setScreenTimeoutOverrideConfig(10000);
+
+        createService();
+        startSystem();
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        advanceTime(30000);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+
+        // Grab a wakelock
+        final String tag = "wakelock1";
+        final String packageName = "pkg.name";
+        final IBinder token = new Binder();
+        final int flags = PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK;
+        mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
+                null /* callback */);
+
+        // Keep screen off and the wake lock won't be acquired when screen off.
+        advanceTime(0);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+
+        // Verify if the wake lock is still valid.
+        forceAwake();
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        advanceTime(10000);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+        // Should not affect anything after release the wake lock.
+        mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+    }
+
+    @Test
+    public void testScreenTimeoutOverrideWakeLockUserActivity() {
+        mSetFlagsRule.enableFlags(com.android.server.power.feature.flags
+                .Flags.FLAG_ENABLE_EARLY_SCREEN_TIMEOUT_DETECTOR);
+
+        final DisplayInfo info = new DisplayInfo();
+        info.displayGroupId = Display.DEFAULT_DISPLAY_GROUP;
+        when(mDisplayManagerInternalMock.getDisplayInfo(Display.DEFAULT_DISPLAY)).thenReturn(info);
+
+        setAttentiveTimeout(30000);
+        setScreenTimeoutOverrideConfig(10000);
+
+        createService();
+        startSystem();
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+        // Grab a wakelock
+        final String tag = "wakelock1";
+        final String packageName = "pkg.name";
+        final IBinder token = new Binder();
+        final int flags = PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK;
+        mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
+                null /* callback */);
+
+        // Still keep awake when not timeout.
+        advanceTime(500);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        mService.getBinderServiceInstance().userActivity(Display.DEFAULT_DISPLAY, mClock.now(),
+                PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
+
+        // screen timeout override wake lock should be released after user activity.
+        advanceTime(10000);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.findWakeLockLocked(token)).isEqualTo(null);
+
+        // Should not affect anything after release the wake lock.
+        mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+    }
+
+    @Test
+    public void testScreenTimeoutOverrideWakeLockFullWakeLock() {
+        mSetFlagsRule.enableFlags(com.android.server.power.feature.flags
+                .Flags.FLAG_ENABLE_EARLY_SCREEN_TIMEOUT_DETECTOR);
+
+        setAttentiveTimeout(30000);
+        setScreenTimeoutOverrideConfig(10000);
+
+        createService();
+        startSystem();
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+        // Grab a wakelock
+        final String tag1 = "wakelock1";
+        final String packageName1 = "pkg.name";
+        final IBinder token1 = new Binder();
+        final int flags = PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK;
+        mService.getBinderServiceInstance().acquireWakeLock(token1, flags, tag1, packageName1,
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
+                null /* callback */);
+
+        advanceTime(500);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+        // Grab a full wake lock
+        final String tag2 = "wakelock2";
+        final String packageName2 = "pkg2.name";
+        final IBinder token2 = new Binder();
+        final int flags2 = PowerManager.FULL_WAKE_LOCK;
+        mService.getBinderServiceInstance().acquireWakeLock(token2, flags2, tag2, packageName2,
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
+                null /* callback */);
+
+        // wake lock should be released when another full wake lock acquired.
+        advanceTime(10000);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+        assertThat(mService.findWakeLockLocked(token1)).isEqualTo(null);
+
+        // Should not affect anything after release the wake locks.
+        mService.getBinderServiceInstance().releaseWakeLock(token1, 0 /* flags */);
+        mService.getBinderServiceInstance().releaseWakeLock(token2, 0 /* flags */);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+    }
+
+    @Test
+    public void testScreenTimeoutOverrideWakeLockMultiClients() {
+        mSetFlagsRule.enableFlags(com.android.server.power.feature.flags
+                .Flags.FLAG_ENABLE_EARLY_SCREEN_TIMEOUT_DETECTOR);
+
+        setAttentiveTimeout(30000);
+        setScreenTimeoutOverrideConfig(10000);
+
+        createService();
+        startSystem();
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+        // Grab a wakelock
+        final String tag1 = "wakelock1";
+        final String packageName1 = "pkg.name";
+        final IBinder token1 = new Binder();
+        final int flags = PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK;
+        mService.getBinderServiceInstance().acquireWakeLock(token1, flags, tag1, packageName1,
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
+                null /* callback */);
+
+        // Grab a full wake lock
+        final String tag2 = "wakelock2";
+        final String packageName2 = "pkg2.name";
+        final IBinder token2 = new Binder();
+        final int flags2 = PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK;
+        mService.getBinderServiceInstance().acquireWakeLock(token2, flags2, tag2, packageName2,
+                null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
+                null /* callback */);
+
+        advanceTime(500);
+        // Release the first lock to ensure the second lock is still valid.
+        mService.getBinderServiceInstance().releaseWakeLock(token1, 0 /* flags */);
+        advanceTime(10000);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+
+        // Should not affect anything after release the wake locks.
+        mService.getBinderServiceInstance().releaseWakeLock(token2, 0 /* flags */);
+        assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+    }
+
+    @Test
+    public void testGetScreenOffTimeoutOverrideApi() {
+        mSetFlagsRule.enableFlags(com.android.server.power.feature.flags
+                .Flags.FLAG_ENABLE_EARLY_SCREEN_TIMEOUT_DETECTOR);
+
+        final int screenTimeout = 30000;
+        final int screenDimTimeout = 7000;
+        final int screenTimeoutOverride = 10000;
+        setScreenTimeoutOverrideConfig(screenTimeoutOverride);
+
+        createService();
+        startSystem();
+
+        final String tag = "wakelock";
+        final String packageName = "pkg.name";
+        final IBinder token = new Binder();
+        final int flags = PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK;
+
+        // define cases as {isFaceDown, isTimeoutOverride, expectedTimeout}
+        final int[][] testCases = {{0, 0, screenTimeout}, {0, 1, screenTimeoutOverride},
+                {1, 0, screenDimTimeout}, {1, 1, screenDimTimeout}};
+
+        for (int[] expect : testCases) {
+            mService.mIsFaceDown = expect[0] == 1;
+            final boolean acquireWakeLock = expect[1] == 1;
+            if (acquireWakeLock) {
+                mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
+                        null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
+                        null /* callback */);
+            }
+            assertThat(mService.getScreenOffTimeoutOverrideLocked(screenTimeout, screenDimTimeout))
+                    .isEqualTo(expect[2]);
+            if (acquireWakeLock) {
+                mService.getBinderServiceInstance().releaseWakeLock(token, 0);
+            }
+        }
+    }
+
     private void setCachedUidProcState(int uid) {
         mService.updateUidProcStateInternal(uid, PROCESS_STATE_TOP_SLEEPING);
     }
diff --git a/services/tests/selinux/Android.bp b/services/tests/selinux/Android.bp
new file mode 100644
index 0000000..f387238
--- /dev/null
+++ b/services/tests/selinux/Android.bp
@@ -0,0 +1,60 @@
+// 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 {
+    default_team: "trendy_team_foundation_security_rust_pkvm_",
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+java_defaults {
+    name: "mockito_extended",
+    static_libs: [
+        "mockito-target-extended-minus-junit4",
+    ],
+    jni_libs: [
+        "libdexmakerjvmtiagent",
+        "libstaticjvmtiagent",
+    ],
+}
+
+android_test {
+    name: "SelinuxFrameworksTests",
+    srcs: [
+        "src/**/*.java",
+    ],
+    defaults: [
+        "mockito_extended",
+    ],
+    libs: [
+        "android.test.base",
+        "android.test.mock",
+        "android.test.runner",
+        "servicestests-core-utils",
+    ],
+    static_libs: [
+        "androidx.test.core",
+        "androidx.test.ext.junit",
+        "androidx.test.ext.truth",
+        "androidx.test.runner",
+        "services.core",
+    ],
+    test_suites: [
+        "device-tests",
+    ],
+}
diff --git a/services/tests/selinux/AndroidManifest.xml b/services/tests/selinux/AndroidManifest.xml
new file mode 100644
index 0000000..9273795
--- /dev/null
+++ b/services/tests/selinux/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+     package="com.android.frameworks.selinuxtests">
+
+     <application android:debuggable="true">
+          <uses-library android:name="android.test.runner" />
+     </application>
+
+     <instrumentation
+          android:name="androidx.test.runner.AndroidJUnitRunner"
+          android:targetPackage="com.android.frameworks.selinuxtests"
+          android:label="Selinux Frameworks Tests" />
+</manifest>
\ No newline at end of file
diff --git a/services/tests/selinux/AndroidTest.xml b/services/tests/selinux/AndroidTest.xml
new file mode 100644
index 0000000..16d8e07
--- /dev/null
+++ b/services/tests/selinux/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs Selinux Frameworks Tests.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-instrumentation" />
+
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="install-arg" value="-t" />
+        <option name="test-file-name" value="SelinuxFrameworksTests.apk" />
+    </target_preparer>
+
+    <option name="test-tag" value="SelinuxFrameworksTests" />
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.frameworks.selinuxtests" />
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/services/tests/mockingservicestests/src/com/android/server/selinux/OWNERS b/services/tests/selinux/OWNERS
similarity index 100%
rename from services/tests/mockingservicestests/src/com/android/server/selinux/OWNERS
rename to services/tests/selinux/OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/selinux/RateLimiterTest.java b/services/tests/selinux/src/com/android/server/selinux/RateLimiterTest.java
similarity index 100%
rename from services/tests/mockingservicestests/src/com/android/server/selinux/RateLimiterTest.java
rename to services/tests/selinux/src/com/android/server/selinux/RateLimiterTest.java
diff --git a/services/tests/mockingservicestests/src/com/android/server/selinux/SelinuxAuditLogsBuilderTest.java b/services/tests/selinux/src/com/android/server/selinux/SelinuxAuditLogsBuilderTest.java
similarity index 100%
rename from services/tests/mockingservicestests/src/com/android/server/selinux/SelinuxAuditLogsBuilderTest.java
rename to services/tests/selinux/src/com/android/server/selinux/SelinuxAuditLogsBuilderTest.java
diff --git a/services/tests/mockingservicestests/src/com/android/server/selinux/SelinuxAuditLogsCollectorTest.java b/services/tests/selinux/src/com/android/server/selinux/SelinuxAuditLogsCollectorTest.java
similarity index 99%
rename from services/tests/mockingservicestests/src/com/android/server/selinux/SelinuxAuditLogsCollectorTest.java
rename to services/tests/selinux/src/com/android/server/selinux/SelinuxAuditLogsCollectorTest.java
index 9758ea5..4a70ad3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/selinux/SelinuxAuditLogsCollectorTest.java
+++ b/services/tests/selinux/src/com/android/server/selinux/SelinuxAuditLogsCollectorTest.java
@@ -69,8 +69,7 @@
         // Ignore what was written in the event logs by previous tests.
         mSelinuxAutidLogsCollector.mLastWrite = Instant.now();
 
-        mMockitoSession =
-                mockitoSession().initMocks(this).mockStatic(FrameworkStatsLog.class).startMocking();
+        mMockitoSession = mockitoSession().mockStatic(FrameworkStatsLog.class).startMocking();
     }
 
     @After
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index 9d32ed8..1bf9a9d 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -25,6 +25,7 @@
 
 import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
+import static com.android.server.accessibility.AccessibilityManagerService.ACTION_LAUNCH_HEARING_DEVICES_DIALOG;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -771,6 +772,7 @@
 
     @SmallTest
     @Test
+    @RequiresFlagsDisabled(com.android.systemui.Flags.FLAG_HEARING_AIDS_QS_TILE_DIALOG)
     public void testPerformAccessibilityShortcut_hearingAids_startActivityWithExpectedComponent() {
         final AccessibilityUserState userState = mA11yms.mUserStates.get(
                 mA11yms.getCurrentUserIdLocked());
@@ -786,6 +788,27 @@
                 ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
     }
 
+    @SmallTest
+    @Test
+    @RequiresFlagsEnabled(com.android.systemui.Flags.FLAG_HEARING_AIDS_QS_TILE_DIALOG)
+    public void testPerformAccessibilityShortcut_hearingAids_sendExpectedBroadcast() {
+        final AccessibilityUserState userState = mA11yms.mUserStates.get(
+                mA11yms.getCurrentUserIdLocked());
+        mockManageAccessibilityGranted(mTestableContext);
+        userState.mAccessibilityShortcutKeyTargets.add(
+                ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
+
+        mA11yms.performAccessibilityShortcut(
+                ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
+        mTestableLooper.processAllMessages();
+
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mTestableContext.getMockContext()).sendBroadcastAsUser(intentCaptor.capture(),
+                eq(UserHandle.SYSTEM));
+        assertThat(intentCaptor.getValue().getAction()).isEqualTo(
+                ACTION_LAUNCH_HEARING_DEVICES_DIALOG);
+    }
+
     @Test
     public void testPackagesForceStopped_disablesRelevantService() {
         final AccessibilityServiceInfo info_a = new AccessibilityServiceInfo();
@@ -1618,6 +1641,11 @@
         }
 
         @Override
+        public void sendBroadcastAsUser(Intent intent, UserHandle user) {
+            mMockContext.sendBroadcastAsUser(intent, user);
+        }
+
+        @Override
         public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
                 IntentFilter filter, String broadcastPermission, Handler scheduler) {
             Iterator<String> actions = filter.actionsIterator();
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index e0a99b0..e189098 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -3156,6 +3156,39 @@
     }
 
     @SmallTest
+    public void testAccountRemovedBroadcastMarkedAccountAsVisibleTwice() throws Exception {
+        unlockSystemUser();
+
+        HashMap<String, Integer> visibility = new HashMap<>();
+        visibility.put("testpackage1", AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
+
+        addAccountRemovedReceiver("testpackage1");
+        mAms.registerAccountListener(
+                new String [] {AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1},
+                "testpackage1");
+        mAms.addAccountExplicitlyWithVisibility(
+                AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
+                /* password= */ "p11",
+                /* extras= */ null,
+                visibility,
+                /* callerPackage= */ null);
+
+        updateBroadcastCounters(2);
+        assertEquals(mVisibleAccountsChangedBroadcasts, 1);
+        assertEquals(mLoginAccountsChangedBroadcasts, 1);
+        assertEquals(mAccountRemovedBroadcasts, 0);
+
+        mAms.setAccountVisibility(AccountManagerServiceTestFixtures.ACCOUNT_SUCCESS,
+                "testpackage1",
+                AccountManager.VISIBILITY_VISIBLE);
+
+        updateBroadcastCounters(3);
+        assertEquals(mVisibleAccountsChangedBroadcasts, 1); // visibility was not changed
+        assertEquals(mLoginAccountsChangedBroadcasts, 2);
+        assertEquals(mAccountRemovedBroadcasts, 0);
+    }
+
+    @SmallTest
     public void testRegisterAccountListenerCredentialsUpdate() throws Exception {
         unlockSystemUser();
         mAms.registerAccountListener(
@@ -3493,6 +3526,12 @@
         }
 
         @Override
+        public boolean bindServiceAsUser(Intent service, ServiceConnection conn,
+                Context.BindServiceFlags flags, UserHandle user) {
+            return mTestContext.bindServiceAsUser(service, conn, flags, user);
+        }
+
+        @Override
         public void unbindService(ServiceConnection conn) {
             mTestContext.unbindService(conn);
         }
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
index f1c1dc3..59f4d56b 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
@@ -24,6 +24,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
@@ -315,7 +316,7 @@
                                 mFakeBtDevice.getAddress()));
                 verify(mMockAudioService,
                         timeout(MAX_MESSAGE_HANDLING_DELAY_MS).times(0)).onUpdatedAdiDeviceState(
-                        eq(devState));
+                        eq(devState), anyBoolean());
             }
 
             // metadata set
@@ -326,7 +327,7 @@
                                 mFakeBtDevice.getAddress()));
                 verify(mMockAudioService,
                         timeout(MAX_MESSAGE_HANDLING_DELAY_MS)).onUpdatedAdiDeviceState(
-                        any());
+                        any(), anyBoolean());
             }
         } finally {
             // reset the metadata device type
@@ -354,7 +355,7 @@
         verify(mMockAudioService,
                 timeout(MAX_MESSAGE_HANDLING_DELAY_MS).atLeast(1)).onUpdatedAdiDeviceState(
                 ArgumentMatchers.argThat(devState -> devState.getAudioDeviceCategory()
-                        == AudioManager.AUDIO_DEVICE_CATEGORY_OTHER));
+                        == AudioManager.AUDIO_DEVICE_CATEGORY_OTHER), anyBoolean());
     }
 
     private void doTestConnectionDisconnectionReconnection(int delayAfterDisconnection,
diff --git a/services/tests/servicestests/src/com/android/server/audio/VolumeHelperTest.java b/services/tests/servicestests/src/com/android/server/audio/VolumeHelperTest.java
index 83bbd0e..23728db 100644
--- a/services/tests/servicestests/src/com/android/server/audio/VolumeHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/VolumeHelperTest.java
@@ -35,6 +35,7 @@
 import static android.media.AudioManager.STREAM_RING;
 import static android.media.AudioManager.STREAM_SYSTEM;
 import static android.media.AudioManager.STREAM_VOICE_CALL;
+import static android.media.audio.Flags.autoPublicVolumeApiHardening;
 import static android.view.KeyEvent.ACTION_DOWN;
 import static android.view.KeyEvent.KEYCODE_VOLUME_UP;
 
@@ -47,6 +48,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
 import static org.junit.Assume.assumeNotNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -66,6 +68,8 @@
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
 import android.media.AudioDeviceAttributes;
 import android.media.AudioDeviceInfo;
 import android.media.AudioManager;
@@ -214,6 +218,19 @@
 
         reset(mSpyAudioSystem);
 
+        final boolean useFixedVolume = mContext.getResources().getBoolean(
+                Resources.getSystem().getIdentifier("config_useFixedVolume", "bool", "android"));
+        final PackageManager packageManager = mContext.getPackageManager();
+        final boolean isTelevision = packageManager != null
+                && (packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
+                || packageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION));
+        final boolean isSingleVolume = mContext.getResources().getBoolean(
+                Resources.getSystem().getIdentifier("config_single_volume", "bool", "android"));
+        final boolean automotiveHardened = mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_AUTOMOTIVE) && autoPublicVolumeApiHardening();
+        assumeFalse("Skipping test for fixed, TV, single volume and auto devices",
+                useFixedVolume || isTelevision || isSingleVolume || automotiveHardened);
+
         InstrumentationRegistry.getInstrumentation().getUiAutomation()
                 .adoptShellPermissionIdentity(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED,
                         Manifest.permission.MODIFY_AUDIO_ROUTING,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
index f0dc5f0..7e04277 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
@@ -269,7 +269,7 @@
                 mFingerprintSensorConfigurationsCaptor.capture());
 
         final SensorProps[] fingerprintProp = mFingerprintSensorConfigurationsCaptor.getValue()
-                .getSensorPairForInstance("defaultHIDL").second;
+                .getSensorPropForInstance("defaultHIDL");
 
         assertEquals(fingerprintProp[0].commonProps.sensorId, fingerprintId);
         assertEquals(fingerprintProp[0].commonProps.sensorStrength,
@@ -280,7 +280,7 @@
 
         final android.hardware.biometrics.face.SensorProps[] faceProp =
                 mFaceSensorConfigurationsCaptor.getValue()
-                        .getSensorPairForInstance("defaultHIDL").second;
+                        .getSensorPropForInstance("defaultHIDL");
 
         assertEquals(faceProp[0].commonProps.sensorId, faceId);
         assertEquals(faceProp[0].commonProps.sensorStrength,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
index 74eb79d..34092b6 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java
@@ -68,7 +68,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
-import android.security.KeyStore;
+import android.security.KeyStoreAuthorization;
 
 import androidx.test.filters.SmallTest;
 
@@ -105,7 +105,7 @@
     @Mock private IBiometricServiceReceiver mClientReceiver;
     @Mock private IStatusBarService mStatusBarService;
     @Mock private IBiometricSysuiReceiver mSysuiReceiver;
-    @Mock private KeyStore mKeyStore;
+    @Mock private KeyStoreAuthorization mKeyStoreAuthorization;
     @Mock private AuthSession.ClientDeathReceiver mClientDeathReceiver;
     @Mock private BiometricFrameworkStatsLogger mBiometricFrameworkStatsLogger;
     @Mock private BiometricCameraManager mBiometricCameraManager;
@@ -665,9 +665,10 @@
         final PreAuthInfo preAuthInfo = createPreAuthInfo(sensors, userId, promptInfo,
                 checkDevicePolicyManager);
         return new AuthSession(mContext, mBiometricContext, mStatusBarService, mSysuiReceiver,
-                mKeyStore, mRandom, mClientDeathReceiver, preAuthInfo, mToken, requestId,
-                operationId, userId, mSensorReceiver, mClientReceiver, TEST_PACKAGE, promptInfo,
-                false /* debugEnabled */, mFingerprintSensorProps, mBiometricFrameworkStatsLogger);
+                mKeyStoreAuthorization, mRandom, mClientDeathReceiver, preAuthInfo, mToken,
+                requestId, operationId, userId, mSensorReceiver, mClientReceiver, TEST_PACKAGE,
+                promptInfo, false /* debugEnabled */, mFingerprintSensorProps,
+                mBiometricFrameworkStatsLogger);
     }
 
     private PromptInfo createPromptInfo(@Authenticators.Types int authenticators) {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index a852677..5fd29c2 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -82,8 +82,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.security.GateKeeper;
-import android.security.KeyStore;
-import android.security.authorization.IKeystoreAuthorization;
+import android.security.KeyStoreAuthorization;
 import android.service.gatekeeper.IGateKeeperService;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -182,7 +181,7 @@
     private BiometricHandlerProvider mBiometricHandlerProvider;
 
     @Mock
-    private IKeystoreAuthorization mKeystoreAuthService;
+    private KeyStoreAuthorization mKeyStoreAuthorization;
 
     @Mock
     private IGateKeeperService mGateKeeperService;
@@ -207,7 +206,7 @@
         when(mInjector.getStatusBarService()).thenReturn(mock(IStatusBarService.class));
         when(mInjector.getSettingObserver(any(), any(), any()))
                 .thenReturn(mock(BiometricService.SettingObserver.class));
-        when(mInjector.getKeyStore()).thenReturn(mock(KeyStore.class));
+        when(mInjector.getKeyStoreAuthorization()).thenReturn(mock(KeyStoreAuthorization.class));
         when(mInjector.isDebugEnabled(any(), anyInt())).thenReturn(false);
         when(mInjector.getBiometricStrengthController(any()))
                 .thenReturn(mock(BiometricStrengthController.class));
@@ -243,7 +242,7 @@
                 mStatusBarService, null /* handler */,
                 mAuthSessionCoordinator);
         when(mInjector.getBiometricContext(any())).thenReturn(mBiometricContextProvider);
-        when(mInjector.getKeystoreAuthorizationService()).thenReturn(mKeystoreAuthService);
+        when(mInjector.getKeyStoreAuthorization()).thenReturn(mKeyStoreAuthorization);
         when(mInjector.getGateKeeperService()).thenReturn(mGateKeeperService);
         when(mInjector.getNotificationLogger()).thenReturn(mNotificationLogger);
         when(mGateKeeperService.getSecureUserId(anyInt())).thenReturn(42L);
@@ -682,9 +681,9 @@
         waitForIdle();
         // HAT sent to keystore
         if (isStrongBiometric) {
-            verify(mBiometricService.mKeyStore).addAuthToken(AdditionalMatchers.aryEq(HAT));
+            verify(mKeyStoreAuthorization).addAuthToken(AdditionalMatchers.aryEq(HAT));
         } else {
-            verify(mBiometricService.mKeyStore, never()).addAuthToken(any(byte[].class));
+            verify(mKeyStoreAuthorization, never()).addAuthToken(any(byte[].class));
         }
         // Send onAuthenticated to client
         verify(mReceiver1).onAuthenticationSucceeded(
@@ -747,7 +746,7 @@
         waitForIdle();
         // Waiting for SystemUI to send confirmation callback
         assertEquals(STATE_AUTH_PENDING_CONFIRM, mBiometricService.mAuthSession.getState());
-        verify(mBiometricService.mKeyStore, never()).addAuthToken(any(byte[].class));
+        verify(mKeyStoreAuthorization, never()).addAuthToken(any(byte[].class));
 
         // SystemUI sends confirm, HAT is sent to keystore and client is notified.
         mBiometricService.mAuthSession.mSysuiReceiver.onDialogDismissed(
@@ -755,9 +754,9 @@
                 null /* credentialAttestation */);
         waitForIdle();
         if (isStrongBiometric) {
-            verify(mBiometricService.mKeyStore).addAuthToken(AdditionalMatchers.aryEq(HAT));
+            verify(mKeyStoreAuthorization).addAuthToken(AdditionalMatchers.aryEq(HAT));
         } else {
-            verify(mBiometricService.mKeyStore, never()).addAuthToken(any(byte[].class));
+            verify(mKeyStoreAuthorization, never()).addAuthToken(any(byte[].class));
         }
         verify(mReceiver1).onAuthenticationSucceeded(
                 BiometricPrompt.AUTHENTICATION_RESULT_TYPE_BIOMETRIC);
@@ -1313,7 +1312,7 @@
                 eq(TYPE_FACE),
                 eq(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED),
                 eq(0 /* vendorCode */));
-        verify(mBiometricService.mKeyStore, never()).addAuthToken(any(byte[].class));
+        verify(mKeyStoreAuthorization, never()).addAuthToken(any(byte[].class));
         assertNull(mBiometricService.mAuthSession);
     }
 
@@ -1839,7 +1838,7 @@
 
         final long expectedResult = 31337L;
 
-        when(mKeystoreAuthService.getLastAuthTime(eq(secureUserId), eq(hardwareAuthenticators)))
+        when(mKeyStoreAuthorization.getLastAuthTime(eq(secureUserId), eq(hardwareAuthenticators)))
                 .thenReturn(expectedResult);
 
         mBiometricService = new BiometricService(mContext, mInjector, mBiometricHandlerProvider);
@@ -1848,7 +1847,8 @@
                 Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL);
 
         assertEquals(expectedResult, result);
-        verify(mKeystoreAuthService).getLastAuthTime(eq(secureUserId), eq(hardwareAuthenticators));
+        verify(mKeyStoreAuthorization).getLastAuthTime(eq(secureUserId),
+                eq(hardwareAuthenticators));
     }
 
     // Helper methods
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java
index 3aaac2e..9f3f297 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java
@@ -32,8 +32,6 @@
 import android.content.pm.PackageManager;
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.IBiometricService;
-import android.hardware.biometrics.face.IFace;
-import android.hardware.biometrics.face.SensorProps;
 import android.hardware.face.FaceAuthenticateOptions;
 import android.hardware.face.FaceSensorConfigurations;
 import android.hardware.face.FaceSensorPropertiesInternal;
@@ -93,18 +91,12 @@
     @Mock
     private FaceProvider mFaceProviderVirtual;
     @Mock
-    private IFace mDefaultFaceDaemon;
-    @Mock
-    private IFace mVirtualFaceDaemon;
-    @Mock
     private IBiometricService mIBiometricService;
     @Mock
     private IBinder mToken;
     @Mock
     private IFaceServiceReceiver mFaceServiceReceiver;
 
-    private final SensorProps mDefaultSensorProps = new SensorProps();
-    private final SensorProps mVirtualSensorProps = new SensorProps();
     private FaceService mFaceService;
     private final FaceSensorPropertiesInternal mSensorPropsDefault =
             new FaceSensorPropertiesInternal(ID_DEFAULT, STRENGTH_STRONG,
@@ -126,10 +118,6 @@
 
     @Before
     public void setUp() throws RemoteException {
-        when(mDefaultFaceDaemon.getSensorProps()).thenReturn(
-                new SensorProps[]{mDefaultSensorProps});
-        when(mVirtualFaceDaemon.getSensorProps()).thenReturn(
-                new SensorProps[]{mVirtualSensorProps});
         when(mFaceProviderDefault.getSensorProperties()).thenReturn(List.of(mSensorPropsDefault));
         when(mFaceProviderVirtual.getSensorProperties()).thenReturn(List.of(mSensorPropsVirtual));
         when(mFaceProviderDefault.containsSensor(anyInt()))
@@ -140,15 +128,7 @@
         mContext.getTestablePermissions().setPermission(
                 USE_BIOMETRIC_INTERNAL, PackageManager.PERMISSION_GRANTED);
         mFaceSensorConfigurations = new FaceSensorConfigurations(false);
-        mFaceSensorConfigurations.addAidlConfigs(new String[]{NAME_DEFAULT, NAME_VIRTUAL},
-                (name) -> {
-                    if (name.equals(IFace.DESCRIPTOR + "/" + NAME_DEFAULT)) {
-                        return mDefaultFaceDaemon;
-                    } else if (name.equals(IFace.DESCRIPTOR + "/" + NAME_VIRTUAL)) {
-                        return mVirtualFaceDaemon;
-                    }
-                    return null;
-                });
+        mFaceSensorConfigurations.addAidlConfigs(new String[]{NAME_DEFAULT, NAME_VIRTUAL});
     }
 
     private void initService() {
@@ -181,7 +161,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
+    @RequiresFlagsEnabled({Flags.FLAG_DE_HIDL, Flags.FLAG_FACE_VHAL_FEATURE})
     public void registerAuthenticatorsLegacy_virtualOnly() throws Exception {
         initService();
         Settings.Secure.putInt(mSettingsRule.mockContentResolver(mContext),
@@ -199,15 +179,7 @@
     @RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
     public void registerAuthenticatorsLegacy_virtualAlwaysWhenNoOther() throws Exception {
         mFaceSensorConfigurations = new FaceSensorConfigurations(false);
-        mFaceSensorConfigurations.addAidlConfigs(new String[]{NAME_VIRTUAL},
-                (name) -> {
-                    if (name.equals(IFace.DESCRIPTOR + "/" + NAME_DEFAULT)) {
-                        return mDefaultFaceDaemon;
-                    } else if (name.equals(IFace.DESCRIPTOR + "/" + NAME_VIRTUAL)) {
-                        return mVirtualFaceDaemon;
-                    }
-                    return null;
-                });
+        mFaceSensorConfigurations.addAidlConfigs(new String[]{NAME_VIRTUAL});
         initService();
 
         mFaceService.mServiceWrapper.registerAuthenticatorsLegacy(mFaceSensorConfigurations);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
index 88956b6..20961a9 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
@@ -43,8 +43,6 @@
 import android.content.ComponentName;
 import android.content.pm.PackageManager;
 import android.hardware.biometrics.IBiometricService;
-import android.hardware.biometrics.fingerprint.IFingerprint;
-import android.hardware.biometrics.fingerprint.SensorProps;
 import android.hardware.fingerprint.FingerprintAuthenticateOptions;
 import android.hardware.fingerprint.FingerprintSensorConfigurations;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
@@ -123,10 +121,6 @@
     private IBinder mToken;
     @Mock
     private VirtualDeviceManagerInternal mVdmInternal;
-    @Mock
-    private IFingerprint mDefaultFingerprintDaemon;
-    @Mock
-    private IFingerprint mVirtualFingerprintDaemon;
 
     @Captor
     private ArgumentCaptor<FingerprintAuthenticateOptions> mAuthenticateOptionsCaptor;
@@ -145,8 +139,6 @@
                     false /* resetLockoutRequiresHardwareAuthToken */);
     private FingerprintSensorConfigurations mFingerprintSensorConfigurations;
     private FingerprintService mService;
-    private final SensorProps mDefaultSensorProps = new SensorProps();
-    private final SensorProps mVirtualSensorProps = new SensorProps();
 
     @Before
     public void setup() throws Exception {
@@ -159,10 +151,6 @@
                 .thenAnswer(i -> i.getArguments()[0].equals(ID_DEFAULT));
         when(mFingerprintVirtual.containsSensor(anyInt()))
                 .thenAnswer(i -> i.getArguments()[0].equals(ID_VIRTUAL));
-        when(mDefaultFingerprintDaemon.getSensorProps()).thenReturn(
-                new SensorProps[]{mDefaultSensorProps});
-        when(mVirtualFingerprintDaemon.getSensorProps()).thenReturn(
-                new SensorProps[]{mVirtualSensorProps});
 
         mContext.addMockSystemService(AppOpsManager.class, mAppOpsManager);
         for (int permission : List.of(OP_USE_BIOMETRIC, OP_USE_FINGERPRINT)) {
@@ -177,15 +165,7 @@
 
         mFingerprintSensorConfigurations = new FingerprintSensorConfigurations(
                 true /* resetLockoutRequiresHardwareAuthToken */);
-        mFingerprintSensorConfigurations.addAidlSensors(new String[]{NAME_DEFAULT, NAME_VIRTUAL},
-                (name) -> {
-                    if (name.equals(IFingerprint.DESCRIPTOR + "/" + NAME_DEFAULT)) {
-                        return mDefaultFingerprintDaemon;
-                    } else if (name.equals(IFingerprint.DESCRIPTOR + "/" + NAME_VIRTUAL)) {
-                        return mVirtualFingerprintDaemon;
-                    }
-                    return null;
-                });
+        mFingerprintSensorConfigurations.addAidlSensors(new String[]{NAME_DEFAULT, NAME_VIRTUAL});
     }
 
     private void initServiceWith(String... aidlInstances) {
@@ -270,15 +250,7 @@
     public void registerAuthenticatorsLegacy_virtualAlwaysWhenNoOther() throws Exception {
         mFingerprintSensorConfigurations =
                 new FingerprintSensorConfigurations(true);
-        mFingerprintSensorConfigurations.addAidlSensors(new String[]{NAME_VIRTUAL},
-                        (name) -> {
-                            if (name.equals(IFingerprint.DESCRIPTOR + "/" + NAME_DEFAULT)) {
-                                return mDefaultFingerprintDaemon;
-                            } else if (name.equals(IFingerprint.DESCRIPTOR + "/" + NAME_VIRTUAL)) {
-                                return mVirtualFingerprintDaemon;
-                            }
-                            return null;
-                        });
+        mFingerprintSensorConfigurations.addAidlSensors(new String[]{NAME_VIRTUAL});
         initServiceWith(NAME_VIRTUAL);
 
         mService.mServiceWrapper.registerAuthenticatorsLegacy(mFingerprintSensorConfigurations);
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java
index ec3e97b..0678140 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/GenericWindowPolicyControllerTest.java
@@ -123,6 +123,7 @@
     @Test
     public void containsUid() {
         GenericWindowPolicyController gwpc = createGwpc();
+        gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
 
         assertThat(gwpc.containsUid(TEST_UID)).isFalse();
 
@@ -136,6 +137,7 @@
     @Test
     public void isEnteringPipAllowed_falseByDefault() {
         GenericWindowPolicyController gwpc = createGwpc();
+        gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
 
         assertThat(gwpc.isEnteringPipAllowed(TEST_UID)).isFalse();
         verify(mPipBlockedCallback, timeout(TIMEOUT_MILLIS)).onEnteringPipBlocked(TEST_UID);
@@ -144,6 +146,7 @@
     @Test
     public void isEnteringPipAllowed_dpcSupportsPinned_allowed() {
         GenericWindowPolicyController gwpc = createGwpc();
+        gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
         gwpc.setSupportedWindowingModes(new HashSet<>(
                 Arrays.asList(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
                         WindowConfiguration.WINDOWING_MODE_PINNED)));
@@ -160,11 +163,25 @@
                 NONBLOCKED_APP_PACKAGE_NAME,
                 NONBLOCKED_APP_PACKAGE_NAME,
                 /* displayOnRemoteDevices */ true,
-                /* targetDisplayCategory */ null);
+                /* targetDisplayCategory */ null,
+                /* uid */ UserHandle.PER_USER_RANGE + 1);
         assertActivityIsBlocked(gwpc, activityInfo);
     }
 
     @Test
+    public void userNotAllowlisted_systemUser_isNotBlocked() {
+        GenericWindowPolicyController gwpc = createGwpcWithNoAllowedUsers();
+        gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
+
+        ActivityInfo activityInfo = getActivityInfo(
+                NONBLOCKED_APP_PACKAGE_NAME,
+                NONBLOCKED_APP_PACKAGE_NAME,
+                /* displayOnRemoteDevices */ true,
+                /* targetDisplayCategory */ null);
+        assertActivityCanBeLaunched(gwpc, activityInfo);
+    }
+
+    @Test
     public void userNotAllowlisted_systemUserCanLaunchBlockedAppStreamingActivity() {
         GenericWindowPolicyController gwpc = createGwpcWithNoAllowedUsers();
         gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
@@ -521,6 +538,7 @@
     public void registerRunningAppsChangedListener_onRunningAppsChanged_listenersNotified() {
         ArraySet<Integer> uids = new ArraySet<>(Arrays.asList(TEST_UID));
         GenericWindowPolicyController gwpc = createGwpc();
+        gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
 
         gwpc.registerRunningAppsChangedListener(mRunningAppsChangedListener);
         gwpc.onRunningAppsChanged(uids);
@@ -545,6 +563,7 @@
     public void noRunningAppsChangedListener_onRunningAppsChanged_doesNotThrowException() {
         ArraySet<Integer> uids = new ArraySet<>(Arrays.asList(TEST_UID));
         GenericWindowPolicyController gwpc = createGwpc();
+        gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
 
         gwpc.onRunningAppsChanged(uids);
 
@@ -557,6 +576,7 @@
     public void registerUnregisterRunningAppsChangedListener_onRunningAppsChanged_doesNotThrowException() {
         ArraySet<Integer> uids = new ArraySet<>(Arrays.asList(TEST_UID));
         GenericWindowPolicyController gwpc = createGwpc();
+        gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
 
         gwpc.registerRunningAppsChangedListener(mRunningAppsChangedListener);
         gwpc.unregisterRunningAppsChangedListener(mRunningAppsChangedListener);
@@ -579,6 +599,7 @@
         doReturn(interceptor).when(interceptor).queryLocalInterface(anyString());
 
         GenericWindowPolicyController gwpc = createGwpc();
+        gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
         ActivityInfo activityInfo = getActivityInfo(
                 NONBLOCKED_APP_PACKAGE_NAME,
                 NONBLOCKED_APP_PACKAGE_NAME,
@@ -603,6 +624,7 @@
         Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("testing"));
 
         GenericWindowPolicyController gwpc = createGwpc();
+        gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
         ActivityInfo activityInfo = getActivityInfo(
                 NONBLOCKED_APP_PACKAGE_NAME,
                 NONBLOCKED_APP_PACKAGE_NAME,
@@ -621,6 +643,7 @@
     @Test
     public void onTopActivitychanged_null_noCallback() {
         GenericWindowPolicyController gwpc = createGwpc();
+        gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
 
         gwpc.onTopActivityChanged(null, 0, 0);
         verify(mActivityListener, after(TIMEOUT_MILLIS).never())
@@ -697,6 +720,7 @@
     @Test
     public void getCustomHomeComponent_noneSet() {
         GenericWindowPolicyController gwpc = createGwpc();
+        gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
 
         assertThat(gwpc.getCustomHomeComponent()).isNull();
     }
@@ -705,6 +729,7 @@
     public void getCustomHomeComponent_returnsHomeComponent() {
         GenericWindowPolicyController gwpc = createGwpcWithCustomHomeComponent(
                 NONBLOCKED_COMPONENT);
+        gwpc.setDisplayId(DISPLAY_ID, /* isMirrorDisplay= */ false);
 
         assertThat(gwpc.getCustomHomeComponent()).isEqualTo(NONBLOCKED_COMPONENT);
     }
diff --git a/services/tests/servicestests/src/com/android/server/contentcapture/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/contentcapture/TEST_MAPPING
index dae8f93..0946229 100644
--- a/services/tests/servicestests/src/com/android/server/contentcapture/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/contentcapture/TEST_MAPPING
@@ -1,23 +1,6 @@
 {
   "presubmit": [
     {
-      "name": "FrameworksServicesTests",
-      "options": [
-        {
-          "include-filter": "com.android.server.contentcapture"
-        },
-        {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
-        },
-        {
-          "exclude-annotation": "org.junit.Ignore"
-        }
-      ]
-    }
-  ],
-  "postsubmit": [
-    {
-      // b/331020193, Move to presubmit early april 2024
       "name": "FrameworksServicesTests_contentcapture"
     }
   ]
diff --git a/services/tests/servicestests/src/com/android/server/contentprotection/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/contentprotection/TEST_MAPPING
index 32729a8..1ad7baa 100644
--- a/services/tests/servicestests/src/com/android/server/contentprotection/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/contentprotection/TEST_MAPPING
@@ -1,23 +1,6 @@
 {
   "presubmit": [
     {
-      "name": "FrameworksServicesTests",
-      "options": [
-        {
-          "include-filter": "com.android.server.contentprotection"
-        },
-        {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
-        },
-        {
-          "exclude-annotation": "org.junit.Ignore"
-        }
-      ]
-    }
-  ],
-  "postsubmit": [
-    {
-      // b/331020193, Move to presubmit early april 2024
       "name": "FrameworksServicesTests_contentprotection"
     }
   ]
diff --git a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java
index dacff4c..44aa868 100644
--- a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java
+++ b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java
@@ -30,6 +30,9 @@
 import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
 import android.system.Os;
 import android.text.FontConfig;
 import android.util.Xml;
@@ -38,8 +41,11 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.text.flags.Flags;
+
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.xmlpull.v1.XmlPullParser;
@@ -69,6 +75,9 @@
 
     private static final String LEGACY_FONTS_XML = "/system/etc/fonts.xml";
 
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
     /**
      * A {@link UpdatableFontDir.FontFileParser} for testing. Instead of using real font files,
      * this test uses fake font files. A fake font file has its PostScript naem and revision as the
@@ -999,6 +1008,587 @@
         assertThat(mUpdatableFontFilesDir.list()).hasLength(0);
     }
 
+    private UpdatableFontDir createNewUpdateDir() {
+        UpdatableFontDir dir = new UpdatableFontDir(
+                mUpdatableFontFilesDir, mParser, mFakeFsverityUtil,
+                mConfigFile, mCurrentTimeSupplier, mConfigSupplier);
+        dir.loadFontFileMap();
+        return dir;
+    }
+
+    private UpdatableFontDir installTestFontFamilies(int version) {
+        UpdatableFontDir dir = createNewUpdateDir();
+        try {
+            dir.update(Arrays.asList(
+                    newFontUpdateRequest("foo.ttf," + version + ",foo", GOOD_SIGNATURE),
+                    newFontUpdateRequest("bar.ttf," + version + ",bar", GOOD_SIGNATURE),
+                    newAddFontFamilyRequest("<family name='foobar'>"
+                            + "  <font>foo.ttf</font>"
+                            + "  <font>bar.ttf</font>"
+                            + "</family>")));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return dir;
+    }
+
+    private UpdatableFontDir installTestFontFile(int numFonts, int version) {
+        UpdatableFontDir dir = createNewUpdateDir();
+        List<FontUpdateRequest> requests = new ArrayList<>();
+        if (numFonts <= 0 || numFonts > 3) {
+            throw new IllegalArgumentException("numFont must be 1, 2 or 3");
+        }
+        try {
+            requests.add(newFontUpdateRequest("foo.ttf," + version + ",foo", GOOD_SIGNATURE));
+            if (numFonts >= 2) {
+                requests.add(newFontUpdateRequest("bar.ttf," + version + ",bar", GOOD_SIGNATURE));
+            }
+            if (numFonts == 3) {
+                requests.add(newFontUpdateRequest("baz.ttf," + version + ",baz", GOOD_SIGNATURE));
+            }
+            dir.update(requests);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return dir;
+    }
+
+    private List<File> collectSignatureFiles() {
+        return Arrays.stream(mUpdatableFontFilesDir.listFiles())
+                .map((file) -> file.listFiles((unused, s) -> s.endsWith(".fsv_sig")))
+                .flatMap(Arrays::stream)
+                .toList();
+    }
+
+    private List<File> collectFontFiles() {
+        return Arrays.stream(mUpdatableFontFilesDir.listFiles())
+                .map((file) -> file.listFiles((unused, s) -> s.endsWith(".ttf")))
+                .flatMap(Arrays::stream)
+                .toList();
+    }
+
+    private void removeAll(List<File> files) {
+        files.forEach((File file) -> {
+            if (file.isDirectory()) {
+                removeAll(List.of(file.listFiles()));
+            } else {
+                assertThat(file.delete()).isTrue();
+            }
+        });
+    }
+
+    private void assertTestFontFamilyInstalled(UpdatableFontDir dir, int version) {
+        try {
+            assertNamedFamilyExists(dir.getSystemFontConfig(), "foobar");
+            assertThat(dir.getFontFamilyMap()).containsKey("foobar");
+            assertThat(dir.getFontFamilyMap().get("foobar").getFamilies().size()).isEqualTo(1);
+            FontConfig.FontFamily foobar = dir.getFontFamilyMap().get("foobar").getFamilies()
+                    .get(0);
+            assertThat(foobar.getFontList()).hasSize(2);
+            assertThat(foobar.getFontList().get(0).getFile())
+                    .isEqualTo(dir.getPostScriptMap().get("foo"));
+            assertThat(mParser.getRevision(dir.getPostScriptMap().get("foo"))).isEqualTo(version);
+            assertThat(foobar.getFontList().get(1).getFile())
+                    .isEqualTo(dir.getPostScriptMap().get("bar"));
+            assertThat(mParser.getRevision(dir.getPostScriptMap().get("bar"))).isEqualTo(version);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void assertTestFontInstalled(UpdatableFontDir dir, int version) {
+        try {
+            assertThat(dir.getPostScriptMap().containsKey("foo")).isTrue();
+            assertThat(mParser.getRevision(dir.getPostScriptMap().get("foo"))).isEqualTo(version);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void signatureMissingCase_fontFamilyInstalled_fontFamilyInstallLater() {
+        // Install font families, foo.ttf, bar.ttf.
+        installTestFontFamilies(1 /* version */);
+
+        // Delete one signature file
+        assertThat(collectSignatureFiles().get(0).delete()).isTrue();
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFamilies(2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontFamilyInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontFamilyInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void signatureMissingCase_fontFamilyInstalled_fontInstallLater() {
+        // Install font families, foo.ttf, bar.ttf.
+        installTestFontFamilies(1);
+
+        // Delete one signature file
+        assertThat(collectSignatureFiles().get(0).delete()).isTrue();
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void signatureMissingCase_fontFileInstalled_fontFamilyInstallLater() {
+        // Install font file, foo.ttf and bar.ttf
+        installTestFontFile(2 /* numFonts */, 1 /* version */);
+
+        // Delete one signature file
+        assertThat(collectSignatureFiles().get(0).delete()).isTrue();
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFamilies(2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontFamilyInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontFamilyInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void signatureMissingCase_fontFileInstalled_fontFileInstallLater() {
+        // Install font file, foo.ttf and bar.ttf
+        installTestFontFile(2 /* numFonts */, 1 /* version */);
+
+        // Delete one signature file
+        assertThat(collectSignatureFiles().get(0).delete()).isTrue();
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFile(2 /* numFonts */, 2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void signatureAllMissingCase_fontFamilyInstalled_fontFamilyInstallLater() {
+        // Install font families, foo.ttf, bar.ttf.
+        installTestFontFamilies(1 /* version */);
+
+        // Delete all signature files
+        removeAll(collectSignatureFiles());
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFamilies(2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontFamilyInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontFamilyInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void signatureAllMissingCase_fontFamilyInstalled_fontInstallLater() {
+        // Install font families, foo.ttf, bar.ttf.
+        installTestFontFamilies(1 /* version */);
+
+        // Delete all signature files
+        removeAll(collectSignatureFiles());
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void signatureAllMissingCase_fontFileInstalled_fontFamilyInstallLater() {
+        // Install font file, foo.ttf
+        installTestFontFile(1 /* numFonts */, 1 /* version */);
+
+        // Delete all signature files
+        removeAll(collectSignatureFiles());
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFamilies(2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontFamilyInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontFamilyInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void signatureAllMissingCase_fontFileInstalled_fontFileInstallLater() {
+        // Install font file, foo.ttf
+        installTestFontFile(1 /* numFonts */, 1 /* version */);
+
+        // Delete all signature files
+        removeAll(collectSignatureFiles());
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void fontMissingCase_fontFamilyInstalled_fontFamilyInstallLater() {
+        // Install font families, foo.ttf, bar.ttf.
+        installTestFontFamilies(1 /* version */);
+
+        // Delete one font file
+        assertThat(collectFontFiles().get(0).delete()).isTrue();
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFamilies(2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontFamilyInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontFamilyInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void fontMissingCase_fontFamilyInstalled_fontInstallLater() {
+        // Install font families, foo.ttf, bar.ttf.
+        installTestFontFamilies(1);
+
+        // Delete one font file
+        assertThat(collectFontFiles().get(0).delete()).isTrue();
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void fontMissingCase_fontFileInstalled_fontFamilyInstallLater() {
+        // Install font file, foo.ttf and bar.ttf
+        installTestFontFile(2 /* numFonts */, 1 /* version */);
+
+        // Delete one font file
+        assertThat(collectFontFiles().get(0).delete()).isTrue();
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFamilies(2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontFamilyInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontFamilyInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void fontMissingCase_fontFileInstalled_fontFileInstallLater() {
+        // Install font file, foo.ttf and bar.ttf
+        installTestFontFile(2 /* numFonts */, 1 /* version */);
+
+        // Delete one font file
+        assertThat(collectFontFiles().get(0).delete()).isTrue();
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFile(2 /* numFonts */, 2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void fontAllMissingCase_fontFamilyInstalled_fontFamilyInstallLater() {
+        // Install font families, foo.ttf, bar.ttf.
+        installTestFontFamilies(1 /* version */);
+
+        // Delete all font files
+        removeAll(collectFontFiles());
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFamilies(2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontFamilyInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontFamilyInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void fontAllMissingCase_fontFamilyInstalled_fontInstallLater() {
+        // Install font families, foo.ttf, bar.ttf.
+        installTestFontFamilies(1 /* version */);
+
+        // Delete all font files
+        removeAll(collectFontFiles());
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void fontAllMissingCase_fontFileInstalled_fontFamilyInstallLater() {
+        // Install font file, foo.ttf
+        installTestFontFile(1 /* numFonts */, 1 /* version */);
+
+        // Delete all font files
+        removeAll(collectFontFiles());
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFamilies(2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontFamilyInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontFamilyInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void fontAllMissingCase_fontFileInstalled_fontFileInstallLater() {
+        // Install font file, foo.ttf
+        installTestFontFile(1 /* numFonts */, 1 /* version */);
+
+        // Delete all font files
+        removeAll(collectFontFiles());
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void fontDirAllMissingCase_fontFamilyInstalled_fontFamilyInstallLater() {
+        // Install font families, foo.ttf, bar.ttf.
+        installTestFontFamilies(1 /* version */);
+
+        // Delete all font files
+        removeAll(List.of(mUpdatableFontFilesDir.listFiles()));
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFamilies(2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontFamilyInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontFamilyInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void fontDirAllMissingCase_fontFamilyInstalled_fontInstallLater() {
+        // Install font families, foo.ttf, bar.ttf.
+        installTestFontFamilies(1 /* version */);
+
+        // Delete all font files
+        removeAll(List.of(mUpdatableFontFilesDir.listFiles()));
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void fontDirAllMissingCase_fontFileInstalled_fontFamilyInstallLater() {
+        // Install font file, foo.ttf
+        installTestFontFile(1 /* numFonts */, 1 /* version */);
+
+        // Delete all font files
+        removeAll(List.of(mUpdatableFontFilesDir.listFiles()));
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFamilies(2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontFamilyInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontFamilyInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void fontDirAllMissingCase_fontFileInstalled_fontFileInstallLater() {
+        // Install font file, foo.ttf
+        installTestFontFile(1 /* numFonts */, 1 /* version */);
+
+        // Delete all font files
+        removeAll(List.of(mUpdatableFontFilesDir.listFiles()));
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void dirContentAllMissingCase_fontFamilyInstalled_fontFamilyInstallLater() {
+        // Install font families, foo.ttf, bar.ttf.
+        installTestFontFamilies(1 /* version */);
+
+        // Delete all font files
+        removeAll(collectFontFiles());
+        removeAll(collectSignatureFiles());
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFamilies(2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontFamilyInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontFamilyInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void dirContentAllMissingCase_fontFamilyInstalled_fontInstallLater() {
+        // Install font families, foo.ttf, bar.ttf.
+        installTestFontFamilies(1 /* version */);
+
+        // Delete all font files
+        removeAll(collectFontFiles());
+        removeAll(collectSignatureFiles());
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void dirContentAllMissingCase_fontFileInstalled_fontFamilyInstallLater() {
+        // Install font file, foo.ttf
+        installTestFontFile(1 /* numFonts */, 1 /* version */);
+
+        // Delete all font files
+        removeAll(collectFontFiles());
+        removeAll(collectSignatureFiles());
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFamilies(2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontFamilyInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontFamilyInstalled(nextDir, 2 /* version */);
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_FIX_FONT_UPDATE_FAILURE)
+    public void dirContentAllMissingCase_fontFileInstalled_fontFileInstallLater() {
+        // Install font file, foo.ttf
+        installTestFontFile(1 /* numFonts */, 1 /* version */);
+
+        // Delete all font files
+        removeAll(collectFontFiles());
+        removeAll(collectSignatureFiles());
+
+        // New instance of UpdatableFontDir, this emulate a device reboot.
+        UpdatableFontDir dir = installTestFontFile(1 /* numFonts */, 2 /* version */);
+
+        // Make sure the font installation succeeds.
+        assertTestFontInstalled(dir, 2 /* version */);
+
+        // Make sure after the reboot, the configuration remains.
+        UpdatableFontDir nextDir = createNewUpdateDir();
+        assertTestFontInstalled(nextDir, 2 /* version */);
+    }
+
     private FontUpdateRequest newFontUpdateRequest(String content, String signature)
             throws Exception {
         File file = File.createTempFile("font", "ttf", mCacheDir);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index 1bd6e29..28da97c 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -21,6 +21,9 @@
 import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
 import static com.android.server.hdmi.Constants.ADDR_INVALID;
 import static com.android.server.hdmi.Constants.ADDR_TV;
+import static com.android.server.hdmi.HdmiCecLocalDevicePlayback.POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS;
+import static com.android.server.hdmi.HdmiCecLocalDevicePlayback.STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS;
+import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_BOOT_UP;
 import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -58,7 +61,9 @@
 public class HdmiCecLocalDevicePlaybackTest {
     private static final int TIMEOUT_MS = HdmiConfig.TIMEOUT_MS + 1;
     private static final int HOTPLUG_INTERVAL =
-            HotplugDetectionAction.POLLING_INTERVAL_MS_FOR_PLAYBACK;
+            HotplugDetectionAction.POLLING_BATCH_INTERVAL_MS_FOR_PLAYBACK;
+    private static final long POLLING_DELAY =
+            HotplugDetectionAction.POLLING_MESSAGE_INTERVAL_MS_FOR_PLAYBACK;
 
     private static final int PORT_1 = 1;
     private static final HdmiDeviceInfo INFO_TV = HdmiDeviceInfo.cecDeviceBuilder()
@@ -87,6 +92,8 @@
     private FakePowerManagerInternalWrapper mPowerManagerInternal =
             new FakePowerManagerInternalWrapper();
 
+    private boolean mIsOnActiveSourceLostPopupActive;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -141,6 +148,18 @@
                 mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
         mHdmiControlService.setCecController(mHdmiCecController);
         mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
+        mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(mHdmiControlService) {
+            @Override
+            void startHdmiCecActiveSourceLostActivity() {
+                mIsOnActiveSourceLostPopupActive = true;
+            }
+
+            @Override
+            void dismissUiOnActiveSourceStatusRecovered() {
+                mIsOnActiveSourceLostPopupActive = false;
+            }
+        };
+        mHdmiCecLocalDevicePlayback.init();
         HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[1];
         hdmiPortInfos[0] =
                 new HdmiPortInfo.Builder(1, HdmiPortInfo.PORT_OUTPUT, 0x0000)
@@ -158,14 +177,15 @@
         mPlaybackPhysicalAddress = 0x2000;
         mNativeWrapper.setPhysicalAddress(mPlaybackPhysicalAddress);
         mTestLooper.dispatchAll();
-        mHdmiCecLocalDevicePlayback = mHdmiControlService.playback();
         mLocalDevices.add(mHdmiCecLocalDevicePlayback);
-        mPlaybackLogicalAddress = mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress();
         mHdmiControlService.getHdmiCecNetwork().addCecDevice(INFO_TV);
         mNativeWrapper.clearResultMessages();
         mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
                 HdmiProperties.playback_device_action_on_routing_control_values.NONE;
         mHdmiControlService.setPowerStatus(HdmiControlManager.POWER_STATUS_ON);
+        mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_BOOT_UP);
+        mTestLooper.dispatchAll();
+        mPlaybackLogicalAddress = mHdmiCecLocalDevicePlayback.getDeviceInfo().getLogicalAddress();
     }
 
     @Test
@@ -379,6 +399,8 @@
         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
                 .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+        // After 30s of device inactivity, device would go to sleep.
+        skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
         assertThat(mPowerManager.isInteractive()).isFalse();
     }
 
@@ -420,6 +442,8 @@
         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(message))
                 .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+        // After 30s of device inactivity, device would go to sleep.
+        skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
         assertThat(mPowerManager.isInteractive()).isFalse();
     }
 
@@ -578,6 +602,8 @@
         assertThat(mHdmiCecLocalDevicePlayback.handleRoutingInformation(message))
                 .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+        // After 30s of device inactivity, device would go to sleep.
+        skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
         assertThat(mPowerManager.isInteractive()).isFalse();
     }
 
@@ -681,6 +707,8 @@
         // See {@link HdmiCecLocalDevicePlayback#handleRoutingChangeAndInformation}.
         assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(
                 ADDR_INVALID);
+        // After 30s of device inactivity, device would go to sleep.
+        skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
         assertThat(mPowerManager.isInteractive()).isFalse();
     }
 
@@ -1223,6 +1251,9 @@
         assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message))
                 .isEqualTo(Constants.HANDLED);
         mTestLooper.dispatchAll();
+
+        // After 30s of device inactivity, device would go to sleep.
+        skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
         assertThat(mPowerManager.isInteractive()).isFalse();
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
     }
@@ -1297,6 +1328,8 @@
         assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(message2))
                 .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+        // After 30s of device inactivity, device would go to sleep.
+        skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
         assertThat(mPowerManager.isInteractive()).isFalse();
         mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
         // 3. DUT becomes <AS> again.
@@ -1657,6 +1690,9 @@
         assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(message))
                 .isEqualTo(Constants.HANDLED);
         assertThat(mHdmiCecLocalDevicePlayback.isActiveSource()).isFalse();
+
+        // After 30s of device inactivity, device would go to sleep.
+        skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
         assertThat(mPowerManager.isInteractive()).isFalse();
     }
 
@@ -1867,9 +1903,14 @@
 
         mNativeWrapper.setPollAddressResponse(otherPlaybackLogicalAddress,
                 SendMessageResult.SUCCESS);
+        // Moving forward to skip hotplug interval for polling to start
         mTestLooper.moveTimeForward(HOTPLUG_INTERVAL);
         mTestLooper.dispatchAll();
-
+        // Skipping each polling delay and dispatch each polling message
+        for (int i = 0; i < 14; i++) {
+            mTestLooper.moveTimeForward(POLLING_DELAY);
+            mTestLooper.dispatchAll();
+        }
         // Check for <Give Physical Address> being sent to the newly discovered device.
         // This message is sent as part of the HotplugDetectionAction to available devices.
         HdmiCecMessage givePhysicalAddress = HdmiCecMessageBuilder.buildGivePhysicalAddress(
@@ -2248,6 +2289,159 @@
     }
 
     @Test
+    public void onActiveSourceLostToTv_noInteractionWithDut_standbyAfterTimeout() {
+        mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
+                HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
+                HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
+
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
+        mPowerManager.setInteractive(true);
+        mNativeWrapper.clearResultMessages();
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage activeSourceFromTv =
+                HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
+
+        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(activeSourceFromTv))
+                .isEqualTo(Constants.HANDLED);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(ADDR_TV);
+        mTestLooper.dispatchAll();
+
+        // After 30s of device inactivity, device would go to sleep.
+        skipActiveSourceLostUi(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
+        assertThat(mPowerManager.isInteractive()).isFalse();
+    }
+
+    @Test
+    public void onActiveSourceLost_interactionWithDut_noStandbyAfterTimeout() {
+        mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
+                HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
+                HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
+        mPowerManager.setInteractive(true);
+        mNativeWrapper.clearResultMessages();
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage activeSourceFromTv =
+                HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
+        HdmiCecMessage activeSourceFromPlayback =
+                HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
+                        mPlaybackPhysicalAddress);
+
+        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(activeSourceFromTv))
+                .isEqualTo(Constants.HANDLED);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(ADDR_TV);
+        mTestLooper.dispatchAll();
+
+        // User interacted with the DUT, so the device will not go to standby.
+        skipActiveSourceLostUi(0);
+        assertThat(mIsOnActiveSourceLostPopupActive).isFalse();
+        assertThat(mPowerManager.isInteractive()).isTrue();
+        assertThat(mNativeWrapper.getResultMessages().contains(activeSourceFromPlayback)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress)
+                .isEqualTo(mPlaybackLogicalAddress);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress)
+                .isEqualTo(mPlaybackPhysicalAddress);
+    }
+
+    @Test
+    public void onActiveSourceLost_incomingSetStreamPathToDut_noStandbyAfterTimeout() {
+        mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
+                HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
+                HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
+        mPowerManager.setInteractive(true);
+        mNativeWrapper.clearResultMessages();
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage activeSourceFromTv =
+                HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
+        HdmiCecMessage activeSourceFromPlayback =
+                HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
+                        mPlaybackPhysicalAddress);
+        HdmiCecMessage setStreamPathToPlayback = HdmiCecMessageBuilder.buildSetStreamPath(ADDR_TV,
+                mPlaybackPhysicalAddress);
+
+        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(activeSourceFromTv))
+                .isEqualTo(Constants.HANDLED);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(ADDR_TV);
+        mTestLooper.dispatchAll();
+
+        // Pop-up is triggered.
+        mTestLooper.moveTimeForward(POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
+        mTestLooper.dispatchAll();
+        assertThat(mIsOnActiveSourceLostPopupActive).isTrue();
+
+        assertThat(mHdmiCecLocalDevicePlayback.handleSetStreamPath(setStreamPathToPlayback))
+                .isEqualTo(Constants.HANDLED);
+        mTestLooper.dispatchAll();
+
+        assertThat(mIsOnActiveSourceLostPopupActive).isFalse();
+        assertThat(mNativeWrapper.getResultMessages().contains(activeSourceFromPlayback)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress)
+                .isEqualTo(mPlaybackLogicalAddress);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress)
+                .isEqualTo(mPlaybackPhysicalAddress);
+        mTestLooper.moveTimeForward(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
+        mTestLooper.dispatchAll();
+
+        assertThat(mPowerManager.isInteractive()).isTrue();
+    }
+
+    @Test
+    public void onActiveSourceLost_incomingRoutingChangeToDut_noStandbyAfterTimeout() {
+        mHdmiCecLocalDevicePlayback.mService.getHdmiCecConfig().setStringValue(
+                HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
+                HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW);
+        mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
+                HdmiProperties
+                        .playback_device_action_on_routing_control_values
+                        .WAKE_UP_AND_SEND_ACTIVE_SOURCE;
+        mHdmiCecLocalDevicePlayback.setActiveSource(mPlaybackLogicalAddress,
+                mPlaybackPhysicalAddress, "HdmiCecLocalDevicePlaybackTest");
+        mPowerManager.setInteractive(true);
+        mNativeWrapper.clearResultMessages();
+        mTestLooper.dispatchAll();
+
+        HdmiCecMessage activeSourceFromTv =
+                HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
+        HdmiCecMessage activeSourceFromPlayback =
+                HdmiCecMessageBuilder.buildActiveSource(mPlaybackLogicalAddress,
+                        mPlaybackPhysicalAddress);
+        HdmiCecMessage routingChangeToPlayback =
+                HdmiCecMessageBuilder.buildRoutingChange(ADDR_TV, 0x0000,
+                        mPlaybackPhysicalAddress);
+
+        assertThat(mHdmiCecLocalDevicePlayback.handleActiveSource(activeSourceFromTv))
+                .isEqualTo(Constants.HANDLED);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress).isEqualTo(ADDR_TV);
+        mTestLooper.dispatchAll();
+
+        // Pop-up is triggered.
+        mTestLooper.moveTimeForward(POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
+        mTestLooper.dispatchAll();
+        assertThat(mIsOnActiveSourceLostPopupActive).isTrue();
+
+        assertThat(mHdmiCecLocalDevicePlayback.handleRoutingChange(routingChangeToPlayback))
+                .isEqualTo(Constants.HANDLED);
+        mTestLooper.dispatchAll();
+
+        assertThat(mIsOnActiveSourceLostPopupActive).isFalse();
+        assertThat(mNativeWrapper.getResultMessages().contains(activeSourceFromPlayback)).isTrue();
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().logicalAddress)
+                .isEqualTo(mPlaybackLogicalAddress);
+        assertThat(mHdmiCecLocalDevicePlayback.getActiveSource().physicalAddress)
+                .isEqualTo(mPlaybackPhysicalAddress);
+        mTestLooper.moveTimeForward(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
+        mTestLooper.dispatchAll();
+
+        assertThat(mPowerManager.isInteractive()).isTrue();
+    }
+
+    @Test
     public void handleRoutingChange_addressNotAllocated_removeActiveSourceAction() {
         long allocationDelay = TimeUnit.SECONDS.toMillis(60);
         mHdmiCecLocalDevicePlayback.mPlaybackDeviceActionOnRoutingControl =
@@ -2353,4 +2547,14 @@
         assertThat(mHdmiCecLocalDevicePlayback.getActions(ActiveSourceAction.class)).isEmpty();
         assertThat(mNativeWrapper.getResultMessages()).doesNotContain(unexpectedMessage);
     }
+
+    private void skipActiveSourceLostUi(long idleDuration) {
+        mTestLooper.moveTimeForward(POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
+        mTestLooper.dispatchAll();
+        assertThat(mIsOnActiveSourceLostPopupActive).isTrue();
+
+        mPowerManagerInternal.setIdleDuration(idleDuration);
+        mTestLooper.moveTimeForward(STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
+        mTestLooper.dispatchAll();
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index 67ae998..902ffed 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -829,8 +829,8 @@
         // Playback 1 begins ACKing polls, allowing detection by HotplugDetectionAction
         mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS);
         for (int pollCount = 0; pollCount < HotplugDetectionAction.TIMEOUT_COUNT; pollCount++) {
-            mTestLooper.moveTimeForward(
-                    TimeUnit.SECONDS.toMillis(HotplugDetectionAction.POLLING_INTERVAL_MS_FOR_TV));
+            mTestLooper.moveTimeForward(TimeUnit.SECONDS.toMillis(
+                    HotplugDetectionAction.POLLING_BATCH_INTERVAL_MS_FOR_TV));
             mTestLooper.dispatchAll();
         }
 
@@ -872,7 +872,7 @@
         // Assert that this device is removed from the list of devices.
         mNativeWrapper.setPollAddressResponse(Constants.ADDR_PLAYBACK_2, SendMessageResult.NACK);
         for (int pollCount = 0; pollCount < HotplugDetectionAction.TIMEOUT_COUNT; pollCount++) {
-            mTestLooper.moveTimeForward(HotplugDetectionAction.POLLING_INTERVAL_MS_FOR_TV);
+            mTestLooper.moveTimeForward(HotplugDetectionAction.POLLING_BATCH_INTERVAL_MS_FOR_TV);
             mTestLooper.dispatchAll();
         }
 
@@ -920,7 +920,7 @@
         // Assert that this device is removed from the list of devices.
         mNativeWrapper.setPollAddressResponse(ADDR_AUDIO_SYSTEM, SendMessageResult.NACK);
         for (int pollCount = 0; pollCount < HotplugDetectionAction.TIMEOUT_COUNT; pollCount++) {
-            mTestLooper.moveTimeForward(HotplugDetectionAction.POLLING_INTERVAL_MS_FOR_TV);
+            mTestLooper.moveTimeForward(HotplugDetectionAction.POLLING_BATCH_INTERVAL_MS_FOR_TV);
             mTestLooper.dispatchAll();
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING
index dc8f934..58f5bb3 100644
--- a/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING
@@ -1,29 +1,11 @@
 {
   "presubmit": [
     {
-      "name": "FrameworksServicesTests",
-      "options": [
-        {
-          "include-filter": "com.android.server.location.contexthub."
-        },
-        {
-          "include-annotation": "android.platform.test.annotations.Presubmit"
-        },
-        {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
-        },
-        {
-          "exclude-annotation": "org.junit.Ignore"
-        }
-      ]
+      "name": "FrameworksServicesTests_contexthub_presubmit"
     }
   ],
   "postsubmit": [
     {
-      // b/331020193, Move to presubmit early april 2024
-      "name": "FrameworksServicesTests_contexthub_presubmit"
-    },
-    {
       "name": "FrameworksServicesTests",
       "options": [
         {
diff --git a/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING
index 41c4383..944c1df 100644
--- a/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING
@@ -1,12 +1,7 @@
 {
   "presubmit": [
     {
-      "name": "FrameworksServicesTests",
-      "options": [
-        {
-          "include-filter": "com.android.server.om."
-        }
-      ]
+      "name": "FrameworksServicesTests_om"
     },
     {
       "name": "PackageManagerServiceHostTests",
@@ -16,11 +11,5 @@
         }
       ]
     }
-  ],
-  "postsubmit": [
-    {
-      // b/331020193, Move to presubmit early april 2024
-      "name": "FrameworksServicesTests_om"
-    }
   ]
 }
diff --git a/services/tests/servicestests/src/com/android/server/os/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/os/TEST_MAPPING
index 06e7002..2138da9 100644
--- a/services/tests/servicestests/src/com/android/server/os/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/os/TEST_MAPPING
@@ -1,17 +1,6 @@
 {
   "presubmit": [
     {
-      "name": "FrameworksServicesTests",
-      "options": [
-        {
-          "include-filter": "com.android.server.os."
-        }
-      ]
-    }
-  ],
-  "postsubmit": [
-    {
-      // b/331020193, Move to presubmit early april 2024
       "name": "FrameworksServicesTests_os"
     }
   ]
diff --git a/services/tests/servicestests/src/com/android/server/pm/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/pm/TEST_MAPPING
index f4e724f..861562d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/pm/TEST_MAPPING
@@ -21,7 +21,7 @@
   "postsubmit": [
     {
       // Presubmit is intentional here while testing with SLO checker.
-      // b/331020193, Move to presubmit early april 2024
+      // Tests are flaky, waiting to bypass.
       "name": "FrameworksServicesTests_pm_presubmit"
     },
     {
diff --git a/services/tests/servicestests/src/com/android/server/power/hint/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/power/hint/TEST_MAPPING
index 2d5df07..874eec7 100644
--- a/services/tests/servicestests/src/com/android/server/power/hint/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/power/hint/TEST_MAPPING
@@ -1,5 +1,5 @@
 {
-  "postsubmit": [
+  "presubmit": [
     {
       "name": "FrameworksServicesTests",
       "options": [
diff --git a/services/tests/servicestests/src/com/android/server/recoverysystem/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/recoverysystem/TEST_MAPPING
index 7e7393c..eb7453d 100644
--- a/services/tests/servicestests/src/com/android/server/recoverysystem/TEST_MAPPING
+++ b/services/tests/servicestests/src/com/android/server/recoverysystem/TEST_MAPPING
@@ -1,21 +1,7 @@
 {
-    "presubmit": [
-        {
-            "name": "FrameworksServicesTests",
-            "options": [
-                {
-                    "include-filter": "com.android.server.recoverysystem."
-                },
-                {
-                    "exclude-annotation": "androidx.test.filters.FlakyTest"
-                }
-            ]
-        }
-    ],
-    "postsubmit": [
-      {
-        // b/331020193, Move to presubmit early april 2024
-        "name": "FrameworksServicesTests_recoverysystem"
-      }
-    ]
-}
\ No newline at end of file
+  "presubmit": [
+    {
+      "name": "FrameworksServicesTests_recoverysystem"
+    }
+  ]
+}
diff --git a/services/tests/servicestests/src/com/android/server/tare/AnalystTest.java b/services/tests/servicestests/src/com/android/server/tare/AnalystTest.java
deleted file mode 100644
index a603b93..0000000
--- a/services/tests/servicestests/src/com/android/server/tare/AnalystTest.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.app.IBatteryStats;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/** Test that the Analyst processes transactions correctly. */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class AnalystTest {
-
-    @Test
-    public void testInitialState() {
-        final Analyst analyst = new Analyst();
-        assertEquals(0, analyst.getReports().size());
-    }
-
-    @Test
-    public void testBatteryLevelChange() {
-        final Analyst analyst = new Analyst();
-
-        Analyst.Report expected = new Analyst.Report();
-        expected.currentBatteryLevel = 75;
-        analyst.noteBatteryLevelChange(75);
-        assertEquals(1, analyst.getReports().size());
-        assertReportsEqual(expected, analyst.getReports().get(0));
-
-        // Discharging
-        analyst.noteBatteryLevelChange(54);
-        expected.currentBatteryLevel = 54;
-        expected.cumulativeBatteryDischarge = 21;
-        assertEquals(1, analyst.getReports().size());
-        assertReportsEqual(expected, analyst.getReports().get(0));
-        analyst.noteBatteryLevelChange(50);
-        expected.currentBatteryLevel = 50;
-        expected.cumulativeBatteryDischarge = 25;
-        assertEquals(1, analyst.getReports().size());
-        assertReportsEqual(expected, analyst.getReports().get(0));
-
-        // Charging
-        analyst.noteBatteryLevelChange(51);
-        expected.currentBatteryLevel = 51;
-        assertEquals(1, analyst.getReports().size());
-        assertReportsEqual(expected, analyst.getReports().get(0));
-        analyst.noteBatteryLevelChange(55);
-        expected.currentBatteryLevel = 55;
-        assertEquals(1, analyst.getReports().size());
-        assertReportsEqual(expected, analyst.getReports().get(0));
-
-        // Reset
-        analyst.noteBatteryLevelChange(100);
-        assertEquals(2, analyst.getReports().size());
-        assertReportsEqual(expected, analyst.getReports().get(0));
-        expected.currentBatteryLevel = 100;
-        expected.cumulativeBatteryDischarge = 0;
-        assertReportsEqual(expected, analyst.getReports().get(1));
-    }
-
-    @Test
-    public void testTransaction() {
-        runTestTransactions(new Analyst(), new Analyst.Report(), 1);
-    }
-
-    @Test
-    public void testTransaction_PeriodChange() throws Exception {
-        IBatteryStats iBatteryStats = mock(IBatteryStats.class);
-        final Analyst analyst = new Analyst(iBatteryStats);
-
-        // Reset from enough discharge.
-        Analyst.Report expected = new Analyst.Report();
-        expected.currentBatteryLevel = 75;
-        analyst.noteBatteryLevelChange(75);
-
-        runTestTransactions(analyst, expected, 1);
-
-        expected.currentBatteryLevel = 49;
-        expected.cumulativeBatteryDischarge = 26;
-        analyst.noteBatteryLevelChange(49);
-
-        runTestTransactions(analyst, expected, 1);
-
-        expected = new Analyst.Report();
-        expected.currentBatteryLevel = 90;
-        analyst.noteBatteryLevelChange(90);
-        expected.cumulativeBatteryDischarge = 0;
-
-        runTestTransactions(analyst, expected, 2);
-
-        // Reset from report being long enough.
-        doReturn(Analyst.MIN_REPORT_DURATION_FOR_RESET)
-                .when(iBatteryStats).computeBatteryScreenOffRealtimeMs();
-        expected.currentBatteryLevel = 85;
-        analyst.noteBatteryLevelChange(85);
-        expected.cumulativeBatteryDischarge = 5;
-        expected.screenOffDurationMs = Analyst.MIN_REPORT_DURATION_FOR_RESET;
-
-        runTestTransactions(analyst, expected, 2);
-
-        expected.currentBatteryLevel = 79;
-        analyst.noteBatteryLevelChange(79);
-        expected.cumulativeBatteryDischarge = 11;
-
-        runTestTransactions(analyst, expected, 2);
-
-        expected = new Analyst.Report();
-        expected.currentBatteryLevel = 80;
-        analyst.noteBatteryLevelChange(80);
-        expected.cumulativeBatteryDischarge = 0;
-        expected.screenOffDurationMs = 0;
-
-        runTestTransactions(analyst, expected, 3);
-    }
-
-    private void runTestTransactions(Analyst analyst, Analyst.Report lastExpectedReport,
-            int numExpectedReports) {
-        Analyst.Report expected = lastExpectedReport;
-
-        // Profit
-        analyst.noteTransaction(
-                new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_ACTION, null, -51, 1));
-        expected.cumulativeProfit += 50;
-        expected.numProfitableActions += 1;
-        assertEquals(numExpectedReports, analyst.getReports().size());
-        assertReportsEqual(expected, analyst.getReports().get(numExpectedReports - 1));
-
-        // Loss
-        analyst.noteTransaction(
-                new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_ACTION, null, -51, 100));
-        expected.cumulativeLoss += 49;
-        expected.numUnprofitableActions += 1;
-        assertEquals(numExpectedReports, analyst.getReports().size());
-        assertReportsEqual(expected, analyst.getReports().get(numExpectedReports - 1));
-
-        // Reward
-        analyst.noteTransaction(
-                new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_REWARD, null, 51, 0));
-        expected.cumulativeRewards += 51;
-        expected.numRewards += 1;
-        assertEquals(numExpectedReports, analyst.getReports().size());
-        assertReportsEqual(expected, analyst.getReports().get(numExpectedReports - 1));
-
-        // Regulations
-        analyst.noteTransaction(
-                new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_REGULATION, null, 25, 0));
-        expected.cumulativePositiveRegulations += 25;
-        expected.numPositiveRegulations += 1;
-        assertEquals(numExpectedReports, analyst.getReports().size());
-        assertReportsEqual(expected, analyst.getReports().get(numExpectedReports - 1));
-        analyst.noteTransaction(
-                new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_REGULATION, null, -25, 0));
-        expected.cumulativeNegativeRegulations += 25;
-        expected.numNegativeRegulations += 1;
-        assertEquals(numExpectedReports, analyst.getReports().size());
-        assertReportsEqual(expected, analyst.getReports().get(numExpectedReports - 1));
-
-        // No-ops
-        analyst.noteTransaction(
-                new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_ACTION, null, -100, 100));
-        analyst.noteTransaction(
-                new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_REGULATION, null, 0, 0));
-        analyst.noteTransaction(
-                new Ledger.Transaction(0, 1000, EconomicPolicy.TYPE_REWARD, null, 0, 0));
-        assertEquals(numExpectedReports, analyst.getReports().size());
-    }
-
-    @Test
-    public void testLoadReports() {
-        final Analyst analyst = new Analyst();
-
-        List<Analyst.Report> expected = new ArrayList<>();
-        analyst.loadReports(expected);
-        assertReportListsEqual(expected, analyst.getReports());
-
-        Analyst.Report report1 = new Analyst.Report();
-        report1.cumulativeBatteryDischarge = 1;
-        report1.currentBatteryLevel = 2;
-        report1.cumulativeProfit = 3;
-        report1.numProfitableActions = 4;
-        report1.cumulativeLoss = 5;
-        report1.numUnprofitableActions = 6;
-        report1.cumulativeRewards = 7;
-        report1.numRewards = 8;
-        report1.cumulativePositiveRegulations = 9;
-        report1.numPositiveRegulations = 10;
-        report1.cumulativeNegativeRegulations = 11;
-        report1.numNegativeRegulations = 12;
-        expected.add(report1);
-        analyst.loadReports(expected);
-        assertReportListsEqual(expected, analyst.getReports());
-
-        Analyst.Report report2 = new Analyst.Report();
-        report2.cumulativeBatteryDischarge = 10;
-        report2.currentBatteryLevel = 20;
-        report2.cumulativeProfit = 30;
-        report2.numProfitableActions = 40;
-        report2.cumulativeLoss = 50;
-        report2.numUnprofitableActions = 60;
-        report2.cumulativeRewards = 70;
-        report2.numRewards = 80;
-        report2.cumulativePositiveRegulations = 90;
-        report2.numPositiveRegulations = 100;
-        report2.cumulativeNegativeRegulations = 110;
-        report2.numNegativeRegulations = 120;
-        expected.add(report2);
-        analyst.loadReports(expected);
-        assertReportListsEqual(expected, analyst.getReports());
-    }
-
-    private void assertReportsEqual(Analyst.Report expected, Analyst.Report actual) {
-        if (expected == null) {
-            assertNull(actual);
-            return;
-        }
-        assertNotNull(actual);
-        assertEquals(expected.cumulativeBatteryDischarge, actual.cumulativeBatteryDischarge);
-        assertEquals(expected.currentBatteryLevel, actual.currentBatteryLevel);
-        assertEquals(expected.cumulativeProfit, actual.cumulativeProfit);
-        assertEquals(expected.numProfitableActions, actual.numProfitableActions);
-        assertEquals(expected.cumulativeLoss, actual.cumulativeLoss);
-        assertEquals(expected.numUnprofitableActions, actual.numUnprofitableActions);
-        assertEquals(expected.cumulativeRewards, actual.cumulativeRewards);
-        assertEquals(expected.numRewards, actual.numRewards);
-        assertEquals(expected.cumulativePositiveRegulations, actual.cumulativePositiveRegulations);
-        assertEquals(expected.numPositiveRegulations, actual.numPositiveRegulations);
-        assertEquals(expected.cumulativeNegativeRegulations, actual.cumulativeNegativeRegulations);
-        assertEquals(expected.numNegativeRegulations, actual.numNegativeRegulations);
-        assertEquals(expected.screenOffDurationMs, actual.screenOffDurationMs);
-        assertEquals(expected.screenOffDischargeMah, actual.screenOffDischargeMah);
-    }
-
-    private void assertReportListsEqual(List<Analyst.Report> expected,
-            List<Analyst.Report> actual) {
-        if (expected == null) {
-            assertNull(actual);
-            return;
-        }
-        assertNotNull(actual);
-        assertEquals(expected.size(), actual.size());
-        for (int i = 0; i < expected.size(); ++i) {
-            assertReportsEqual(expected.get(i), actual.get(i));
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/tare/LedgerTest.java b/services/tests/servicestests/src/com/android/server/tare/LedgerTest.java
deleted file mode 100644
index 54566c3..0000000
--- a/services/tests/servicestests/src/com/android/server/tare/LedgerTest.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.tare;
-
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
-import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
-
-import static com.android.server.tare.TareUtils.getCurrentTimeMillis;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import android.util.SparseLongArray;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.time.Clock;
-import java.time.Duration;
-import java.time.ZoneOffset;
-import java.util.ArrayList;
-import java.util.List;
-
-/** Test that the ledger records transactions correctly. */
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class LedgerTest {
-
-    @Before
-    public void setUp() {
-        TareUtils.sSystemClock = Clock.fixed(Clock.systemUTC().instant(), ZoneOffset.UTC);
-    }
-
-    private void shiftSystemTime(long incrementMs) {
-        TareUtils.sSystemClock =
-                Clock.offset(TareUtils.sSystemClock, Duration.ofMillis(incrementMs));
-    }
-
-    @Test
-    public void testInitialState() {
-        final Ledger ledger = new Ledger();
-        assertEquals(0, ledger.getCurrentBalance());
-        assertEquals(0, ledger.get24HourSum(0, 0));
-    }
-
-    @Test
-    public void testInitialization_FullLists() {
-        final long balance = 1234567890L;
-        List<Ledger.Transaction> transactions = new ArrayList<>();
-        List<Ledger.RewardBucket> rewardBuckets = new ArrayList<>();
-
-        final long now = getCurrentTimeMillis();
-        Ledger.Transaction secondTxn = null;
-        Ledger.RewardBucket remainingBucket = null;
-        for (int i = 0; i < Ledger.MAX_TRANSACTION_COUNT; ++i) {
-            final long start = now - 10 * HOUR_IN_MILLIS + i * MINUTE_IN_MILLIS;
-            Ledger.Transaction transaction = new Ledger.Transaction(
-                    start, start + MINUTE_IN_MILLIS, 1, null, 400, 0);
-            if (i == 1) {
-                secondTxn = transaction;
-            }
-            transactions.add(transaction);
-        }
-        for (int b = 0; b < Ledger.NUM_REWARD_BUCKET_WINDOWS; ++b) {
-            final long start = now - (Ledger.NUM_REWARD_BUCKET_WINDOWS - b) * 24 * HOUR_IN_MILLIS;
-            Ledger.RewardBucket rewardBucket = new Ledger.RewardBucket();
-            rewardBucket.startTimeMs = start;
-            for (int r = 0; r < 5; ++r) {
-                rewardBucket.cumulativeDelta.put(EconomicPolicy.TYPE_REWARD | r, b * start + r);
-            }
-            if (b == Ledger.NUM_REWARD_BUCKET_WINDOWS - 1) {
-                remainingBucket = rewardBucket;
-            }
-            rewardBuckets.add(rewardBucket);
-        }
-        final Ledger ledger = new Ledger(balance, transactions, rewardBuckets);
-        assertEquals(balance, ledger.getCurrentBalance());
-        assertEquals(transactions, ledger.getTransactions());
-        // Everything but the last bucket is old, so the returned list should only contain that
-        // bucket.
-        rewardBuckets.clear();
-        rewardBuckets.add(remainingBucket);
-        assertEquals(rewardBuckets, ledger.getRewardBuckets());
-
-        // Make sure the ledger can properly record new transactions.
-        final long start = now - MINUTE_IN_MILLIS;
-        final long delta = 400;
-        final Ledger.Transaction transaction = new Ledger.Transaction(
-                start, start + MINUTE_IN_MILLIS, EconomicPolicy.TYPE_REWARD | 1, null, delta, 0);
-        ledger.recordTransaction(transaction);
-        assertEquals(balance + delta, ledger.getCurrentBalance());
-        transactions = ledger.getTransactions();
-        assertEquals(secondTxn, transactions.get(0));
-        assertEquals(transaction, transactions.get(Ledger.MAX_TRANSACTION_COUNT - 1));
-        final Ledger.RewardBucket rewardBucket = new Ledger.RewardBucket();
-        rewardBucket.startTimeMs = now;
-        rewardBucket.cumulativeDelta.put(EconomicPolicy.TYPE_REWARD | 1, delta);
-        rewardBuckets = ledger.getRewardBuckets();
-        assertRewardBucketsEqual(remainingBucket, rewardBuckets.get(0));
-        assertRewardBucketsEqual(rewardBucket, rewardBuckets.get(1));
-    }
-
-    @Test
-    public void testInitialization_OverflowingLists() {
-        final long balance = 1234567890L;
-        final List<Ledger.Transaction> transactions = new ArrayList<>();
-        final List<Ledger.RewardBucket> rewardBuckets = new ArrayList<>();
-
-        final long now = getCurrentTimeMillis();
-        for (int i = 0; i < 2 * Ledger.MAX_TRANSACTION_COUNT; ++i) {
-            final long start = now - 20 * HOUR_IN_MILLIS + i * MINUTE_IN_MILLIS;
-            Ledger.Transaction transaction = new Ledger.Transaction(
-                    start, start + MINUTE_IN_MILLIS, 1, null, 400, 0);
-            transactions.add(transaction);
-        }
-        for (int b = 0; b < 2 * Ledger.NUM_REWARD_BUCKET_WINDOWS; ++b) {
-            final long start = now
-                    - (2 * Ledger.NUM_REWARD_BUCKET_WINDOWS - b) * 6 * HOUR_IN_MILLIS;
-            Ledger.RewardBucket rewardBucket = new Ledger.RewardBucket();
-            rewardBucket.startTimeMs = start;
-            for (int r = 0; r < 5; ++r) {
-                rewardBucket.cumulativeDelta.put(EconomicPolicy.TYPE_REWARD | r, b * start + r);
-            }
-            rewardBuckets.add(rewardBucket);
-        }
-        final Ledger ledger = new Ledger(balance, transactions, rewardBuckets);
-        assertEquals(balance, ledger.getCurrentBalance());
-        assertEquals(transactions.subList(Ledger.MAX_TRANSACTION_COUNT,
-                        2 * Ledger.MAX_TRANSACTION_COUNT),
-                ledger.getTransactions());
-        assertEquals(rewardBuckets.subList(Ledger.NUM_REWARD_BUCKET_WINDOWS,
-                        2 * Ledger.NUM_REWARD_BUCKET_WINDOWS),
-                ledger.getRewardBuckets());
-    }
-
-    @Test
-    public void testMultipleTransactions() {
-        final Ledger ledger = new Ledger();
-        ledger.recordTransaction(new Ledger.Transaction(0, 1000, 1, null, 5, 0));
-        assertEquals(5, ledger.getCurrentBalance());
-        ledger.recordTransaction(new Ledger.Transaction(2000, 2000, 1, null, 25, 0));
-        assertEquals(30, ledger.getCurrentBalance());
-        ledger.recordTransaction(new Ledger.Transaction(5000, 5500, 1, null, -10, 5));
-        assertEquals(20, ledger.getCurrentBalance());
-    }
-
-    @Test
-    public void test24HourSum() {
-        final long now = getCurrentTimeMillis();
-        final long end = now + 24 * HOUR_IN_MILLIS;
-        final int reward1 = EconomicPolicy.TYPE_REWARD | 1;
-        final int reward2 = EconomicPolicy.TYPE_REWARD | 2;
-        final Ledger ledger = new Ledger();
-
-        // First bucket
-        assertEquals(0, ledger.get24HourSum(reward1, end));
-        ledger.recordTransaction(new Ledger.Transaction(now, now + 1000, reward1, null, 500, 0));
-        assertEquals(500, ledger.get24HourSum(reward1, end));
-        assertEquals(0, ledger.get24HourSum(reward2, end));
-        ledger.recordTransaction(
-                new Ledger.Transaction(now + 2 * HOUR_IN_MILLIS, now + 3 * HOUR_IN_MILLIS,
-                        reward1, null, 2500, 0));
-        assertEquals(3000, ledger.get24HourSum(reward1, end));
-        // Second bucket
-        shiftSystemTime(7 * HOUR_IN_MILLIS); // now + 7
-        ledger.recordTransaction(
-                new Ledger.Transaction(now + 7 * HOUR_IN_MILLIS, now + 7 * HOUR_IN_MILLIS,
-                        reward1, null, 1, 0));
-        ledger.recordTransaction(
-                new Ledger.Transaction(now + 7 * HOUR_IN_MILLIS, now + 7 * HOUR_IN_MILLIS,
-                        reward2, null, 42, 0));
-        assertEquals(3001, ledger.get24HourSum(reward1, end));
-        assertEquals(42, ledger.get24HourSum(reward2, end));
-        // Third bucket
-        shiftSystemTime(12 * HOUR_IN_MILLIS); // now + 19
-        ledger.recordTransaction(
-                new Ledger.Transaction(now + 12 * HOUR_IN_MILLIS, now + 13 * HOUR_IN_MILLIS,
-                        reward1, null, 300, 0));
-        assertEquals(3301, ledger.get24HourSum(reward1, end));
-        assertRewardBucketsInOrder(ledger.getRewardBuckets());
-        // Older buckets should be excluded
-        assertEquals(301, ledger.get24HourSum(reward1, end + HOUR_IN_MILLIS));
-        assertEquals(301, ledger.get24HourSum(reward1, end + 2 * HOUR_IN_MILLIS));
-        // 2nd bucket should still be included since it started at the 7 hour mark
-        assertEquals(301, ledger.get24HourSum(reward1, end + 6 * HOUR_IN_MILLIS));
-        assertEquals(42, ledger.get24HourSum(reward2, end + 6 * HOUR_IN_MILLIS));
-        assertEquals(300, ledger.get24HourSum(reward1, end + 7 * HOUR_IN_MILLIS + 1));
-        assertEquals(0, ledger.get24HourSum(reward2, end + 8 * HOUR_IN_MILLIS));
-        assertEquals(0, ledger.get24HourSum(reward1, end + 19 * HOUR_IN_MILLIS + 1));
-    }
-
-    @Test
-    public void testRemoveOldTransactions() {
-        final Ledger ledger = new Ledger();
-        ledger.removeOldTransactions(24 * HOUR_IN_MILLIS);
-        assertNull(ledger.getEarliestTransaction());
-
-        final long now = getCurrentTimeMillis();
-        Ledger.Transaction transaction1 = new Ledger.Transaction(
-                now - 48 * HOUR_IN_MILLIS, now - 40 * HOUR_IN_MILLIS, 1, null, 4800, 0);
-        Ledger.Transaction transaction2 = new Ledger.Transaction(
-                now - 24 * HOUR_IN_MILLIS, now - 23 * HOUR_IN_MILLIS, 1, null, 600, 0);
-        Ledger.Transaction transaction3 = new Ledger.Transaction(
-                now - 22 * HOUR_IN_MILLIS, now - 21 * HOUR_IN_MILLIS, 1, null, 600, 0);
-        // Instant event
-        Ledger.Transaction transaction4 = new Ledger.Transaction(
-                now - 20 * HOUR_IN_MILLIS, now - 20 * HOUR_IN_MILLIS, 1, null, 500, 0);
-        // Recent event
-        Ledger.Transaction transaction5 = new Ledger.Transaction(
-                now - 5 * MINUTE_IN_MILLIS, now - MINUTE_IN_MILLIS, 1, null, 400, 0);
-        ledger.recordTransaction(transaction1);
-        ledger.recordTransaction(transaction2);
-        ledger.recordTransaction(transaction3);
-        ledger.recordTransaction(transaction4);
-        ledger.recordTransaction(transaction5);
-
-        assertEquals(transaction1, ledger.getEarliestTransaction());
-        ledger.removeOldTransactions(24 * HOUR_IN_MILLIS);
-        assertEquals(transaction2, ledger.getEarliestTransaction());
-        ledger.removeOldTransactions(23 * HOUR_IN_MILLIS);
-        assertEquals(transaction3, ledger.getEarliestTransaction());
-        // Shouldn't delete transaction3 yet since there's still a piece of it within the min age
-        // window.
-        ledger.removeOldTransactions(21 * HOUR_IN_MILLIS + 30 * MINUTE_IN_MILLIS);
-        assertEquals(transaction3, ledger.getEarliestTransaction());
-        // Instant event should be removed as soon as we hit the exact threshold.
-        ledger.removeOldTransactions(20 * HOUR_IN_MILLIS);
-        assertEquals(transaction5, ledger.getEarliestTransaction());
-        ledger.removeOldTransactions(0);
-        assertNull(ledger.getEarliestTransaction());
-    }
-
-    @Test
-    public void testTransactionsAlwaysInOrder() {
-        final Ledger ledger = new Ledger();
-        List<Ledger.Transaction> transactions = ledger.getTransactions();
-        assertTrue(transactions.isEmpty());
-
-        final long now = getCurrentTimeMillis();
-        Ledger.Transaction transaction1 = new Ledger.Transaction(
-                now - 48 * HOUR_IN_MILLIS, now - 40 * HOUR_IN_MILLIS, 1, null, 4800, 0);
-        Ledger.Transaction transaction2 = new Ledger.Transaction(
-                now - 24 * HOUR_IN_MILLIS, now - 23 * HOUR_IN_MILLIS, 1, null, 600, 0);
-        Ledger.Transaction transaction3 = new Ledger.Transaction(
-                now - 22 * HOUR_IN_MILLIS, now - 21 * HOUR_IN_MILLIS, 1, null, 600, 0);
-        // Instant event
-        Ledger.Transaction transaction4 = new Ledger.Transaction(
-                now - 20 * HOUR_IN_MILLIS, now - 20 * HOUR_IN_MILLIS, 1, null, 500, 0);
-
-        Ledger.Transaction transaction5 = new Ledger.Transaction(
-                now - 15 * HOUR_IN_MILLIS, now - 15 * HOUR_IN_MILLIS + MINUTE_IN_MILLIS,
-                1, null, 400, 0);
-        ledger.recordTransaction(transaction1);
-        ledger.recordTransaction(transaction2);
-        ledger.recordTransaction(transaction3);
-        ledger.recordTransaction(transaction4);
-        ledger.recordTransaction(transaction5);
-
-        transactions = ledger.getTransactions();
-        assertEquals(5, transactions.size());
-        assertTransactionsInOrder(transactions);
-
-        for (int i = 0; i < Ledger.MAX_TRANSACTION_COUNT - 5; ++i) {
-            final long start = now - 10 * HOUR_IN_MILLIS + i * MINUTE_IN_MILLIS;
-            Ledger.Transaction transaction = new Ledger.Transaction(
-                    start, start + MINUTE_IN_MILLIS, 1, null, 400, 0);
-            ledger.recordTransaction(transaction);
-        }
-        transactions = ledger.getTransactions();
-        assertEquals(Ledger.MAX_TRANSACTION_COUNT, transactions.size());
-        assertTransactionsInOrder(transactions);
-
-        long start = now - 5 * HOUR_IN_MILLIS;
-        Ledger.Transaction transactionLast5 = new Ledger.Transaction(
-                start, start + MINUTE_IN_MILLIS, 1, null, 4800, 0);
-        start = now - 4 * HOUR_IN_MILLIS;
-        Ledger.Transaction transactionLast4 = new Ledger.Transaction(
-                start, start + MINUTE_IN_MILLIS, 1, null, 600, 0);
-        start = now - 3 * HOUR_IN_MILLIS;
-        Ledger.Transaction transactionLast3 = new Ledger.Transaction(
-                start, start + MINUTE_IN_MILLIS, 1, null, 600, 0);
-        // Instant event
-        start = now - 2 * HOUR_IN_MILLIS;
-        Ledger.Transaction transactionLast2 = new Ledger.Transaction(
-                start, start, 1, null, 500, 0);
-        Ledger.Transaction transactionLast1 = new Ledger.Transaction(
-                start, start + MINUTE_IN_MILLIS, 1, null, 400, 0);
-        ledger.recordTransaction(transactionLast5);
-        ledger.recordTransaction(transactionLast4);
-        ledger.recordTransaction(transactionLast3);
-        ledger.recordTransaction(transactionLast2);
-        ledger.recordTransaction(transactionLast1);
-
-        transactions = ledger.getTransactions();
-        assertEquals(Ledger.MAX_TRANSACTION_COUNT, transactions.size());
-        assertTransactionsInOrder(transactions);
-        assertEquals(transactionLast1, transactions.get(Ledger.MAX_TRANSACTION_COUNT - 1));
-        assertEquals(transactionLast2, transactions.get(Ledger.MAX_TRANSACTION_COUNT - 2));
-        assertEquals(transactionLast3, transactions.get(Ledger.MAX_TRANSACTION_COUNT - 3));
-        assertEquals(transactionLast4, transactions.get(Ledger.MAX_TRANSACTION_COUNT - 4));
-        assertEquals(transactionLast5, transactions.get(Ledger.MAX_TRANSACTION_COUNT - 5));
-        assertFalse(transactions.contains(transaction1));
-        assertFalse(transactions.contains(transaction2));
-        assertFalse(transactions.contains(transaction3));
-        assertFalse(transactions.contains(transaction4));
-        assertFalse(transactions.contains(transaction5));
-    }
-
-    private void assertSparseLongArraysEqual(SparseLongArray expected, SparseLongArray actual) {
-        if (expected == null) {
-            assertNull(actual);
-            return;
-        }
-        assertNotNull(actual);
-        final int size = expected.size();
-        assertEquals(size, actual.size());
-        for (int i = 0; i < size; ++i) {
-            assertEquals(expected.keyAt(i), actual.keyAt(i));
-            assertEquals(expected.valueAt(i), actual.valueAt(i));
-        }
-    }
-
-    private void assertRewardBucketsEqual(Ledger.RewardBucket expected,
-            Ledger.RewardBucket actual) {
-        if (expected == null) {
-            assertNull(actual);
-            return;
-        }
-        assertNotNull(actual);
-        assertEquals(expected.startTimeMs, actual.startTimeMs);
-        assertSparseLongArraysEqual(expected.cumulativeDelta, actual.cumulativeDelta);
-    }
-
-    private void assertRewardBucketsInOrder(List<Ledger.RewardBucket> rewardBuckets) {
-        assertNotNull(rewardBuckets);
-        for (int i = 1; i < rewardBuckets.size(); ++i) {
-            final Ledger.RewardBucket prev = rewardBuckets.get(i - 1);
-            final Ledger.RewardBucket cur = rewardBuckets.get(i);
-            assertTrue("Newer bucket stored before older bucket @ index " + i
-                            + ": " + prev.startTimeMs + " vs " + cur.startTimeMs,
-                    prev.startTimeMs <= cur.startTimeMs);
-        }
-    }
-
-    private void assertTransactionsInOrder(List<Ledger.Transaction> transactions) {
-        assertNotNull(transactions);
-        for (int i = 1; i < transactions.size(); ++i) {
-            final Ledger.Transaction prev = transactions.get(i - 1);
-            final Ledger.Transaction cur = transactions.get(i);
-            assertTrue("Newer transaction stored before older transaction @ index " + i
-                            + ": " + prev.endTimeMs + " vs " + cur.endTimeMs,
-                    prev.endTimeMs <= cur.endTimeMs);
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/tare/OWNERS b/services/tests/servicestests/src/com/android/server/tare/OWNERS
deleted file mode 100644
index 217a5ed..0000000
--- a/services/tests/servicestests/src/com/android/server/tare/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include /apex/jobscheduler/service/java/com/android/server/tare/OWNERS
\ No newline at end of file
diff --git a/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java b/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java
index 06fc017..b3ec215 100644
--- a/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java
+++ b/services/tests/uiservicestests/src/com/android/server/UiServiceTestCase.java
@@ -19,10 +19,13 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
+import android.annotation.UserIdInt;
 import android.content.Intent;
 import android.content.pm.PackageManagerInternal;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.Build;
+import android.os.UserHandle;
 import android.testing.TestableContext;
 
 import androidx.test.InstrumentationRegistry;
@@ -45,10 +48,20 @@
     protected static final String PKG_P = "com.example.p";
     protected static final String PKG_R = "com.example.r";
 
+    protected static final int UID_N_MR1 = 10001;
+    protected static final int UID_O = 10002;
+    protected static final int UID_P = 10003;
+    protected static final int UID_R = 10004;
+
     @Rule
     public TestableContext mContext =
             spy(new TestableContext(InstrumentationRegistry.getContext(), null));
 
+    protected final int mUid = Binder.getCallingUid();
+    protected final @UserIdInt int mUserId = UserHandle.getUserId(mUid);
+    protected final UserHandle mUser = UserHandle.of(mUserId);
+    protected final String mPkg = mContext.getPackageName();
+
     protected TestableContext getContext() {
         return mContext;
     }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
index 77ce2f0..ad25d76 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationChannelExtractorTest.java
@@ -16,26 +16,43 @@
 
 package com.android.server.notification;
 
+import static android.app.Notification.CATEGORY_ALARM;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 
+import static android.media.AudioAttributes.USAGE_ALARM;
+import static android.media.AudioAttributes.USAGE_MEDIA;
+import static android.media.AudioAttributes.USAGE_NOTIFICATION;
+import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
+import static android.media.AudioAttributes.USAGE_UNKNOWN;
+import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
+import static com.google.common.truth.Truth.assertThat;
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNull;
 
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.app.Flags;
 import android.app.Notification;
 import android.app.NotificationChannel;
+import android.app.PendingIntent;
+import android.app.Person;
+import android.media.AudioAttributes;
+import android.net.Uri;
 import android.os.UserHandle;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.Settings;
 import android.service.notification.StatusBarNotification;
 
 import com.android.server.UiServiceTestCase;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
@@ -44,25 +61,34 @@
 
     @Mock RankingConfig mConfig;
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
+
+    NotificationChannelExtractor mExtractor;
+
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+
+        mExtractor = new NotificationChannelExtractor();
+        mExtractor.setConfig(mConfig);
+        mExtractor.initialize(mContext, null);
+    }
+
+    private NotificationRecord getRecord(NotificationChannel channel, Notification n) {
+        StatusBarNotification sbn = new StatusBarNotification("", "", 0, "", 0,
+                0, n, UserHandle.ALL, null, System.currentTimeMillis());
+        return new NotificationRecord(getContext(), sbn, channel);
     }
 
     @Test
-    public void testExtractsUpdatedChannel() {
-        NotificationChannelExtractor extractor = new NotificationChannelExtractor();
-        extractor.setConfig(mConfig);
-        extractor.initialize(mContext, null);
-
+    public void testExtractsUpdatedConversationChannel() {
         NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
-        final Notification.Builder builder = new Notification.Builder(getContext())
+        final Notification n = new Notification.Builder(getContext())
                 .setContentTitle("foo")
-                .setSmallIcon(android.R.drawable.sym_def_app_icon);
-        Notification n = builder.build();
-        StatusBarNotification sbn = new StatusBarNotification("", "", 0, "", 0,
-                0, n, UserHandle.ALL, null, System.currentTimeMillis());
-        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+        NotificationRecord r = getRecord(channel, n);
 
         NotificationChannel updatedChannel =
                 new NotificationChannel("a", "", IMPORTANCE_HIGH);
@@ -70,26 +96,19 @@
                 any(), anyInt(), eq("a"), eq(null), eq(true), eq(false)))
                 .thenReturn(updatedChannel);
 
-        assertNull(extractor.process(r));
+        assertNull(mExtractor.process(r));
         assertEquals(updatedChannel, r.getChannel());
     }
 
     @Test
-    public void testInvalidShortcutFlagEnabled_looksUpCorrectChannel() {
-
-        NotificationChannelExtractor extractor = new NotificationChannelExtractor();
-        extractor.setConfig(mConfig);
-        extractor.initialize(mContext, null);
-
+    public void testInvalidShortcutFlagEnabled_looksUpCorrectNonChannel() {
         NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
-        final Notification.Builder builder = new Notification.Builder(getContext())
+        final Notification n = new Notification.Builder(getContext())
                 .setContentTitle("foo")
                 .setStyle(new Notification.MessagingStyle("name"))
-                .setSmallIcon(android.R.drawable.sym_def_app_icon);
-        Notification n = builder.build();
-        StatusBarNotification sbn = new StatusBarNotification("", "", 0, "tag", 0,
-                0, n, UserHandle.ALL, null, System.currentTimeMillis());
-        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+        NotificationRecord r = getRecord(channel, n);
 
         NotificationChannel updatedChannel =
                 new NotificationChannel("a", "", IMPORTANCE_HIGH);
@@ -98,26 +117,19 @@
                 eq(true), eq(false)))
                 .thenReturn(updatedChannel);
 
-        assertNull(extractor.process(r));
+        assertNull(mExtractor.process(r));
         assertEquals(updatedChannel, r.getChannel());
     }
 
     @Test
     public void testInvalidShortcutFlagDisabled_looksUpCorrectChannel() {
-
-        NotificationChannelExtractor extractor = new NotificationChannelExtractor();
-        extractor.setConfig(mConfig);
-        extractor.initialize(mContext, null);
-
         NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
-        final Notification.Builder builder = new Notification.Builder(getContext())
+        final Notification n = new Notification.Builder(getContext())
                 .setContentTitle("foo")
                 .setStyle(new Notification.MessagingStyle("name"))
-                .setSmallIcon(android.R.drawable.sym_def_app_icon);
-        Notification n = builder.build();
-        StatusBarNotification sbn = new StatusBarNotification("", "", 0, "tag", 0,
-                0, n, UserHandle.ALL, null, System.currentTimeMillis());
-        NotificationRecord r = new NotificationRecord(getContext(), sbn, channel);
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+        NotificationRecord r = getRecord(channel, n);
 
         NotificationChannel updatedChannel =
                 new NotificationChannel("a", "", IMPORTANCE_HIGH);
@@ -125,7 +137,129 @@
                 any(), anyInt(), eq("a"), eq(null), eq(true), eq(false)))
                 .thenReturn(updatedChannel);
 
-        assertNull(extractor.process(r));
+        assertNull(mExtractor.process(r));
         assertEquals(updatedChannel, r.getChannel());
     }
+
+    @Test
+    @EnableFlags(Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_CALL)
+    public void testAudioAttributes_callStyleCanUseCallUsage() {
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        channel.setSound(Uri.EMPTY, new AudioAttributes.Builder()
+                .setUsage(USAGE_NOTIFICATION_RINGTONE)
+                .build());
+        final Notification n = new Notification.Builder(getContext())
+                .setContentTitle("foo")
+                .setStyle(Notification.CallStyle.forIncomingCall(
+                        new Person.Builder().setName("A Caller").build(),
+                        mock(PendingIntent.class),
+                        mock(PendingIntent.class)
+                ))
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+        NotificationRecord r = getRecord(channel, n);
+
+        assertThat(mExtractor.process(r)).isNull();
+        assertThat(r.getAudioAttributes().getUsage()).isEqualTo(USAGE_NOTIFICATION_RINGTONE);
+        assertThat(r.getChannel()).isEqualTo(channel);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_CALL)
+    public void testAudioAttributes_nonCallStyleCannotUseCallUsage() {
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        channel.setSound(Uri.EMPTY, new AudioAttributes.Builder()
+                .setUsage(USAGE_NOTIFICATION_RINGTONE)
+                .build());
+        final Notification n = new Notification.Builder(getContext())
+                .setContentTitle("foo")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+        NotificationRecord r = getRecord(channel, n);
+
+        assertThat(mExtractor.process(r)).isNull();
+        // instance updated
+        assertThat(r.getAudioAttributes().getUsage()).isEqualTo(USAGE_NOTIFICATION);
+        // in-memory channel unchanged
+        assertThat(channel.getAudioAttributes().getUsage()).isEqualTo(USAGE_NOTIFICATION_RINGTONE);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_ALARM)
+    public void testAudioAttributes_alarmCategoryCanUseAlarmUsage() {
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        channel.setSound(Uri.EMPTY, new AudioAttributes.Builder()
+                .setUsage(USAGE_ALARM)
+                .build());
+        final Notification n = new Notification.Builder(getContext())
+                .setContentTitle("foo")
+                .setCategory(CATEGORY_ALARM)
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+        NotificationRecord r = getRecord(channel, n);
+
+        assertThat(mExtractor.process(r)).isNull();
+        assertThat(r.getAudioAttributes().getUsage()).isEqualTo(USAGE_ALARM);
+        assertThat(r.getChannel()).isEqualTo(channel);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_ALARM)
+    public void testAudioAttributes_nonAlarmCategoryCannotUseAlarmUsage() {
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        channel.setSound(Uri.EMPTY, new AudioAttributes.Builder()
+                .setUsage(USAGE_ALARM)
+                .build());
+        final Notification n = new Notification.Builder(getContext())
+                .setContentTitle("foo")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+        NotificationRecord r = getRecord(channel, n);
+
+        assertThat(mExtractor.process(r)).isNull();
+        // instance updated
+        assertThat(r.getAudioAttributes().getUsage()).isEqualTo(USAGE_NOTIFICATION);
+        // in-memory channel unchanged
+        assertThat(channel.getAudioAttributes().getUsage()).isEqualTo(USAGE_ALARM);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_MEDIA)
+    public void testAudioAttributes_noMediaUsage() {
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        channel.setSound(Uri.EMPTY, new AudioAttributes.Builder()
+                .setUsage(USAGE_MEDIA)
+                .build());
+        final Notification n = new Notification.Builder(getContext())
+                .setContentTitle("foo")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+        NotificationRecord r = getRecord(channel, n);
+
+        assertThat(mExtractor.process(r)).isNull();
+        // instance updated
+        assertThat(r.getAudioAttributes().getUsage()).isEqualTo(USAGE_NOTIFICATION);
+        // in-memory channel unchanged
+        assertThat(channel.getAudioAttributes().getUsage()).isEqualTo(USAGE_MEDIA);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_MEDIA)
+    public void testAudioAttributes_noUnknownUsage() {
+        NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        channel.setSound(Uri.EMPTY, new AudioAttributes.Builder()
+                .setUsage(USAGE_UNKNOWN)
+                .build());
+        final Notification n = new Notification.Builder(getContext())
+                .setContentTitle("foo")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+        NotificationRecord r = getRecord(channel, n);
+
+        assertThat(mExtractor.process(r)).isNull();
+        // instance updated
+        assertThat(r.getAudioAttributes().getUsage()).isEqualTo(USAGE_NOTIFICATION);
+        // in-memory channel unchanged
+        assertThat(channel.getAudioAttributes().getUsage()).isEqualTo(USAGE_UNKNOWN);
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 39a962d..6106278 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -35,6 +35,7 @@
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
 import static android.app.Notification.FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
 import static android.app.Notification.FLAG_NO_CLEAR;
+import static android.app.Notification.FLAG_NO_DISMISS;
 import static android.app.Notification.FLAG_ONGOING_EVENT;
 import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
 import static android.app.Notification.FLAG_USER_INITIATED_JOB;
@@ -72,6 +73,8 @@
 import static android.content.pm.PackageManager.FEATURE_WATCH;
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.media.AudioAttributes.USAGE_MEDIA;
+import static android.media.AudioAttributes.USAGE_NOTIFICATION;
 import static android.os.Build.VERSION_CODES.O_MR1;
 import static android.os.Build.VERSION_CODES.P;
 import static android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE;
@@ -103,20 +106,22 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
+
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
 import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
 import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
 import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
 import static com.android.server.notification.NotificationManagerService.BITMAP_DURATION;
 import static com.android.server.notification.NotificationManagerService.DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
+import static com.android.server.notification.NotificationManagerService.NOTIFICATION_TTL;
 import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_ADJUSTED;
 import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED;
 import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_UPDATED;
+
 import static com.google.common.collect.Iterables.getOnlyElement;
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
-import static java.util.Collections.emptyList;
-import static java.util.Collections.singletonList;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
@@ -125,6 +130,7 @@
 import static junit.framework.Assert.assertSame;
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.fail;
+
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertThrows;
 import static org.mockito.ArgumentMatchers.isNull;
@@ -134,6 +140,9 @@
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.*;
 
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
+
 import android.Manifest;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
@@ -186,6 +195,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.drawable.Icon;
+import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.session.MediaSession;
 import android.net.Uri;
@@ -238,8 +248,10 @@
 import android.util.Pair;
 import android.util.Xml;
 import android.widget.RemoteViews;
+
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
+
 import com.android.internal.R;
 import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
 import com.android.internal.config.sysui.TestableFlagResolver;
@@ -270,10 +282,13 @@
 import com.android.server.utils.quota.MultiRateLimiter;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
+
 import com.google.android.collect.Lists;
 import com.google.common.collect.ImmutableList;
+
 import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
+
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -331,9 +346,6 @@
                     .setOwner(new ComponentName("pkg", "cls"))
                     .build();
 
-    private final int mUid = Binder.getCallingUid();
-    private final @UserIdInt int mUserId = UserHandle.getUserId(mUid);
-
     @ClassRule
     public static final LimitDevicesRule sLimitDevicesRule = new LimitDevicesRule();
 
@@ -357,7 +369,6 @@
     @Mock
     private PermissionHelper mPermissionHelper;
     private NotificationChannelLoggerFake mLogger = new NotificationChannelLoggerFake();
-    private final String PKG = mContext.getPackageName();
     private TestableLooper mTestableLooper;
     @Mock
     private RankingHelper mRankingHelper;
@@ -566,8 +577,8 @@
         when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
         when(mPackageManagerClient.hasSystemFeature(FEATURE_WATCH)).thenReturn(false);
         when(mUgmInternal.newUriPermissionOwner(anyString())).thenReturn(mPermOwner);
-        when(mPackageManager.getPackagesForUid(mUid)).thenReturn(new String[]{PKG});
-        when(mPackageManagerClient.getPackagesForUid(anyInt())).thenReturn(new String[]{PKG});
+        when(mPackageManager.getPackagesForUid(mUid)).thenReturn(new String[]{mPkg});
+        when(mPackageManagerClient.getPackagesForUid(anyInt())).thenReturn(new String[]{mPkg});
         when(mAtm.getTaskToShowPermissionDialogOn(anyString(), anyInt()))
                 .thenReturn(INVALID_TASK_ID);
         mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
@@ -599,7 +610,7 @@
         when(mNlf.isPackageAllowed(null)).thenReturn(true);
         when(mListeners.getNotificationListenerFilter(any())).thenReturn(mNlf);
         mListener = mListeners.new ManagedServiceInfo(
-                null, new ComponentName(PKG, "test_class"),
+                null, new ComponentName(mPkg, "test_class"),
                 mUserId, true, null, 0, 123);
         ComponentName defaultComponent = ComponentName.unflattenFromString("config/device");
         ArraySet<ComponentName> components = new ArraySet<>();
@@ -743,7 +754,7 @@
         // Pretend the shortcut exists
         List<ShortcutInfo> shortcutInfos = new ArrayList<>();
         ShortcutInfo info = mock(ShortcutInfo.class);
-        when(info.getPackage()).thenReturn(PKG);
+        when(info.getPackage()).thenReturn(mPkg);
         when(info.getId()).thenReturn(VALID_CONVO_SHORTCUT_ID);
         when(info.getUserId()).thenReturn(USER_SYSTEM);
         when(info.isLongLived()).thenReturn(true);
@@ -765,16 +776,16 @@
         mBinderService = mService.getBinderService();
         mInternalService = mService.getInternalService();
 
-        mBinderService.createNotificationChannels(PKG, new ParceledListSlice(
+        mBinderService.createNotificationChannels(mPkg, new ParceledListSlice(
                 Arrays.asList(mTestNotificationChannel, mSilentChannel)));
         mBinderService.createNotificationChannels(PKG_P, new ParceledListSlice(
                 Arrays.asList(mTestNotificationChannel, mSilentChannel)));
         mBinderService.createNotificationChannels(PKG_O, new ParceledListSlice(
                 Arrays.asList(mTestNotificationChannel, mSilentChannel)));
         assertNotNull(mBinderService.getNotificationChannel(
-                PKG, mContext.getUserId(), PKG, TEST_CHANNEL_ID));
+                mPkg, mContext.getUserId(), mPkg, TEST_CHANNEL_ID));
         assertNotNull(mBinderService.getNotificationChannel(
-                PKG, mContext.getUserId(), PKG, mSilentChannel.getId()));
+                mPkg, mContext.getUserId(), mPkg, mSilentChannel.getId()));
         clearInvocations(mRankingHandler);
         when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
 
@@ -976,7 +987,7 @@
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
                 .setGroup(groupKey)
                 .setGroupSummary(isSummary);
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id,
                 tag, mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         return new NotificationRecord(mContext, sbn, channel);
@@ -998,14 +1009,14 @@
         if (extender != null) {
             nb.extend(extender);
         }
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         return new NotificationRecord(mContext, sbn, channel);
     }
 
     private NotificationRecord generateNotificationRecord(NotificationChannel channel,
             long postTime) {
-        final StatusBarNotification sbn = generateSbn(PKG, mUid, postTime, mUserId);
+        final StatusBarNotification sbn = generateSbn(mPkg, mUid, postTime, mUserId);
         return new NotificationRecord(mContext, sbn, channel);
     }
 
@@ -1026,7 +1037,7 @@
         Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
                 .setContentTitle(title)
                 .setSmallIcon(android.R.drawable.sym_def_app_icon);
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, "tag", mUid, 0,
                 nb.build(), new UserHandle(userId), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, channel);
         return r;
@@ -1046,7 +1057,7 @@
             tag = "tag";
         }
         Notification.Builder nb = getMessageStyleNotifBuilder(addMetadata, groupKey, isSummary);
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, id,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id,
                 tag, mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         return new NotificationRecord(mContext, sbn, channel);
@@ -1058,7 +1069,7 @@
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
                 .setContentText(REDACTED_TEXT);
-        return new StatusBarNotification(PKG, PKG, id, "tag", mUid, 0,
+        return new StatusBarNotification(mPkg, mPkg, id, "tag", mUid, 0,
                 nb.build(), new UserHandle(userId), null, 0);
     }
 
@@ -1180,13 +1191,13 @@
         NotificationRecord nrBubble = generateMessageBubbleNotifRecord(true /* addMetadata */,
                 mTestNotificationChannel, 1 /* id */, "tag", groupKey, false /* isSummary */);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nrBubble.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nrBubble.getSbn().getTag(),
                 nrBubble.getSbn().getId(), nrBubble.getSbn().getNotification(),
                 nrBubble.getSbn().getUserId());
         waitForIdle();
 
         // Make sure we are a bubble
-        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifsAfter.length);
         assertTrue((notifsAfter[0].getNotification().flags & FLAG_BUBBLE) != 0);
 
@@ -1194,12 +1205,12 @@
         NotificationRecord nrPlain = generateMessageBubbleNotifRecord(false /* addMetadata */,
                 mTestNotificationChannel, 2 /* id */, "tag", groupKey, false /* isSummary */);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nrPlain.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nrPlain.getSbn().getTag(),
                 nrPlain.getSbn().getId(), nrPlain.getSbn().getNotification(),
                 nrPlain.getSbn().getUserId());
         waitForIdle();
 
-        notifsAfter = mBinderService.getActiveNotifications(PKG);
+        notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertEquals(2, notifsAfter.length);
 
         // Summary notification for both of those
@@ -1209,12 +1220,12 @@
         if (summaryAutoCancel) {
             nrSummary.getNotification().flags |= FLAG_AUTO_CANCEL;
         }
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nrSummary.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nrSummary.getSbn().getTag(),
                 nrSummary.getSbn().getId(), nrSummary.getSbn().getNotification(),
                 nrSummary.getSbn().getUserId());
         waitForIdle();
 
-        notifsAfter = mBinderService.getActiveNotifications(PKG);
+        notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertEquals(3, notifsAfter.length);
 
         return nrSummary;
@@ -1229,7 +1240,7 @@
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
                 .setTimeoutAfter(1);
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, channel);
 
@@ -1269,17 +1280,17 @@
     public void testCreateNotificationChannels_SingleChannel() throws Exception {
         final NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(channel)));
         final NotificationChannel createdChannel =
-                mBinderService.getNotificationChannel(PKG, mContext.getUserId(), PKG, "id");
+                mBinderService.getNotificationChannel(mPkg, mContext.getUserId(), mPkg, "id");
         assertTrue(createdChannel != null);
     }
 
     @Test
     public void testCreateNotificationChannels_NullChannelThrowsException() throws Exception {
         try {
-            mBinderService.createNotificationChannels(PKG,
+            mBinderService.createNotificationChannels(mPkg,
                     new ParceledListSlice(Arrays.asList((Object[])null)));
             fail("Exception should be thrown immediately.");
         } catch (NullPointerException e) {
@@ -1304,11 +1315,11 @@
     public void testCreateNotificationChannels_SecondChannelWithFgndTaskDoesntStartPermDialog()
             throws Exception {
         when(mAtm.getTaskToShowPermissionDialogOn(anyString(), anyInt())).thenReturn(TEST_TASK_ID);
-        assertTrue(mBinderService.getNumNotificationChannelsForPackage(PKG, mUid, true) > 0);
+        assertTrue(mBinderService.getNumNotificationChannelsForPackage(mPkg, mUid, true) > 0);
 
         final NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(channel)));
         verify(mWorkerHandler, never()).post(any(
                 NotificationManagerService.ShowNotificationPermissionPromptRunnable.class));
@@ -1322,7 +1333,7 @@
 
         final NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(channel)));
 
         verify(mWorkerHandler, never()).post(any(
@@ -1335,12 +1346,12 @@
                 new NotificationChannel("id1", "name", IMPORTANCE_DEFAULT);
         final NotificationChannel channel2 =
                 new NotificationChannel("id2", "name", IMPORTANCE_DEFAULT);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(channel1, channel2)));
         assertTrue(mBinderService.getNotificationChannel(
-                PKG, mContext.getUserId(), PKG, "id1") != null);
+                mPkg, mContext.getUserId(), mPkg, "id1") != null);
         assertTrue(mBinderService.getNotificationChannel(
-                PKG, mContext.getUserId(), PKG, "id2") != null);
+                mPkg, mContext.getUserId(), mPkg, "id2") != null);
     }
 
     @Test
@@ -1348,16 +1359,16 @@
             throws Exception {
         final NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(channel)));
 
         // Recreating the channel doesn't throw, but ignores importance.
         final NotificationChannel dupeChannel =
                 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(dupeChannel)));
         final NotificationChannel createdChannel =
-                mBinderService.getNotificationChannel(PKG, mContext.getUserId(), PKG, "id");
+                mBinderService.getNotificationChannel(mPkg, mContext.getUserId(), mPkg, "id");
         assertEquals(IMPORTANCE_DEFAULT, createdChannel.getImportance());
     }
 
@@ -1366,16 +1377,16 @@
             throws Exception {
         final NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(channel)));
 
         // Recreating with a lower importance is allowed to modify the channel.
         final NotificationChannel dupeChannel =
                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(dupeChannel)));
         final NotificationChannel createdChannel =
-                mBinderService.getNotificationChannel(PKG, mContext.getUserId(), PKG, "id");
+                mBinderService.getNotificationChannel(mPkg, mContext.getUserId(), mPkg, "id");
         assertEquals(NotificationManager.IMPORTANCE_LOW, createdChannel.getImportance());
     }
 
@@ -1384,21 +1395,21 @@
             throws Exception {
         final NotificationChannel channel =
                 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(channel)));
 
         // The user modifies importance directly, can no longer be changed by the app.
         final NotificationChannel updatedChannel =
                 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
-        mBinderService.updateNotificationChannelForPackage(PKG, mUid, updatedChannel);
+        mBinderService.updateNotificationChannelForPackage(mPkg, mUid, updatedChannel);
 
         // Recreating with a lower importance leaves channel unchanged.
         final NotificationChannel dupeChannel =
                 new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(dupeChannel)));
         final NotificationChannel createdChannel =
-                mBinderService.getNotificationChannel(PKG, mContext.getUserId(), PKG, "id");
+                mBinderService.getNotificationChannel(mPkg, mContext.getUserId(), mPkg, "id");
         assertEquals(IMPORTANCE_HIGH, createdChannel.getImportance());
     }
 
@@ -1409,10 +1420,10 @@
                 new NotificationChannel("id", "name", IMPORTANCE_DEFAULT);
         final NotificationChannel channel2 =
                 new NotificationChannel("id", "name", IMPORTANCE_HIGH);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(channel1, channel2)));
         final NotificationChannel createdChannel =
-                mBinderService.getNotificationChannel(PKG, mContext.getUserId(), PKG, "id");
+                mBinderService.getNotificationChannel(mPkg, mContext.getUserId(), mPkg, "id");
         assertEquals(IMPORTANCE_DEFAULT, createdChannel.getImportance());
     }
 
@@ -1438,9 +1449,9 @@
         assertTrue(mService.isRecordBlockedLocked(r));
 
         mBinderService.createNotificationChannels(
-                PKG, new ParceledListSlice(Arrays.asList(channel)));
+                mPkg, new ParceledListSlice(Arrays.asList(channel)));
         final StatusBarNotification sbn = generateNotificationRecord(channel).getSbn();
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testBlockedNotifications_blockedChannel",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         waitForIdle();
@@ -1457,18 +1468,18 @@
         NotificationChannel channel = new NotificationChannel("blocked", "name",
                 NotificationManager.IMPORTANCE_NONE);
         mBinderService.createNotificationChannels(
-                PKG, new ParceledListSlice(Arrays.asList(channel)));
+                mPkg, new ParceledListSlice(Arrays.asList(channel)));
 
         final StatusBarNotification sbn = generateNotificationRecord(channel).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, sbn.getTag(),
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         waitForIdle();
         assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
         assertEquals(IMPORTANCE_LOW,
                 mService.getNotificationRecord(sbn.getKey()).getImportance());
         assertEquals(IMPORTANCE_LOW, mBinderService.getNotificationChannel(
-                PKG, mContext.getUserId(), PKG, channel.getId()).getImportance());
+                mPkg, mContext.getUserId(), mPkg, channel.getId()).getImportance());
     }
 
     @Test
@@ -1481,18 +1492,18 @@
         NotificationChannel channel =
                 new NotificationChannel("blockedbyuser", "name", IMPORTANCE_HIGH);
         mBinderService.createNotificationChannels(
-                PKG, new ParceledListSlice(Arrays.asList(channel)));
+                mPkg, new ParceledListSlice(Arrays.asList(channel)));
 
         NotificationChannel update =
                 new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE);
-        mBinderService.updateNotificationChannelForPackage(PKG, mUid, update);
+        mBinderService.updateNotificationChannelForPackage(mPkg, mUid, update);
         waitForIdle();
         assertEquals(IMPORTANCE_NONE, mBinderService.getNotificationChannel(
-                PKG, mContext.getUserId(), PKG, channel.getId()).getImportance());
+                mPkg, mContext.getUserId(), mPkg, channel.getId()).getImportance());
 
         StatusBarNotification sbn = generateNotificationRecord(channel).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, sbn.getTag(),
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         waitForIdle();
         // The first time a foreground service notification is shown, we allow the channel
@@ -1501,20 +1512,20 @@
         assertEquals(IMPORTANCE_LOW,
                 mService.getNotificationRecord(sbn.getKey()).getImportance());
         assertEquals(IMPORTANCE_LOW, mBinderService.getNotificationChannel(
-                PKG, mContext.getUserId(), PKG, channel.getId()).getImportance());
-        mBinderService.cancelNotificationWithTag(PKG, PKG, "tag", sbn.getId(), sbn.getUserId());
+                mPkg, mContext.getUserId(), mPkg, channel.getId()).getImportance());
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, "tag", sbn.getId(), sbn.getUserId());
         waitForIdle();
 
         update = new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE);
         update.setUserVisibleTaskShown(true);
-        mBinderService.updateNotificationChannelForPackage(PKG, mUid, update);
+        mBinderService.updateNotificationChannelForPackage(mPkg, mUid, update);
         waitForIdle();
         assertEquals(IMPORTANCE_NONE, mBinderService.getNotificationChannel(
-                PKG, mContext.getUserId(), PKG, channel.getId()).getImportance());
+                mPkg, mContext.getUserId(), mPkg, channel.getId()).getImportance());
 
         sbn = generateNotificationRecord(channel).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testEnqueuedBlockedNotifications_userBlockedChannelForegroundService",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         waitForIdle();
@@ -1522,7 +1533,7 @@
         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
         assertNull(mService.getNotificationRecord(sbn.getKey()));
         assertEquals(IMPORTANCE_NONE, mBinderService.getNotificationChannel(
-                PKG, mContext.getUserId(), PKG, channel.getId()).getImportance());
+                mPkg, mContext.getUserId(), mPkg, channel.getId()).getImportance());
     }
 
     @Test
@@ -1545,7 +1556,7 @@
         when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
 
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testEnqueuedBlockedNotifications_blockedApp",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         waitForIdle();
@@ -1561,7 +1572,7 @@
 
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testEnqueuedBlockedNotifications_blockedAppForegroundService",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         waitForIdle();
@@ -1590,12 +1601,12 @@
             final StatusBarNotification sbn =
                     generateNotificationRecord(mTestNotificationChannel, ++id, "", false).getSbn();
             sbn.getNotification().category = category;
-            mBinderService.enqueueNotificationWithTag(PKG, PKG,
+            mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                     "testEnqueuedRestrictedNotifications_asSystem",
                     sbn.getId(), sbn.getNotification(), sbn.getUserId());
         }
         waitForIdle();
-        assertEquals(categories.size(), mBinderService.getActiveNotifications(PKG).length);
+        assertEquals(categories.size(), mBinderService.getActiveNotifications(mPkg).length);
     }
 
 
@@ -1614,12 +1625,12 @@
             final StatusBarNotification sbn =
                     generateNotificationRecord(mTestNotificationChannel, ++id, "", false).getSbn();
             sbn.getNotification().category = category;
-            mBinderService.enqueueNotificationWithTag(PKG, PKG,
+            mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                     "testEnqueuedRestrictedNotifications_notAutomotive",
                     sbn.getId(), sbn.getNotification(), sbn.getUserId());
         }
         waitForIdle();
-        assertEquals(categories.size(), mBinderService.getActiveNotifications(PKG).length);
+        assertEquals(categories.size(), mBinderService.getActiveNotifications(mPkg).length);
     }
 
     /**
@@ -1637,7 +1648,7 @@
             final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
             sbn.getNotification().category = category;
             try {
-                mBinderService.enqueueNotificationWithTag(PKG, PKG,
+                mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                         "testEnqueuedRestrictedNotifications_badUser",
                         sbn.getId(), sbn.getNotification(), sbn.getUserId());
                 fail("Calls from non system apps should not allow use of restricted categories");
@@ -1646,7 +1657,7 @@
             }
         }
         waitForIdle();
-        assertEquals(0, mBinderService.getActiveNotifications(PKG).length);
+        assertEquals(0, mBinderService.getActiveNotifications(mPkg).length);
     }
 
     @Test
@@ -1726,7 +1737,7 @@
         NotificationRecord nr = generateNotificationRecord(
                 new NotificationChannel("did not create", "", IMPORTANCE_DEFAULT));
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -1736,7 +1747,7 @@
         reset(mPermissionHelper);
         when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -1748,7 +1759,7 @@
     public void testEnqueueNotification_appBlocked() throws Exception {
         when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testEnqueueNotification_appBlocked", 0,
                 generateNotificationRecord(null).getNotification(), mUserId);
         waitForIdle();
@@ -1758,11 +1769,11 @@
 
     @Test
     public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
                 generateNotificationRecord(null).getNotification(), mUserId);
         waitForIdle();
-        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifs.length);
         assertEquals(1, mService.getNotificationRecordCount());
     }
@@ -1770,7 +1781,7 @@
     @Test
     public void testEnqueueNotificationWithTag_WritesExpectedLogs() throws Exception {
         final String tag = "testEnqueueNotificationWithTag_WritesExpectedLog";
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, tag, 0,
                 generateNotificationRecord(null).getNotification(), mUserId);
         waitForIdle();
         assertEquals(1, mNotificationRecordLogger.numCalls());
@@ -1782,7 +1793,7 @@
         assertNull(call.old);
         assertEquals(0, call.position);
         assertEquals(0, call.buzzBeepBlink);
-        assertEquals(PKG, call.r.getSbn().getPackageName());
+        assertEquals(mPkg, call.r.getSbn().getPackageName());
         assertEquals(0, call.r.getSbn().getId());
         assertEquals(tag, call.r.getSbn().getTag());
         assertEquals(1, call.getInstanceId());  // Fake instance IDs are assigned in order
@@ -1795,12 +1806,12 @@
         Notification original = new Notification.Builder(mContext,
                 mTestNotificationChannel.getId())
                 .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, original, mUserId);
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, tag, 0, original, mUserId);
         Notification update = new Notification.Builder(mContext,
                 mTestNotificationChannel.getId())
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
                 .setCategory(Notification.CATEGORY_ALARM).build();
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, update, mUserId);
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, tag, 0, update, mUserId);
         waitForIdle();
         assertEquals(2, mNotificationRecordLogger.numCalls());
 
@@ -1819,9 +1830,9 @@
     @Test
     public void testEnqueueNotificationWithTag_DoesNotLogOnMinorUpdate() throws Exception {
         final String tag = "testEnqueueNotificationWithTag_DoesNotLogOnMinorUpdate";
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, tag, 0,
                 generateNotificationRecord(null).getNotification(), mUserId);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, tag, 0,
                 generateNotificationRecord(null).getNotification(), mUserId);
         waitForIdle();
         assertEquals(2, mNotificationRecordLogger.numCalls());
@@ -1834,12 +1845,12 @@
     @Test
     public void testEnqueueNotificationWithTag_DoesNotLogOnTitleUpdate() throws Exception {
         final String tag = "testEnqueueNotificationWithTag_DoesNotLogOnTitleUpdate";
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, tag, 0,
                 generateNotificationRecord(null).getNotification(),
                 mUserId);
         final Notification notif = generateNotificationRecord(null).getNotification();
         notif.extras.putString(Notification.EXTRA_TITLE, "Changed title");
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, notif, mUserId);
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, tag, 0, notif, mUserId);
         waitForIdle();
         assertEquals(2, mNotificationRecordLogger.numCalls());
         assertEquals(NOTIFICATION_POSTED, mNotificationRecordLogger.event(0));
@@ -1852,11 +1863,11 @@
         Notification notification = new Notification.Builder(mContext,
                 mTestNotificationChannel.getId())
                 .setSmallIcon(android.R.drawable.sym_def_app_icon).build();
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, notification, mUserId);
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, tag, 0, notification, mUserId);
         waitForIdle();
-        mBinderService.cancelNotificationWithTag(PKG, PKG, tag, 0, mUserId);
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, tag, 0, mUserId);
         waitForIdle();
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, tag, 0, notification, mUserId);
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, tag, 0, notification, mUserId);
         waitForIdle();
         assertEquals(3, mNotificationRecordLogger.numCalls());
 
@@ -1893,14 +1904,14 @@
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
                 .setFlag(FLAG_FOREGROUND_SERVICE, true)
                 .build();
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, tag, mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, tag, mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, tag,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, tag,
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         waitForIdle();
 
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(PKG);
+                mBinderService.getActiveNotifications(mPkg);
         assertThat(notifs[0].getNotification().flags).isEqualTo(
                 FLAG_FOREGROUND_SERVICE | FLAG_CAN_COLORIZE | FLAG_NO_CLEAR);
     }
@@ -1916,10 +1927,10 @@
                 .build();
         n.actions[1] = null;
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, n, mUserId);
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 0, n, mUserId);
         waitForIdle();
 
-        StatusBarNotification[] posted = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] posted = mBinderService.getActiveNotifications(mPkg);
         assertThat(posted).hasLength(1);
         assertThat(posted[0].getNotification().actions).hasLength(2);
         assertThat(posted[0].getNotification().actions[0].title.toString()).isEqualTo("one");
@@ -1937,17 +1948,17 @@
         n.actions[0] = null;
         n.actions[1] = null;
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, n, mUserId);
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 0, n, mUserId);
         waitForIdle();
 
-        StatusBarNotification[] posted = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] posted = mBinderService.getActiveNotifications(mPkg);
         assertThat(posted).hasLength(1);
         assertThat(posted[0].getNotification().actions).isNull();
     }
 
     @Test
     public void enqueueNotificationWithTag_usesAndFinishesTracker() throws Exception {
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
                 generateNotificationRecord(null).getNotification(), mUserId);
 
@@ -1956,7 +1967,7 @@
 
         waitForIdle();
 
-        assertThat(mBinderService.getActiveNotifications(PKG)).hasLength(1);
+        assertThat(mBinderService.getActiveNotifications(mPkg)).hasLength(1);
         assertThat(mPostNotificationTrackerFactory.mCreatedTrackers).hasSize(1);
         assertThat(mPostNotificationTrackerFactory.mCreatedTrackers.get(0).isOngoing()).isFalse();
     }
@@ -1965,13 +1976,13 @@
     public void enqueueNotificationWithTag_throws_usesAndCancelsTracker() throws Exception {
         // Simulate not enqueued due to rejected inputs.
         assertThrows(Exception.class,
-                () -> mBinderService.enqueueNotificationWithTag(PKG, PKG,
+                () -> mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                         "testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
                         /* notification= */ null, mUserId));
 
         waitForIdle();
 
-        assertThat(mBinderService.getActiveNotifications(PKG)).hasLength(0);
+        assertThat(mBinderService.getActiveNotifications(mPkg)).hasLength(0);
         assertThat(mPostNotificationTrackerFactory.mCreatedTrackers).hasSize(1);
         assertThat(mPostNotificationTrackerFactory.mCreatedTrackers.get(0).isOngoing()).isFalse();
     }
@@ -1982,12 +1993,12 @@
         when(mSnoozeHelper.getSnoozeContextForUnpostedNotification(anyInt(), any(), any()))
                 .thenReturn("zzzzzzz");
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
                 generateNotificationRecord(null).getNotification(), mUserId);
         waitForIdle();
 
-        assertThat(mBinderService.getActiveNotifications(PKG)).hasLength(0);
+        assertThat(mBinderService.getActiveNotifications(mPkg)).hasLength(0);
         assertThat(mPostNotificationTrackerFactory.mCreatedTrackers).hasSize(1);
         assertThat(mPostNotificationTrackerFactory.mCreatedTrackers.get(0).isOngoing()).isFalse();
     }
@@ -1997,19 +2008,19 @@
         // Simulate not posted due to blocked app.
         when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testEnqueueNotificationWithTag_PopulatesGetActiveNotifications", 0,
                 generateNotificationRecord(null).getNotification(), mUserId);
         waitForIdle();
 
-        assertThat(mBinderService.getActiveNotifications(PKG)).hasLength(0);
+        assertThat(mBinderService.getActiveNotifications(mPkg)).hasLength(0);
         assertThat(mPostNotificationTrackerFactory.mCreatedTrackers).hasSize(1);
         assertThat(mPostNotificationTrackerFactory.mCreatedTrackers.get(0).isOngoing()).isFalse();
     }
 
     @Test
     public void enqueueNotification_acquiresAndReleasesWakeLock() throws Exception {
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "enqueueNotification_acquiresAndReleasesWakeLock", 0,
                 generateNotificationRecord(null).getNotification(), mUserId);
 
@@ -2027,7 +2038,7 @@
     public void enqueueNotification_throws_acquiresAndReleasesWakeLock() throws Exception {
         // Simulate not enqueued due to rejected inputs.
         assertThrows(Exception.class,
-                () -> mBinderService.enqueueNotificationWithTag(PKG, PKG,
+                () -> mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                         "enqueueNotification_throws_acquiresAndReleasesWakeLock", 0,
                         /* notification= */ null, mUserId));
 
@@ -2042,7 +2053,7 @@
         when(mSnoozeHelper.getSnoozeContextForUnpostedNotification(anyInt(), any(), any()))
                 .thenReturn("zzzzzzz");
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "enqueueNotification_notEnqueued_acquiresAndReleasesWakeLock", 0,
                 generateNotificationRecord(null).getNotification(), mUserId);
 
@@ -2063,7 +2074,7 @@
                 .setContentTitle("foo")
                 .build();
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "enqueueNotification_notPosted_acquiresAndReleasesWakeLock", 0,
                 notif, mUserId);
 
@@ -2088,14 +2099,14 @@
         WakeLock wakeLock = mock(WakeLock.class);
         when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(wakeLock);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "enqueueNotification_setsWakeLockWorkSource", 0,
                 generateNotificationRecord(null).getNotification(), mUserId);
         waitForIdle();
 
         InOrder inOrder = inOrder(mPowerManager, wakeLock);
         inOrder.verify(mPowerManager).newWakeLock(eq(PARTIAL_WAKE_LOCK), anyString());
-        inOrder.verify(wakeLock).setWorkSource(eq(new WorkSource(mUid, PKG)));
+        inOrder.verify(wakeLock).setWorkSource(eq(new WorkSource(mUid, mPkg)));
         inOrder.verify(wakeLock).acquire(anyLong());
         inOrder.verify(wakeLock).release();
         inOrder.verifyNoMoreInteractions();
@@ -2103,7 +2114,7 @@
 
     @Test
     public void testCancelNonexistentNotification() throws Exception {
-        mBinderService.cancelNotificationWithTag(PKG, PKG,
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg,
                 "testCancelNonexistentNotification", 0, mUserId);
         waitForIdle();
         // The notification record logger doesn't even get called when a nonexistent notification
@@ -2113,14 +2124,14 @@
 
     @Test
     public void testCancelNotificationImmediatelyAfterEnqueue() throws Exception {
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelNotificationImmediatelyAfterEnqueue", 0,
                 generateNotificationRecord(null).getNotification(), mUserId);
-        mBinderService.cancelNotificationWithTag(PKG, PKG,
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg,
                 "testCancelNotificationImmediatelyAfterEnqueue", 0, mUserId);
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(PKG);
+                mBinderService.getActiveNotifications(mPkg);
         assertEquals(0, notifs.length);
         assertEquals(0, mService.getNotificationRecordCount());
     }
@@ -2129,39 +2140,39 @@
     public void testPostCancelPostNotifiesListeners() throws Exception {
         // WHEN a notification is posted
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", sbn.getId(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", sbn.getId(),
                 sbn.getNotification(), sbn.getUserId());
         mTestableLooper.moveTimeForward(1);
         // THEN it is canceled
-        mBinderService.cancelNotificationWithTag(PKG, PKG, "tag", sbn.getId(), sbn.getUserId());
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, "tag", sbn.getId(), sbn.getUserId());
         mTestableLooper.moveTimeForward(1);
         // THEN it is posted again (before the cancel has a chance to finish)
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", sbn.getId(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", sbn.getId(),
                 sbn.getNotification(), sbn.getUserId());
         // THEN the later enqueue isn't swallowed by the cancel. I.e., ordering is respected
         waitForIdle();
 
         // The final enqueue made it to the listener instead of being canceled
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(PKG);
+                mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifs.length);
         assertEquals(1, mService.getNotificationRecordCount());
     }
 
     @Test
     public void testCancelNotificationWhilePostedAndEnqueued() throws Exception {
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelNotificationWhilePostedAndEnqueued", 0,
                 generateNotificationRecord(null).getNotification(), mUserId);
         waitForIdle();
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelNotificationWhilePostedAndEnqueued", 0,
                 generateNotificationRecord(null).getNotification(), mUserId);
-        mBinderService.cancelNotificationWithTag(PKG, PKG,
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg,
                 "testCancelNotificationWhilePostedAndEnqueued", 0, mUserId);
         waitForIdle();
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(PKG);
+                mBinderService.getActiveNotifications(mPkg);
         assertEquals(0, notifs.length);
         assertEquals(0, mService.getNotificationRecordCount());
         ArgumentCaptor<NotificationStats> captor = ArgumentCaptor.forClass(NotificationStats.class);
@@ -2173,7 +2184,7 @@
     public void testCancelNotificationsFromListenerImmediatelyAfterEnqueue() throws Exception {
         NotificationRecord r = generateNotificationRecord(null);
         final StatusBarNotification sbn = r.getSbn();
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelNotificationsFromListenerImmediatelyAfterEnqueue",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         mBinderService.cancelNotificationsFromListener(null, null);
@@ -2187,10 +2198,10 @@
     @Test
     public void testCancelAllNotificationsImmediatelyAfterEnqueue() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelAllNotificationsImmediatelyAfterEnqueue",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
-        mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
+        mBinderService.cancelAllNotifications(mPkg, sbn.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
@@ -2203,7 +2214,7 @@
         final NotificationRecord n = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group", true);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testUserInitiatedClearAll_noLeak",
                 n.getSbn().getId(), n.getSbn().getNotification(), n.getSbn().getUserId());
         waitForIdle();
@@ -2227,17 +2238,17 @@
         final NotificationRecord child = generateNotificationRecord(
                 mTestNotificationChannel, 2, "group1", false);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelAllNotificationsCancelsChildren",
                 parent.getSbn().getId(), parent.getSbn().getNotification(),
                 parent.getSbn().getUserId());
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelAllNotificationsCancelsChildren",
                 child.getSbn().getId(), child.getSbn().getNotification(),
                 child.getSbn().getUserId());
         waitForIdle();
 
-        mBinderService.cancelAllNotifications(PKG, parent.getSbn().getUserId());
+        mBinderService.cancelAllNotifications(mPkg, parent.getSbn().getUserId());
         waitForIdle();
         assertEquals(0, mService.getNotificationRecordCount());
     }
@@ -2246,11 +2257,11 @@
     public void testCancelAllNotificationsMultipleEnqueuedDoesNotCrash() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         for (int i = 0; i < 10; i++) {
-            mBinderService.enqueueNotificationWithTag(PKG, PKG,
+            mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                     "testCancelAllNotificationsMultipleEnqueuedDoesNotCrash",
                     sbn.getId(), sbn.getNotification(), sbn.getUserId());
         }
-        mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
+        mBinderService.cancelAllNotifications(mPkg, sbn.getUserId());
         waitForIdle();
 
         assertEquals(0, mService.getNotificationRecordCount());
@@ -2266,7 +2277,7 @@
                 mTestNotificationChannel, 2, "group1", false);
 
         // fully post parent notification
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash",
                 parent.getSbn().getId(), parent.getSbn().getNotification(),
                 parent.getSbn().getUserId());
@@ -2274,13 +2285,13 @@
 
         // enqueue the child several times
         for (int i = 0; i < 10; i++) {
-            mBinderService.enqueueNotificationWithTag(PKG, PKG,
+            mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                     "testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash",
                     child.getSbn().getId(), child.getSbn().getNotification(),
                     child.getSbn().getUserId());
         }
         // make the parent a child, which will cancel the child notification
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelGroupSummaryMultipleEnqueuedChildrenDoesNotCrash",
                 parentAsChild.getSbn().getId(), parentAsChild.getSbn().getNotification(),
                 parentAsChild.getSbn().getUserId());
@@ -2332,10 +2343,10 @@
                 any(), anyString(), anyInt(), anyString(), anyInt())).thenReturn(SHOW_IMMEDIATELY);
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelAllNotifications_IgnoreForegroundService",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
-        mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
+        mBinderService.cancelAllNotifications(mPkg, sbn.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
@@ -2350,10 +2361,10 @@
                 .thenReturn(NOT_FOREGROUND_SERVICE);
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelAllNotifications_IgnoreForegroundService",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
-        mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
+        mBinderService.cancelAllNotifications(mPkg, sbn.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
@@ -2367,7 +2378,7 @@
                 .thenReturn(SHOW_IMMEDIATELY);
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelAllNotifications_IgnoreOtherPackages",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         mBinderService.cancelAllNotifications("other_pkg_name", sbn.getUserId());
@@ -2381,7 +2392,7 @@
     @Test
     public void testCancelAllNotifications_NullPkgRemovesAll() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelAllNotifications_NullPkgRemovesAll",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         mBinderService.cancelAllNotifications(null, sbn.getUserId());
@@ -2395,7 +2406,7 @@
     @Test
     public void testCancelAllNotifications_NullPkgIgnoresUserAllNotifications() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelAllNotifications_NullPkgIgnoresUserAllNotifications",
                 sbn.getId(), sbn.getNotification(), UserHandle.USER_ALL);
         // Null pkg is how we signal a user switch.
@@ -2411,10 +2422,10 @@
     public void testAppInitiatedCancelAllNotifications_CancelsNoClearFlag() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= Notification.FLAG_NO_CLEAR;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testAppInitiatedCancelAllNotifications_CancelsNoClearFlag",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
-        mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
+        mBinderService.cancelAllNotifications(mPkg, sbn.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
@@ -2427,7 +2438,7 @@
                 mTestNotificationChannel, 1, "group", true);
         notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
         mService.addNotification(notif);
-        mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0,
+        mService.cancelAllNotificationsInt(mUid, 0, mPkg, null, 0, 0,
                 notif.getUserId(), REASON_CANCEL);
         waitForIdle();
         StatusBarNotification[] notifs =
@@ -2462,9 +2473,9 @@
         StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, null, mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, null,
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
-        mInternalService.removeForegroundServiceFlagFromNotification(PKG, sbn.getId(),
+        mInternalService.removeForegroundServiceFlagFromNotification(mPkg, sbn.getId(),
                 sbn.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
@@ -2477,12 +2488,12 @@
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags =
                 Notification.FLAG_ONGOING_EVENT | FLAG_FOREGROUND_SERVICE;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, sbn.getTag(),
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, sbn.getTag(),
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
-        mBinderService.cancelNotificationWithTag(PKG, PKG, sbn.getTag(), sbn.getId(),
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, sbn.getTag(), sbn.getId(),
                 sbn.getUserId());
         waitForIdle();
         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
@@ -2501,7 +2512,7 @@
         assertThat(mBinderService.getActiveNotifications(sbn.getPackageName()).length).isEqualTo(1);
         assertThat(mService.getNotificationRecordCount()).isEqualTo(1);
 
-        mBinderService.cancelNotificationWithTag(PKG, PKG, sbn.getTag(), sbn.getId(),
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, sbn.getTag(), sbn.getId(),
                 sbn.getUserId());
         waitForIdle();
 
@@ -2520,7 +2531,7 @@
                 FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY);
 
         mSetFlagsRule.disableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
-        mBinderService.cancelNotificationWithTag(PKG, PKG, sbn.getTag(), sbn.getId(),
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, sbn.getTag(), sbn.getId(),
                 sbn.getUserId());
         waitForIdle();
 
@@ -2542,13 +2553,13 @@
                 mTestNotificationChannel, 2, null, false);
         mService.addNotification(notifCancelable);
         // Verify that both notifications have been posted and are active.
-        assertThat(mBinderService.getActiveNotifications(PKG).length).isEqualTo(2);
+        assertThat(mBinderService.getActiveNotifications(mPkg).length).isEqualTo(2);
 
-        mBinderService.cancelAllNotifications(PKG, notif.getSbn().getUserId());
+        mBinderService.cancelAllNotifications(mPkg, notif.getSbn().getUserId());
         waitForIdle();
 
         // The non-lifetime extended notification, with id = 2, has been cancelled.
-        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(mPkg);
         assertThat(notifs.length).isEqualTo(1);
         assertThat(notifs[0].getId()).isEqualTo(1);
 
@@ -3230,7 +3241,7 @@
     public void testGroupInstanceIds() throws Exception {
         final NotificationRecord group1 = generateNotificationRecord(
                 mTestNotificationChannel, 1, "group1", true);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "testGroupInstanceIds",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testGroupInstanceIds",
                 group1.getSbn().getId(), group1.getSbn().getNotification(),
                 group1.getSbn().getUserId());
         waitForIdle();
@@ -3238,7 +3249,7 @@
         // same group, child, should be returned
         final NotificationRecord group1Child = generateNotificationRecord(
                 mTestNotificationChannel, 2, "group1", false);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "testGroupInstanceIds",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testGroupInstanceIds",
                 group1Child.getSbn().getId(),
                 group1Child.getSbn().getNotification(), group1Child.getSbn().getUserId());
         waitForIdle();
@@ -3259,7 +3270,7 @@
         // should not be returned
         final NotificationRecord group2 = generateNotificationRecord(
                 mTestNotificationChannel, 2, "group2", true);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "testFindGroupNotificationsLocked",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testFindGroupNotificationsLocked",
                 group2.getSbn().getId(), group2.getSbn().getNotification(),
                 group2.getSbn().getUserId());
         waitForIdle();
@@ -3267,7 +3278,7 @@
         // should not be returned
         final NotificationRecord nonGroup = generateNotificationRecord(
                 mTestNotificationChannel, 3, null, false);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "testFindGroupNotificationsLocked",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testFindGroupNotificationsLocked",
                 nonGroup.getSbn().getId(), nonGroup.getSbn().getNotification(),
                 nonGroup.getSbn().getUserId());
         waitForIdle();
@@ -3275,13 +3286,13 @@
         // same group, child, should be returned
         final NotificationRecord group1Child = generateNotificationRecord(
                 mTestNotificationChannel, 4, "group1", false);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "testFindGroupNotificationsLocked",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testFindGroupNotificationsLocked",
                 group1Child.getSbn().getId(),
                 group1Child.getSbn().getNotification(), group1Child.getSbn().getUserId());
         waitForIdle();
 
         List<NotificationRecord> inGroup1 =
-                mService.findGroupNotificationsLocked(PKG, group1.getGroupKey(),
+                mService.findGroupNotificationsLocked(mPkg, group1.getGroupKey(),
                         group1.getSbn().getUserId());
         assertEquals(3, inGroup1.size());
         for (NotificationRecord record : inGroup1) {
@@ -3296,7 +3307,7 @@
                 mTestNotificationChannel, 1, "group", true);
         notif.getNotification().flags |= Notification.FLAG_NO_CLEAR;
         mService.addNotification(notif);
-        mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0,
+        mService.cancelAllNotificationsInt(mUid, 0, mPkg, null, 0,
                 Notification.FLAG_ONGOING_EVENT, notif.getUserId(), REASON_CANCEL);
         waitForIdle();
         StatusBarNotification[] notifs =
@@ -3308,10 +3319,10 @@
     public void testAppInitiatedCancelAllNotifications_CancelsOngoingFlag() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testAppInitiatedCancelAllNotifications_CancelsOnGoingFlag",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
-        mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
+        mBinderService.cancelAllNotifications(mPkg, sbn.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
@@ -3324,7 +3335,7 @@
                 mTestNotificationChannel, 1, "group", true);
         notif.getNotification().flags |= Notification.FLAG_ONGOING_EVENT;
         mService.addNotification(notif);
-        mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0,
+        mService.cancelAllNotificationsInt(mUid, 0, mPkg, null, 0, 0,
                 notif.getUserId(), REASON_CANCEL);
         waitForIdle();
         StatusBarNotification[] notifs =
@@ -3420,16 +3431,16 @@
     @Test
     public void testPostNotification_appPermissionFixed() throws Exception {
         when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
-        when(mPermissionHelper.isPermissionFixed(PKG, mUserId)).thenReturn(true);
+        when(mPermissionHelper.isPermissionFixed(mPkg, mUserId)).thenReturn(true);
 
         NotificationRecord temp = generateNotificationRecord(mTestNotificationChannel);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testPostNotification_appPermissionFixed", 0,
                 temp.getNotification(), mUserId);
         waitForIdle();
         assertThat(mService.getNotificationRecordCount()).isEqualTo(1);
         StatusBarNotification[] notifs =
-                mBinderService.getActiveNotifications(PKG);
+                mBinderService.getActiveNotifications(mPkg);
         assertThat(mService.getNotificationRecord(notifs[0].getKey()).isImportanceFixed()).isTrue();
     }
 
@@ -3439,7 +3450,7 @@
         mService.addNotification(temp);
 
         when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
-        when(mPermissionHelper.isPermissionFixed(PKG, temp.getUserId())).thenReturn(true);
+        when(mPermissionHelper.isPermissionFixed(mPkg, temp.getUserId())).thenReturn(true);
 
         NotificationRecord r = mService.createAutoGroupSummary(temp.getUserId(),
                 temp.getSbn().getPackageName(), temp.getKey(), 0, mock(Icon.class), 0,
@@ -3457,7 +3468,7 @@
                     new NotificationChannel("foo", "foo", IMPORTANCE_HIGH));
 
         Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "testTvExtenderChannelOverride_onTv", 0,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testTvExtenderChannelOverride_onTv", 0,
                 generateNotificationRecord(null, tv).getNotification(), mUserId);
         verify(mPreferencesHelper, times(1)).getConversationNotificationChannel(
                 anyString(), anyInt(), eq("foo"), eq(null), anyBoolean(), anyBoolean());
@@ -3472,7 +3483,7 @@
                 mTestNotificationChannel);
 
         Notification.TvExtender tv = new Notification.TvExtender().setChannelId("foo");
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "testTvExtenderChannelOverride_notOnTv",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testTvExtenderChannelOverride_notOnTv",
                 0, generateNotificationRecord(null, tv).getNotification(), mUserId);
         verify(mPreferencesHelper, times(1)).getConversationNotificationChannel(
                 anyString(), anyInt(), eq(mTestNotificationChannel.getId()), eq(null),
@@ -3585,7 +3596,7 @@
     public void testUpdateAppNotifyCreatorBlock() throws Exception {
         when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
 
-        mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
+        mBinderService.setNotificationsEnabledForPackage(mPkg, mUid, false);
         Thread.sleep(500);
         waitForIdle();
 
@@ -3594,7 +3605,7 @@
 
         assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
                 captor.getValue().getAction());
-        assertEquals(PKG, captor.getValue().getPackage());
+        assertEquals(mPkg, captor.getValue().getPackage());
         assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
     }
 
@@ -3602,7 +3613,7 @@
     public void testUpdateAppNotifyCreatorBlock_notIfMatchesExistingSetting() throws Exception {
         when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
 
-        mBinderService.setNotificationsEnabledForPackage(PKG, 0, false);
+        mBinderService.setNotificationsEnabledForPackage(mPkg, 0, false);
         verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null));
     }
 
@@ -3610,7 +3621,7 @@
     public void testUpdateAppNotifyCreatorUnblock() throws Exception {
         when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
 
-        mBinderService.setNotificationsEnabledForPackage(PKG, mUid, true);
+        mBinderService.setNotificationsEnabledForPackage(mPkg, mUid, true);
         Thread.sleep(500);
         waitForIdle();
 
@@ -3619,14 +3630,14 @@
 
         assertEquals(NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED,
                 captor.getValue().getAction());
-        assertEquals(PKG, captor.getValue().getPackage());
+        assertEquals(mPkg, captor.getValue().getPackage());
         assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, true));
     }
 
     @Test
     public void testUpdateChannelNotifyCreatorBlock() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
+        when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
                 .thenReturn(mTestNotificationChannel);
 
@@ -3634,13 +3645,13 @@
                 new NotificationChannel(mTestNotificationChannel.getId(),
                         mTestNotificationChannel.getName(), IMPORTANCE_NONE);
 
-        mBinderService.updateNotificationChannelForPackage(PKG, 0, updatedChannel);
+        mBinderService.updateNotificationChannelForPackage(mPkg, 0, updatedChannel);
         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
         verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
 
         assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED,
                 captor.getValue().getAction());
-        assertEquals(PKG, captor.getValue().getPackage());
+        assertEquals(mPkg, captor.getValue().getPackage());
         assertEquals(mTestNotificationChannel.getId(), captor.getValue().getStringExtra(
                         NotificationManager.EXTRA_NOTIFICATION_CHANNEL_ID));
         assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
@@ -3652,17 +3663,17 @@
                 new NotificationChannel(mTestNotificationChannel.getId(),
                         mTestNotificationChannel.getName(), IMPORTANCE_NONE);
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
+        when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
                 .thenReturn(existingChannel);
 
-        mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
+        mBinderService.updateNotificationChannelForPackage(mPkg, 0, mTestNotificationChannel);
         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
         verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
 
         assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED,
                 captor.getValue().getAction());
-        assertEquals(PKG, captor.getValue().getPackage());
+        assertEquals(mPkg, captor.getValue().getPackage());
         assertEquals(mTestNotificationChannel.getId(), captor.getValue().getStringExtra(
                 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_ID));
         assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
@@ -3674,11 +3685,11 @@
                 new NotificationChannel(mTestNotificationChannel.getId(),
                         mTestNotificationChannel.getName(), IMPORTANCE_MAX);
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
+        when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
                 .thenReturn(existingChannel);
 
-        mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
+        mBinderService.updateNotificationChannelForPackage(mPkg, 0, mTestNotificationChannel);
         verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null));
     }
 
@@ -3687,19 +3698,19 @@
         NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
         mService.setPreferencesHelper(mPreferencesHelper);
         when(mPreferencesHelper.getNotificationChannelGroup(eq(existing.getId()),
-                eq(PKG), anyInt()))
+                eq(mPkg), anyInt()))
                 .thenReturn(existing);
 
         NotificationChannelGroup updated = new NotificationChannelGroup("id", "name");
         updated.setBlocked(true);
 
-        mBinderService.updateNotificationChannelGroupForPackage(PKG, 0, updated);
+        mBinderService.updateNotificationChannelGroupForPackage(mPkg, 0, updated);
         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
         verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
 
         assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED,
                 captor.getValue().getAction());
-        assertEquals(PKG, captor.getValue().getPackage());
+        assertEquals(mPkg, captor.getValue().getPackage());
         assertEquals(existing.getId(), captor.getValue().getStringExtra(
                 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_GROUP_ID));
         assertTrue(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
@@ -3711,17 +3722,17 @@
         existing.setBlocked(true);
         mService.setPreferencesHelper(mPreferencesHelper);
         when(mPreferencesHelper.getNotificationChannelGroup(eq(existing.getId()),
-                eq(PKG), anyInt()))
+                eq(mPkg), anyInt()))
                 .thenReturn(existing);
 
         mBinderService.updateNotificationChannelGroupForPackage(
-                PKG, 0, new NotificationChannelGroup("id", "name"));
+                mPkg, 0, new NotificationChannelGroup("id", "name"));
         ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
         verify(mContext, times(1)).sendBroadcastAsUser(captor.capture(), any(), eq(null));
 
         assertEquals(NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED,
                 captor.getValue().getAction());
-        assertEquals(PKG, captor.getValue().getPackage());
+        assertEquals(mPkg, captor.getValue().getPackage());
         assertEquals(existing.getId(), captor.getValue().getStringExtra(
                 NotificationManager.EXTRA_NOTIFICATION_CHANNEL_GROUP_ID));
         assertFalse(captor.getValue().getBooleanExtra(EXTRA_BLOCKED_STATE, false));
@@ -3732,131 +3743,131 @@
         NotificationChannelGroup existing = new NotificationChannelGroup("id", "name");
         mService.setPreferencesHelper(mPreferencesHelper);
         when(mPreferencesHelper.getNotificationChannelGroup(
-                eq(existing.getId()), eq(PKG), anyInt()))
+                eq(existing.getId()), eq(mPkg), anyInt()))
                 .thenReturn(existing);
 
         mBinderService.updateNotificationChannelGroupForPackage(
-                PKG, 0, new NotificationChannelGroup("id", "new name"));
+                mPkg, 0, new NotificationChannelGroup("id", "new name"));
         verify(mContext, never()).sendBroadcastAsUser(any(), any(), eq(null));
     }
 
     @Test
     public void testCreateChannelNotifyListener() throws Exception {
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
+        when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
                 .thenReturn(mTestNotificationChannel);
         NotificationChannel channel2 = new NotificationChannel("a", "b", IMPORTANCE_LOW);
-        when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
+        when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
                 eq(channel2.getId()), anyBoolean()))
                 .thenReturn(channel2);
-        when(mPreferencesHelper.createNotificationChannel(eq(PKG), anyInt(),
+        when(mPreferencesHelper.createNotificationChannel(eq(mPkg), anyInt(),
                 eq(channel2), anyBoolean(), anyBoolean(), anyInt(), anyBoolean()))
                 .thenReturn(true);
 
         reset(mListeners);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(mTestNotificationChannel, channel2)));
-        verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
+        verify(mListeners, never()).notifyNotificationChannelChanged(eq(mPkg),
                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
-        verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
+        verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(mPkg),
                 eq(Process.myUserHandle()), eq(channel2),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
     }
 
     @Test
     public void testCreateChannelGroupNotifyListener() throws Exception {
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
         mService.setPreferencesHelper(mPreferencesHelper);
         NotificationChannelGroup group1 = new NotificationChannelGroup("a", "b");
         NotificationChannelGroup group2 = new NotificationChannelGroup("n", "m");
 
         reset(mListeners);
-        mBinderService.createNotificationChannelGroups(PKG,
+        mBinderService.createNotificationChannelGroups(mPkg,
                 new ParceledListSlice(Arrays.asList(group1, group2)));
-        verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
+        verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(mPkg),
                 eq(Process.myUserHandle()), eq(group1),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
-        verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
+        verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(mPkg),
                 eq(Process.myUserHandle()), eq(group2),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
     }
 
     @Test
     public void testUpdateChannelNotifyListener() throws Exception {
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
         mService.setPreferencesHelper(mPreferencesHelper);
         mTestNotificationChannel.setLightColor(Color.CYAN);
-        when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
+        when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
                 .thenReturn(mTestNotificationChannel);
 
         reset(mListeners);
-        mBinderService.updateNotificationChannelForPackage(PKG, mUid, mTestNotificationChannel);
-        verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
+        mBinderService.updateNotificationChannelForPackage(mPkg, mUid, mTestNotificationChannel);
+        verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(mPkg),
                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
     }
 
     @Test
     public void testDeleteChannelNotifyListener() throws Exception {
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
+        when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
                 .thenReturn(mTestNotificationChannel);
-        when(mPreferencesHelper.deleteNotificationChannel(eq(PKG), anyInt(),
+        when(mPreferencesHelper.deleteNotificationChannel(eq(mPkg), anyInt(),
                 eq(mTestNotificationChannel.getId()),  anyInt(), anyBoolean())).thenReturn(true);
         reset(mListeners);
-        mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
-        verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
+        mBinderService.deleteNotificationChannel(mPkg, mTestNotificationChannel.getId());
+        verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(mPkg),
                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
     }
 
     @Test
     public void testDeleteChannelOnlyDoExtraWorkIfExisted() throws Exception {
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
+        when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
                 .thenReturn(null);
         reset(mListeners);
-        mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
+        mBinderService.deleteNotificationChannel(mPkg, mTestNotificationChannel.getId());
         verifyNoMoreInteractions(mListeners);
         verifyNoMoreInteractions(mHistoryManager);
     }
 
     @Test
     public void testDeleteChannelGroupNotifyListener() throws Exception {
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
         NotificationChannelGroup ncg = new NotificationChannelGroup("a", "b/c");
         mService.setPreferencesHelper(mPreferencesHelper);
         when(mPreferencesHelper.getNotificationChannelGroupWithChannels(
-                eq(PKG), anyInt(), eq(ncg.getId()), anyBoolean()))
+                eq(mPkg), anyInt(), eq(ncg.getId()), anyBoolean()))
                 .thenReturn(ncg);
         reset(mListeners);
-        mBinderService.deleteNotificationChannelGroup(PKG, ncg.getId());
-        verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
+        mBinderService.deleteNotificationChannelGroup(mPkg, ncg.getId());
+        verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(mPkg),
                 eq(Process.myUserHandle()), eq(ncg),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
     }
 
     @Test
     public void testDeleteChannelGroupChecksForFgses() throws Exception {
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
         CountDownLatch latch = new CountDownLatch(2);
         mService.createNotificationChannelGroup(
-                PKG, mUid, new NotificationChannelGroup("group", "group"), true, false);
+                mPkg, mUid, new NotificationChannelGroup("group", "group"), true, false);
         new Thread(() -> {
             NotificationChannel notificationChannel = new NotificationChannel("id", "id",
                     NotificationManager.IMPORTANCE_HIGH);
@@ -3864,7 +3875,7 @@
             ParceledListSlice<NotificationChannel> pls =
                     new ParceledListSlice(ImmutableList.of(notificationChannel));
             try {
-                mBinderService.createNotificationChannelsForPackage(PKG, mUid, pls);
+                mBinderService.createNotificationChannelsForPackage(mPkg, mUid, pls);
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
@@ -3875,7 +3886,7 @@
                 synchronized (this) {
                     wait(5000);
                 }
-                mService.createNotificationChannelGroup(PKG, mUid,
+                mService.createNotificationChannelGroup(mPkg, mUid,
                         new NotificationChannelGroup("new", "new group"), true, false);
                 NotificationChannel notificationChannel =
                         new NotificationChannel("id", "id", NotificationManager.IMPORTANCE_HIGH);
@@ -3883,8 +3894,8 @@
                 ParceledListSlice<NotificationChannel> pls =
                         new ParceledListSlice(ImmutableList.of(notificationChannel));
                 try {
-                mBinderService.createNotificationChannelsForPackage(PKG, mUid, pls);
-                mBinderService.deleteNotificationChannelGroup(PKG, "group");
+                mBinderService.createNotificationChannelsForPackage(mPkg, mUid, pls);
+                mBinderService.deleteNotificationChannelGroup(mPkg, "group");
                 } catch (RemoteException e) {
                     throw new RuntimeException(e);
                 }
@@ -3901,19 +3912,19 @@
     @Test
     public void testUpdateNotificationChannelFromPrivilegedListener_success() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
-        when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
+        when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
                 .thenReturn(mTestNotificationChannel);
 
         mBinderService.updateNotificationChannelFromPrivilegedListener(
-                null, PKG, Process.myUserHandle(), mTestNotificationChannel);
+                null, mPkg, Process.myUserHandle(), mTestNotificationChannel);
 
         verify(mPreferencesHelper, times(1)).updateNotificationChannel(
                 anyString(), anyInt(), any(), anyBoolean(),  anyInt(), anyBoolean());
 
-        verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
+        verify(mListeners, never()).notifyNotificationChannelChanged(eq(mPkg),
                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
     }
@@ -3921,12 +3932,12 @@
     @Test
     public void testUpdateNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(emptyList());
 
         try {
             mBinderService.updateNotificationChannelFromPrivilegedListener(
-                    null, PKG, Process.myUserHandle(), mTestNotificationChannel);
+                    null, mPkg, Process.myUserHandle(), mTestNotificationChannel);
             fail("listeners that don't have a companion device shouldn't be able to call this");
         } catch (SecurityException e) {
             // pass
@@ -3935,7 +3946,7 @@
         verify(mPreferencesHelper, never()).updateNotificationChannel(
                 anyString(), anyInt(), any(), anyBoolean(),  anyInt(), anyBoolean());
 
-        verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
+        verify(mListeners, never()).notifyNotificationChannelChanged(eq(mPkg),
                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
     }
@@ -3943,16 +3954,16 @@
     @Test
     public void testUpdateNotificationChannelFromPrivilegedListener_badUser() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
-        mListener.component = new ComponentName(PKG, PKG);
+        mListener.component = new ComponentName(mPkg, mPkg);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
 
         try {
             mBinderService.updateNotificationChannelFromPrivilegedListener(
-                    null, PKG, UserHandle.ALL, mTestNotificationChannel);
+                    null, mPkg, UserHandle.ALL, mTestNotificationChannel);
             fail("incorrectly allowed a change to a user listener cannot see");
         } catch (SecurityException e) {
             // pass
@@ -3961,7 +3972,7 @@
         verify(mPreferencesHelper, never()).updateNotificationChannel(
                 anyString(), anyInt(), any(), anyBoolean(),  anyInt(), anyBoolean());
 
-        verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
+        verify(mListeners, never()).notifyNotificationChannelChanged(eq(mPkg),
                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
     }
@@ -3970,9 +3981,9 @@
     public void testUpdateNotificationChannelFromPrivilegedListener_noSoundUriPermission()
             throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
-        when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
+        when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
                 .thenReturn(mTestNotificationChannel);
 
@@ -3987,13 +3998,13 @@
                 anyInt(), eq(Process.myUserHandle().getIdentifier()));
 
         assertThrows(SecurityException.class,
-                () -> mBinderService.updateNotificationChannelFromPrivilegedListener(null, PKG,
+                () -> mBinderService.updateNotificationChannelFromPrivilegedListener(null, mPkg,
                 Process.myUserHandle(), updatedNotificationChannel));
 
         verify(mPreferencesHelper, never()).updateNotificationChannel(
                 anyString(), anyInt(), any(), anyBoolean(),  anyInt(), anyBoolean());
 
-        verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
+        verify(mListeners, never()).notifyNotificationChannelChanged(eq(mPkg),
                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
     }
@@ -4002,9 +4013,9 @@
     public void testUpdateNotificationChannelFromPrivilegedListener_noSoundUriPermission_sameSound()
             throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
-        when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
+        when(mPreferencesHelper.getNotificationChannel(eq(mPkg), anyInt(),
                 eq(mTestNotificationChannel.getId()), anyBoolean()))
                 .thenReturn(mTestNotificationChannel);
 
@@ -4019,12 +4030,12 @@
                     anyInt(), eq(Process.myUserHandle().getIdentifier()));
 
         mBinderService.updateNotificationChannelFromPrivilegedListener(
-                null, PKG, Process.myUserHandle(), updatedNotificationChannel);
+                null, mPkg, Process.myUserHandle(), updatedNotificationChannel);
 
         verify(mPreferencesHelper, times(1)).updateNotificationChannel(
                 anyString(), anyInt(), any(), anyBoolean(),  anyInt(), anyBoolean());
 
-        verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
+        verify(mListeners, never()).notifyNotificationChannelChanged(eq(mPkg),
                 eq(Process.myUserHandle()), eq(mTestNotificationChannel),
                 eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
     }
@@ -4032,11 +4043,11 @@
     @Test
     public void testGetNotificationChannelFromPrivilegedListener_cdm_success() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
 
         mBinderService.getNotificationChannelsFromPrivilegedListener(
-                null, PKG, Process.myUserHandle());
+                null, mPkg, Process.myUserHandle());
 
         verify(mPreferencesHelper, times(1)).getNotificationChannels(
                 anyString(), anyInt(), anyBoolean());
@@ -4045,12 +4056,12 @@
     @Test
     public void testGetNotificationChannelFromPrivilegedListener_cdm_noAccess() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(emptyList());
 
         try {
             mBinderService.getNotificationChannelsFromPrivilegedListener(
-                    null, PKG, Process.myUserHandle());
+                    null, mPkg, Process.myUserHandle());
             fail("listeners that don't have a companion device shouldn't be able to call this");
         } catch (SecurityException e) {
             // pass
@@ -4064,12 +4075,12 @@
     public void testGetNotificationChannelFromPrivilegedListener_assistant_success()
             throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(emptyList());
         when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true);
 
         mBinderService.getNotificationChannelsFromPrivilegedListener(
-                null, PKG, Process.myUserHandle());
+                null, mPkg, Process.myUserHandle());
 
         verify(mPreferencesHelper, times(1)).getNotificationChannels(
                 anyString(), anyInt(), anyBoolean());
@@ -4079,13 +4090,13 @@
     public void testGetNotificationChannelFromPrivilegedListener_assistant_noAccess()
             throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(emptyList());
         when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(false);
 
         try {
             mBinderService.getNotificationChannelsFromPrivilegedListener(
-                    null, PKG, Process.myUserHandle());
+                    null, mPkg, Process.myUserHandle());
             fail("listeners that don't have a companion device shouldn't be able to call this");
         } catch (SecurityException e) {
             // pass
@@ -4098,16 +4109,16 @@
     @Test
     public void testGetNotificationChannelFromPrivilegedListener_badUser() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
-        mListener.component = new ComponentName(PKG, PKG);
+        mListener.component = new ComponentName(mPkg, mPkg);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
 
         try {
             mBinderService.getNotificationChannelsFromPrivilegedListener(
-                    null, PKG, Process.myUserHandle());
+                    null, mPkg, Process.myUserHandle());
             fail("listener getting channels from a user they cannot see");
         } catch (SecurityException e) {
             // pass
@@ -4120,11 +4131,11 @@
     @Test
     public void testGetNotificationChannelGroupsFromPrivilegedListener_success() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
 
         mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
-                null, PKG, Process.myUserHandle());
+                null, mPkg, Process.myUserHandle());
 
         verify(mPreferencesHelper, times(1)).getNotificationChannelGroups(anyString(), anyInt());
     }
@@ -4132,12 +4143,12 @@
     @Test
     public void testGetNotificationChannelGroupsFromPrivilegedListener_noAccess() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(emptyList());
 
         try {
             mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
-                    null, PKG, Process.myUserHandle());
+                    null, mPkg, Process.myUserHandle());
             fail("listeners that don't have a companion device shouldn't be able to call this");
         } catch (SecurityException e) {
             // pass
@@ -4149,15 +4160,15 @@
     @Test
     public void testGetNotificationChannelGroupsFromPrivilegedListener_badUser() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
-        when(mCompanionMgr.getAssociations(PKG, mUserId))
+        when(mCompanionMgr.getAssociations(mPkg, mUserId))
                 .thenReturn(emptyList());
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
-        mListener.component = new ComponentName(PKG, PKG);
+        mListener.component = new ComponentName(mPkg, mPkg);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
         try {
             mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
-                    null, PKG, Process.myUserHandle());
+                    null, mPkg, Process.myUserHandle());
             fail("listeners that don't have a companion device shouldn't be able to call this");
         } catch (SecurityException e) {
             // pass
@@ -4190,7 +4201,7 @@
         mService.addNotification(r2);
 
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
-        mListener.component = new ComponentName(PKG, PKG);
+        mListener.component = new ComponentName(mPkg, mPkg);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
 
@@ -4209,7 +4220,7 @@
         mService.addNotification(r2);
 
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
-        mListener.component = new ComponentName(PKG, PKG);
+        mListener.component = new ComponentName(mPkg, mPkg);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(true);
         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
 
@@ -4231,7 +4242,7 @@
         mService.addNotification(nr1);
 
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
-        mListener.component = new ComponentName(PKG, PKG);
+        mListener.component = new ComponentName(mPkg, mPkg);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(true);
         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
 
@@ -4242,7 +4253,7 @@
                 any(NotificationManagerService.SnoozeNotificationRunnable.class));
         // Ensure cancel event is logged.
         verify(mAppOpsManager).noteOpNoThrow(
-                AppOpsManager.OP_RAPID_CLEAR_NOTIFICATIONS_BY_LISTENER, mUid, PKG, null,
+                AppOpsManager.OP_RAPID_CLEAR_NOTIFICATIONS_BY_LISTENER, mUid, mPkg, null,
                 null);
     }
 
@@ -4257,7 +4268,7 @@
         mService.addNotification(nr1);
 
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
-        mListener.component = new ComponentName(PKG, PKG);
+        mListener.component = new ComponentName(mPkg, mPkg);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(true);
         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
 
@@ -4283,7 +4294,7 @@
         mService.addNotification(nr1);
 
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
-        mListener.component = new ComponentName(PKG, PKG);
+        mListener.component = new ComponentName(mPkg, mPkg);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(true);
         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
 
@@ -4309,7 +4320,7 @@
         mService.addNotification(nr1);
 
         mListener = mock(ManagedServices.ManagedServiceInfo.class);
-        mListener.component = new ComponentName(PKG, PKG);
+        mListener.component = new ComponentName(mPkg, mPkg);
         when(mListener.enabledAndUserMatches(anyInt())).thenReturn(true);
         when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
 
@@ -4619,7 +4630,7 @@
         final NotificationRecord child = generateNotificationRecord(
                 mTestNotificationChannel, 2, "group", false);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "testPostNonGroup_noUnsnoozing",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testPostNonGroup_noUnsnoozing",
                 child.getSbn().getId(), child.getSbn().getNotification(),
                 child.getSbn().getUserId());
         waitForIdle();
@@ -4633,7 +4644,7 @@
         final NotificationRecord record = generateNotificationRecord(
                 mTestNotificationChannel, 2, null, false);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "testPostNonGroup_noUnsnoozing",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testPostNonGroup_noUnsnoozing",
                 record.getSbn().getId(), record.getSbn().getNotification(),
                 record.getSbn().getUserId());
         waitForIdle();
@@ -4646,7 +4657,7 @@
         final NotificationRecord parent = generateNotificationRecord(
                 mTestNotificationChannel, 2, "group", true);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "testPostGroupSummary_noUnsnoozing",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testPostGroupSummary_noUnsnoozing",
                 parent.getSbn().getId(), parent.getSbn().getNotification(),
                 parent.getSbn().getUserId());
         waitForIdle();
@@ -4659,7 +4670,7 @@
         final NotificationRecord nr = generateNotificationRecord(
                 mTestNotificationChannel, 2, "group", false);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testSystemNotificationListenerCanUnsnooze",
                 nr.getSbn().getId(), nr.getSbn().getNotification(),
                 nr.getSbn().getUserId());
@@ -4670,13 +4681,13 @@
         snoozeNotificationRunnable.run();
 
         ManagedServices.ManagedServiceInfo listener = mListeners.new ManagedServiceInfo(
-                null, new ComponentName(PKG, "test_class"), mUid, true, null, 0, 234);
+                null, new ComponentName(mPkg, "test_class"), mUid, true, null, 0, 234);
         listener.isSystem = true;
         when(mListeners.checkServiceTokenLocked(any())).thenReturn(listener);
 
         mBinderService.unsnoozeNotificationFromSystemListener(null, nr.getKey());
         waitForIdle();
-        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifs.length);
         assertNotNull(notifs[0].getKey());//mService.getNotificationRecord(nr.getSbn().getKey()));
     }
@@ -5197,17 +5208,17 @@
                 .setContentTitle("foo")
                 .addExtras(extras)
                 .setSmallIcon(android.R.drawable.sym_def_app_icon);
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
                 "testNoNotificationDuringSetupPermission", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, sbn.getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         NotificationRecord posted = mService.findNotificationLocked(
-                PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
+                mPkg, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
 
         assertTrue(posted.getNotification().extras.containsKey(EXTRA_ALLOW_DURING_SETUP));
     }
@@ -5222,17 +5233,17 @@
                 .setColorized(true).setColor(Color.WHITE)
                 .setFlag(FLAG_CAN_COLORIZE, true)
                 .setSmallIcon(android.R.drawable.sym_def_app_icon);
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
                 "testNoFakeColorizedPermission", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, sbn.getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         NotificationRecord posted = mService.findNotificationLocked(
-                PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
+                mPkg, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
 
         assertFalse(posted.getNotification().isColorized());
     }
@@ -5430,9 +5441,9 @@
         // anything that's currently enqueued or posted
         int userId = mUserId;
         assertEquals(40,
-                mService.getNotificationCount(PKG, userId, 0, null));
+                mService.getNotificationCount(mPkg, userId, 0, null));
         assertEquals(40,
-                mService.getNotificationCount(PKG, userId, 0, "tag2"));
+                mService.getNotificationCount(mPkg, userId, 0, "tag2"));
 
         // return all for package "a" - "banana" tag isn't used
         assertEquals(2,
@@ -5440,7 +5451,7 @@
 
         // exclude a known notification - it's excluded from only the posted list, not enqueued
         assertEquals(39, mService.getNotificationCount(
-                PKG, userId, sampleIdToExclude, sampleTagToExclude));
+                mPkg, userId, sampleIdToExclude, sampleTagToExclude));
     }
 
     @Test
@@ -5702,7 +5713,7 @@
         waitForIdle();
 
         // Check that the notification was cancelled.
-        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertThat(notifsAfter.length).isEqualTo(0);
         assertThat(mService.getNotificationRecord(notif.getKey())).isNull();
     }
@@ -5718,7 +5729,7 @@
         waitForIdle();
 
         // Check that the notification was not cancelled.
-        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertThat(notifsAfter.length).isEqualTo(1);
         assertThat(mService.getNotificationRecord(notif.getKey())).isEqualTo(notif);
     }
@@ -5734,7 +5745,7 @@
         waitForIdle();
 
         // Check that the notification was not cancelled.
-        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertThat(notifsAfter.length).isEqualTo(1);
         assertThat(mService.getNotificationRecord(notif.getKey())).isEqualTo(notif);
     }
@@ -5752,7 +5763,7 @@
         waitForIdle();
 
         // Check that the notification was not cancelled.
-        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertThat(notifsAfter.length).isEqualTo(1);
         assertThat(mService.getNotificationRecord(notif.getKey())).isEqualTo(notif);
 
@@ -5926,7 +5937,7 @@
         mService.addNotification(r);
 
         final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 0, 1, true);
-        mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, r.getUserId(),
+        mService.mNotificationDelegate.onNotificationClear(mUid, 0, mPkg, r.getUserId(),
                 r.getKey(), NotificationStats.DISMISSAL_AOD,
                 NotificationStats.DISMISS_SENTIMENT_POSITIVE, nv);
         waitForIdle();
@@ -5949,7 +5960,7 @@
         mService.addNotification(r);
 
         final NotificationVisibility nv = NotificationVisibility.obtain(r.getKey(), 0, 1, true);
-        mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG, r.getUserId(),
+        mService.mNotificationDelegate.onNotificationClear(mUid, 0, mPkg, r.getUserId(),
                 r.getKey(), NotificationStats.DISMISSAL_AOD,
                 NotificationStats.DISMISS_SENTIMENT_NEGATIVE, nv);
         waitForIdle();
@@ -5979,7 +5990,7 @@
         NotificationRecord original = generateNotificationRecord(mTestNotificationChannel);
         mService.addNotification(original);
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, original.getSbn().getId(),
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, original.getSbn().getId(),
                 original.getSbn().getTag(), mUid, 0,
                 new Notification.Builder(mContext, mTestNotificationChannel.getId())
                         .setContentTitle("new title").build(),
@@ -6038,7 +6049,7 @@
         waitForIdle();
 
         verify(handler, timeout(300).times(0)).scheduleSendRankingUpdate();
-        verify(handler, times(1)).scheduleCancelNotification(any());
+        verify(handler, times(1)).scheduleCancelNotification(any(), eq(0));
     }
 
     @Test
@@ -6297,7 +6308,7 @@
                         NotificationManagerService.CancelNotificationRunnable.class);
 
         verify(handler, times(1)).scheduleCancelNotification(
-                captor.capture());
+                captor.capture(), eq(0));
 
         // Run the runnable given to the cancel notification, and see if it logs properly
         NotificationManagerService.CancelNotificationRunnable runnable = captor.getValue();
@@ -6411,7 +6422,7 @@
                         .addMessage(message1)
                         .addMessage(message2));
         NotificationRecord recordA = new NotificationRecord(mContext, new StatusBarNotification(
-                PKG, PKG, 0, "tag", mUid, 0, nbA.build(), UserHandle.getUserHandleForUid(mUid),
+                mPkg, mPkg, 0, "tag", mUid, 0, nbA.build(), UserHandle.getUserHandleForUid(mUid),
                 null, 0), c);
 
         // First post means we grant access to both
@@ -6429,8 +6440,8 @@
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
                 .setStyle(new Notification.MessagingStyle("").addMessage(message2));
-        NotificationRecord recordB = new NotificationRecord(mContext, new StatusBarNotification(PKG,
-                PKG, 0, "tag", mUid, 0, nbB.build(), UserHandle.getUserHandleForUid(mUid), null, 0),
+        NotificationRecord recordB = new NotificationRecord(mContext, new StatusBarNotification(mPkg,
+                mPkg, 0, "tag", mUid, 0, nbB.build(), UserHandle.getUserHandleForUid(mUid), null, 0),
                 c);
 
         // Update means we drop access to first
@@ -6470,7 +6481,7 @@
                 .setStyle(new Notification.MessagingStyle("")
                         .addMessage(message1));
         NotificationRecord recordA = new NotificationRecord(mContext, new StatusBarNotification(
-                PKG, PKG, 0, "tag", mUid, 0, nbA.build(), UserHandle.getUserHandleForUid(mUid),
+                mPkg, mPkg, 0, "tag", mUid, 0, nbA.build(), UserHandle.getUserHandleForUid(mUid),
                 null, 0), c);
 
         doThrow(new SecurityException("no access")).when(mUgm)
@@ -6929,7 +6940,7 @@
     public void testVisualDifference_foreground() {
         Notification.Builder nb1 = new Notification.Builder(mContext, "")
                 .setContentTitle("foo");
-        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn1 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb1.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r1 =
                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
@@ -6937,7 +6948,7 @@
         Notification.Builder nb2 = new Notification.Builder(mContext, "")
                 .setFlag(FLAG_FOREGROUND_SERVICE, true)
                 .setContentTitle("bar");
-        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn2 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb2.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r2 =
                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
@@ -6949,14 +6960,14 @@
     public void testVisualDifference_diffTitle() {
         Notification.Builder nb1 = new Notification.Builder(mContext, "")
                 .setContentTitle("foo");
-        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn1 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb1.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r1 =
                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
 
         Notification.Builder nb2 = new Notification.Builder(mContext, "")
                 .setContentTitle("bar");
-        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn2 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb2.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r2 =
                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
@@ -6969,7 +6980,7 @@
         Notification.Builder nb1 = new Notification.Builder(mContext, "")
                 .setStyle(new Notification.InboxStyle()
                     .addLine("line1").addLine("line2"));
-        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn1 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb1.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r1 =
                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
@@ -6977,7 +6988,7 @@
         Notification.Builder nb2 = new Notification.Builder(mContext, "")
                 .setStyle(new Notification.InboxStyle()
                         .addLine("line1").addLine("line2_changed"));
-        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn2 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb2.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r2 =
                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
@@ -6987,7 +6998,7 @@
         Notification.Builder nb3 = new Notification.Builder(mContext, "")
                 .setStyle(new Notification.InboxStyle()
                         .addLine("line1"));
-        StatusBarNotification sbn3 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn3 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb3.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r3 =
                 new NotificationRecord(mContext, sbn3, mock(NotificationChannel.class));
@@ -6997,7 +7008,7 @@
         Notification.Builder nb4 = new Notification.Builder(mContext, "")
                 .setStyle(new Notification.InboxStyle()
                         .addLine("line1").addLine("line2").addLine("line3"));
-        StatusBarNotification sbn4 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn4 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb4.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r4 =
                 new NotificationRecord(mContext, sbn4, mock(NotificationChannel.class));
@@ -7006,7 +7017,7 @@
 
         Notification.Builder nb5 = new Notification.Builder(mContext, "")
             .setContentText("not an inbox");
-        StatusBarNotification sbn5 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn5 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb5.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r5 =
                 new NotificationRecord(mContext, sbn5, mock(NotificationChannel.class));
@@ -7018,14 +7029,14 @@
     public void testVisualDifference_diffText() {
         Notification.Builder nb1 = new Notification.Builder(mContext, "")
                 .setContentText("foo");
-        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn1 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb1.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r1 =
                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
 
         Notification.Builder nb2 = new Notification.Builder(mContext, "")
                 .setContentText("bar");
-        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn2 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb2.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r2 =
                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
@@ -7037,14 +7048,14 @@
     public void testVisualDifference_sameText() {
         Notification.Builder nb1 = new Notification.Builder(mContext, "")
                 .setContentText("foo");
-        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn1 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb1.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r1 =
                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
 
         Notification.Builder nb2 = new Notification.Builder(mContext, "")
                 .setContentText("foo");
-        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn2 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb2.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r2 =
                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
@@ -7056,14 +7067,14 @@
     public void testVisualDifference_sameTextButStyled() {
         Notification.Builder nb1 = new Notification.Builder(mContext, "")
                 .setContentText(Html.fromHtml("<b>foo</b>"));
-        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn1 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb1.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r1 =
                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
 
         Notification.Builder nb2 = new Notification.Builder(mContext, "")
                 .setContentText(Html.fromHtml("<b>foo</b>"));
-        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn2 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb2.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r2 =
                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
@@ -7075,14 +7086,14 @@
     public void testVisualDifference_diffTextButStyled() {
         Notification.Builder nb1 = new Notification.Builder(mContext, "")
                 .setContentText(Html.fromHtml("<b>foo</b>"));
-        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn1 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb1.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r1 =
                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
 
         Notification.Builder nb2 = new Notification.Builder(mContext, "")
                 .setContentText(Html.fromHtml("<b>bar</b>"));
-        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn2 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb2.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r2 =
                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
@@ -7094,14 +7105,14 @@
     public void testVisualDifference_diffProgress() {
         Notification.Builder nb1 = new Notification.Builder(mContext, "")
                 .setProgress(100, 90, false);
-        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn1 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb1.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r1 =
                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
 
         Notification.Builder nb2 = new Notification.Builder(mContext, "")
                 .setProgress(100, 100, false);
-        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn2 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb2.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r2 =
                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
@@ -7113,14 +7124,14 @@
     public void testVisualDifference_diffProgressNotDone() {
         Notification.Builder nb1 = new Notification.Builder(mContext, "")
                 .setProgress(100, 90, false);
-        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn1 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb1.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r1 =
                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
 
         Notification.Builder nb2 = new Notification.Builder(mContext, "")
                 .setProgress(100, 91, false);
-        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn2 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb2.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r2 =
                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
@@ -7132,14 +7143,14 @@
     public void testVisualDifference_sameProgressStillDone() {
         Notification.Builder nb1 = new Notification.Builder(mContext, "")
                 .setProgress(100, 100, false);
-        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn1 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb1.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r1 =
                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
 
         Notification.Builder nb2 = new Notification.Builder(mContext, "")
                 .setProgress(100, 100, false);
-        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn2 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb2.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r2 =
                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
@@ -7153,7 +7164,7 @@
                 .setGroup("bananas")
                 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
                 .setContentText("foo");
-        StatusBarNotification sbn1 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn1 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb1.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r1 =
                 new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
@@ -7162,7 +7173,7 @@
                 .setGroup("bananas")
                 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
                 .setContentText("bar");
-        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn2 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb2.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r2 =
                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
@@ -7176,7 +7187,7 @@
                 .setGroup("bananas")
                 .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
                 .setContentText("bar");
-        StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+        StatusBarNotification sbn2 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
                 nb2.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r2 =
                 new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
@@ -7227,10 +7238,31 @@
         assertThat(mService.isVisuallyInterruptive(r1, r2)).isTrue();
     }
 
+    @Test
+    @EnableFlags({android.app.Flags.FLAG_UPDATE_RANKING_TIME})
+    public void testVisualDifference_userInitiatedJob() {
+        Notification.Builder nb1 = new Notification.Builder(mContext, "")
+                .setContentTitle("foo");
+        StatusBarNotification sbn1 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
+                nb1.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
+        NotificationRecord r1 =
+                new NotificationRecord(mContext, sbn1, mock(NotificationChannel.class));
+
+        Notification.Builder nb2 = new Notification.Builder(mContext, "")
+                .setFlag(FLAG_USER_INITIATED_JOB, true)
+                .setContentTitle("bar");
+        StatusBarNotification sbn2 = new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0,
+                nb2.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
+        NotificationRecord r2 =
+                new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
+
+        assertFalse(mService.isVisuallyInterruptive(r1, r2));
+    }
+
     private NotificationRecord notificationToRecord(Notification n) {
         return new NotificationRecord(
                 mContext,
-                new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0, n,
+                new StatusBarNotification(mPkg, mPkg, 0, "tag", mUid, 0, n,
                         UserHandle.getUserHandleForUid(mUid), null, 0),
                 mock(NotificationChannel.class));
     }
@@ -7246,13 +7278,13 @@
         mService.addNotification(notif2);
 
         // on broadcast, hide the 2 notifications
-        simulatePackageSuspendBroadcast(true, PKG, notif1.getUid());
+        simulatePackageSuspendBroadcast(true, mPkg, notif1.getUid());
         ArgumentCaptor<List> captorHide = ArgumentCaptor.forClass(List.class);
         verify(mListeners, times(1)).notifyHiddenLocked(captorHide.capture());
         assertEquals(2, captorHide.getValue().size());
 
         // on broadcast, unhide the 2 notifications
-        simulatePackageSuspendBroadcast(false, PKG, notif1.getUid());
+        simulatePackageSuspendBroadcast(false, mPkg, notif1.getUid());
         ArgumentCaptor<List> captorUnhide = ArgumentCaptor.forClass(List.class);
         verify(mListeners, times(1)).notifyUnhiddenLocked(captorUnhide.capture());
         assertEquals(2, captorUnhide.getValue().size());
@@ -7286,7 +7318,7 @@
         mService.addNotification(notif2);
 
         // on broadcast, nothing is hidden since no notifications are of user 10 with package PKG
-        simulatePackageSuspendBroadcast(true, PKG, 10);
+        simulatePackageSuspendBroadcast(true, mPkg, 10);
         ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
         verify(mListeners, times(1)).notifyHiddenLocked(captor.capture());
         assertEquals(0, captor.getValue().size());
@@ -7467,7 +7499,7 @@
                 mContext, mTestNotificationChannel.getId())
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon);
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
                 "tag" + System.currentTimeMillis(),  UserHandle.PER_USER_RANGE, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid + UserHandle.PER_USER_RANGE),
                 null, 0);
@@ -7490,7 +7522,7 @@
                 mContext, mTestNotificationChannel.getId())
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon);
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
                 "tag" + System.currentTimeMillis(),  UserHandle.PER_USER_RANGE, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid + UserHandle.PER_USER_RANGE),
                 null, 0);
@@ -7540,31 +7572,31 @@
 
     @Test
     public void testBubble() throws Exception {
-        mBinderService.setBubblesAllowed(PKG, mUid, BUBBLE_PREFERENCE_NONE);
-        assertFalse(mBinderService.areBubblesAllowed(PKG));
-        assertEquals(mBinderService.getBubblePreferenceForPackage(PKG, mUid),
+        mBinderService.setBubblesAllowed(mPkg, mUid, BUBBLE_PREFERENCE_NONE);
+        assertFalse(mBinderService.areBubblesAllowed(mPkg));
+        assertEquals(mBinderService.getBubblePreferenceForPackage(mPkg, mUid),
                 BUBBLE_PREFERENCE_NONE);
     }
 
     @Test
     public void testUserApprovedBubblesForPackageSelected() throws Exception {
-        mBinderService.setBubblesAllowed(PKG, mUid, BUBBLE_PREFERENCE_SELECTED);
-        assertEquals(mBinderService.getBubblePreferenceForPackage(PKG, mUid),
+        mBinderService.setBubblesAllowed(mPkg, mUid, BUBBLE_PREFERENCE_SELECTED);
+        assertEquals(mBinderService.getBubblePreferenceForPackage(mPkg, mUid),
                 BUBBLE_PREFERENCE_SELECTED);
     }
 
     @Test
     public void testUserApprovedBubblesForPackageAll() throws Exception {
-        mBinderService.setBubblesAllowed(PKG, mUid, BUBBLE_PREFERENCE_ALL);
-        assertTrue(mBinderService.areBubblesAllowed(PKG));
-        assertEquals(mBinderService.getBubblePreferenceForPackage(PKG, mUid),
+        mBinderService.setBubblesAllowed(mPkg, mUid, BUBBLE_PREFERENCE_ALL);
+        assertTrue(mBinderService.areBubblesAllowed(mPkg));
+        assertEquals(mBinderService.getBubblePreferenceForPackage(mPkg, mUid),
                 BUBBLE_PREFERENCE_ALL);
     }
 
     @Test
     public void testUserRejectsBubblesForPackage() throws Exception {
-        mBinderService.setBubblesAllowed(PKG, mUid, BUBBLE_PREFERENCE_NONE);
-        assertFalse(mBinderService.areBubblesAllowed(PKG));
+        mBinderService.setBubblesAllowed(mPkg, mUid, BUBBLE_PREFERENCE_NONE);
+        assertFalse(mBinderService.areBubblesAllowed(mPkg));
     }
 
     @Test
@@ -7763,14 +7795,14 @@
         Notification n = new Notification.Builder(mContext, "").build();
         n.flags |= FLAG_FOREGROUND_SERVICE;
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 9, null, mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 9, null, mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
         mService.addEnqueuedNotification(r);
 
         mInternalService.removeForegroundServiceFlagFromNotification(
-                PKG, r.getSbn().getId(), r.getSbn().getUserId());
+                mPkg, r.getSbn().getId(), r.getSbn().getUserId());
 
         waitForIdle();
 
@@ -7785,14 +7817,14 @@
         Notification n = new Notification.Builder(mContext, "").build();
         n.flags |= FLAG_FOREGROUND_SERVICE;
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 9, null, mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 9, null, mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
         mService.addNotification(r);
 
         mInternalService.removeForegroundServiceFlagFromNotification(
-                PKG, r.getSbn().getId(), r.getSbn().getUserId());
+                mPkg, r.getSbn().getId(), r.getSbn().getUserId());
 
         waitForIdle();
 
@@ -7810,7 +7842,7 @@
                 .thenReturn(SHOW_IMMEDIATELY);
         for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) {
             Notification n = new Notification.Builder(mContext, "").build();
-            StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, i, null, mUid, 0,
+            StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, i, null, mUid, 0,
                     n, UserHandle.getUserHandleForUid(mUid), null, 0);
             NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
             mService.addEnqueuedNotification(r);
@@ -7818,7 +7850,7 @@
         Notification n = new Notification.Builder(mContext, "").build();
         n.flags |= FLAG_FOREGROUND_SERVICE;
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg,
                 NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS, null, mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
@@ -7826,7 +7858,7 @@
         mService.addEnqueuedNotification(r);
 
         mInternalService.removeForegroundServiceFlagFromNotification(
-                PKG, r.getSbn().getId(), r.getSbn().getUserId());
+                mPkg, r.getSbn().getId(), r.getSbn().getUserId());
 
         waitForIdle();
 
@@ -7841,7 +7873,7 @@
                 .thenReturn(SHOW_IMMEDIATELY);
         for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) {
             Notification n = new Notification.Builder(mContext, "").build();
-            StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, i, null, mUid, 0,
+            StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, i, null, mUid, 0,
                     n, UserHandle.getUserHandleForUid(mUid), null, 0);
             NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
             mService.addNotification(r);
@@ -7849,7 +7881,7 @@
         Notification n = new Notification.Builder(mContext, "").build();
         n.flags |= FLAG_FOREGROUND_SERVICE;
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg,
                 NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS, null, mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
@@ -7857,7 +7889,7 @@
         mService.addNotification(r);
 
         mInternalService.removeForegroundServiceFlagFromNotification(
-                PKG, r.getSbn().getId(), r.getSbn().getUserId());
+                mPkg, r.getSbn().getId(), r.getSbn().getUserId());
 
         waitForIdle();
 
@@ -8620,34 +8652,128 @@
     }
 
     @Test
-    public void testOnNotificationActionClickLifetimeExtendedEnds() {
+    public void testActionClickLifetimeExtendedCancel() throws Exception {
         mSetFlagsRule.enableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
+
         final Notification.Action action =
                 new Notification.Action.Builder(null, "text", PendingIntent.getActivity(
                         mContext, 0, new Intent(), PendingIntent.FLAG_IMMUTABLE)).build();
-        final boolean generatedByAssistant = false;
 
         // Creates a notification marked as being lifetime extended.
         NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
         r.getSbn().getNotification().flags |= FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
         mService.addNotification(r);
+
+        StatusBarNotification[] notifs =
+                mBinderService.getActiveNotifications(mPkg);
+        assertThat(notifs.length).isEqualTo(1);
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(1);
+
         // Call on action click.
         NotificationVisibility notificationVisibility =
                 NotificationVisibility.obtain(r.getKey(), 1, 2, true);
         mService.mNotificationDelegate.onNotificationActionClick(
                 10, 10, r.getKey(), /*actionIndex=*/2, action, notificationVisibility,
                 /*generatedByAssistant=*/false);
-        // The flag is removed, so the notification is no longer lifetime extended.
-        assertThat(r.getSbn().getNotification().flags
-                & FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY).isEqualTo(0);
 
-        // The record is sent out without the flag.
-        ArgumentCaptor<NotificationRecord> captor =
-                ArgumentCaptor.forClass(NotificationRecord.class);
-        verify(mAssistants, times(1)).notifyAssistantActionClicked(
-                captor.capture(), eq(action), eq(generatedByAssistant));
-        assertThat(captor.getValue().getNotification().flags
-                & FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY).isEqualTo(0);
+        // Lifetime extended flag persists.
+        assertThat(r.getSbn().getNotification().flags
+                & FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY).isGreaterThan(0);
+
+        mTestableLooper.moveTimeForward(210);
+        waitForIdle();
+        verify(mWorkerHandler, times(1))
+                .scheduleCancelNotification(
+                        any(NotificationManagerService.CancelNotificationRunnable.class), eq(200));
+
+        // Check that the cancelation occurred and the notification is gone.
+        notifs = mBinderService.getActiveNotifications(mPkg);
+        assertThat(notifs.length).isEqualTo(0);
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(0);
+    }
+
+    @Test
+    public void testActionClickLifetimeExtendedCancel_PreventByNoDismiss() throws Exception {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
+
+        final Notification.Action action =
+                new Notification.Action.Builder(null, "text", PendingIntent.getActivity(
+                        mContext, 0, new Intent(), PendingIntent.FLAG_IMMUTABLE)).build();
+
+        // Creates a notification marked as being lifetime extended.
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+        r.getSbn().getNotification().flags |= FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+        // Make the notification non-dismissable
+        r.getSbn().getNotification().flags |= FLAG_NO_DISMISS;
+        mService.addNotification(r);
+
+        StatusBarNotification[] notifs =
+                mBinderService.getActiveNotifications(mPkg);
+        assertThat(notifs.length).isEqualTo(1);
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(1);
+
+        // Call on action click.
+        NotificationVisibility notificationVisibility =
+                NotificationVisibility.obtain(r.getKey(), 1, 2, true);
+        mService.mNotificationDelegate.onNotificationActionClick(
+                10, 10, r.getKey(), /*actionIndex=*/2, action, notificationVisibility,
+                /*generatedByAssistant=*/false);
+
+        // Lifetime extended flag persists.
+        assertThat(r.getSbn().getNotification().flags
+                & FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY).isGreaterThan(0);
+
+        mTestableLooper.moveTimeForward(210);
+        waitForIdle();
+        verify(mWorkerHandler, times(1))
+                .scheduleCancelNotification(
+                        any(NotificationManagerService.CancelNotificationRunnable.class), eq(200));
+
+        // The cancellation is dropped and the notification is still present, with the update.
+        notifs = mBinderService.getActiveNotifications(mPkg);
+        assertThat(notifs.length).isEqualTo(1);
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(1);
+    }
+
+    @Test
+    public void testUpdateOnActionClickDropsLifetimeExtendedCancel() throws Exception {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_LIFETIME_EXTENSION_REFACTOR);
+
+        final Notification.Action action =
+                new Notification.Action.Builder(null, "text", PendingIntent.getActivity(
+                        mContext, 0, new Intent(), PendingIntent.FLAG_IMMUTABLE)).build();
+
+        // Creates a notification marked as being lifetime extended.
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+        r.getSbn().getNotification().flags |= FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY;
+        mService.addNotification(r);
+
+        StatusBarNotification[] notifs =
+                mBinderService.getActiveNotifications(mPkg);
+        assertThat(notifs.length).isEqualTo(1);
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(1);
+
+        // Call on action click.
+        NotificationVisibility notificationVisibility =
+                NotificationVisibility.obtain(r.getKey(), 1, 2, true);
+        mService.mNotificationDelegate.onNotificationActionClick(
+                10, 10, r.getKey(), /*actionIndex=*/2, action, notificationVisibility,
+                /*generatedByAssistant=*/false);
+
+        // The "app" sends an update of the notification in response.
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(),
+                r.getSbn().getId(), r.getSbn().getNotification(), r.getSbn().getUserId());
+
+        mTestableLooper.moveTimeForward(210);
+        waitForIdle();
+        verify(mWorkerHandler, times(1))
+                .scheduleCancelNotification(
+                        any(NotificationManagerService.CancelNotificationRunnable.class), eq(200));
+
+        // The cancellation is dropped and the notification is still present, with the update.
+        notifs = mBinderService.getActiveNotifications(mPkg);
+        assertThat(notifs.length).isEqualTo(1);
+        assertThat(mService.getNotificationRecordCount()).isEqualTo(1);
     }
 
     @Test
@@ -8675,6 +8801,7 @@
                 mNotificationRecordLogger.event(0));
     }
 
+
     @Test
     public void testLogSmartSuggestionsVisible_triggerOnExpandAndVisible() {
         NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
@@ -8723,7 +8850,7 @@
                         .setContentTitle("foo")
                         .setSmallIcon(android.R.drawable.sym_def_app_icon);
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, "opPkg", 0, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, "opPkg", 0, "tag", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r =  new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -8745,7 +8872,7 @@
         NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
         mService.addNotification(r);
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, r.getSbn().getId(),
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, r.getSbn().getId(),
                 r.getSbn().getTag(), mUid, 0,
                 new Notification.Builder(mContext, mTestNotificationChannel.getId()).build(),
                 UserHandle.getUserHandleForUid(mUid), null, 0);
@@ -9073,7 +9200,7 @@
 
     @Test
     public void testFlagBubble() throws RemoteException {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -9081,11 +9208,11 @@
         NotificationRecord nr =
                 generateMessageBubbleNotifRecord(mTestNotificationChannel, "testFlagBubble");
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
-        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifs.length);
         assertTrue((notifs[0].getNotification().flags & FLAG_BUBBLE) != 0);
         assertTrue(mService.getNotificationRecord(
@@ -9094,7 +9221,7 @@
 
     @Test
     public void testFlagBubble_noFlag_appNotAllowed() throws RemoteException {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_NONE /* app */,
                 true /* channel */);
@@ -9102,11 +9229,11 @@
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                         "testFlagBubble_noFlag_appNotAllowed");
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
-        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifs.length);
         assertEquals((notifs[0].getNotification().flags & FLAG_BUBBLE), 0);
         assertFalse(mService.getNotificationRecord(
@@ -9115,7 +9242,7 @@
 
     @Test
     public void testFlagBubbleNotifs_noFlag_whenAppForeground() throws RemoteException {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -9126,14 +9253,14 @@
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
                 .setBubbleMetadata(getBubbleMetadata());
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1, "tag", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
         // Say we're foreground
         when(mActivityManager.getPackageImportance(nr.getSbn().getPackageName())).thenReturn(
                 IMPORTANCE_FOREGROUND);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -9145,7 +9272,7 @@
 
     @Test
     public void testFlagBubbleNotifs_flag_messaging() throws RemoteException {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -9153,7 +9280,7 @@
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                 "testFlagBubbleNotifs_flag_messaging");
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -9164,18 +9291,18 @@
 
     @Test
     public void testFlagBubbleNotifs_noFlag_noShortcut() throws RemoteException {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
 
         Notification.Builder nb = getMessageStyleNotifBuilder(true, null, false);
         nb.setShortcutId(null);
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
                 null, mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, sbn.getTag(),
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         waitForIdle();
 
@@ -9186,7 +9313,7 @@
 
     @Test
     public void testFlagBubbleNotifs_noFlag_messaging_appNotAllowed() throws RemoteException {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_NONE /* app */,
                 true /* channel */);
@@ -9195,7 +9322,7 @@
                 "testFlagBubbleNotifs_noFlag_messaging_appNotAllowed");
 
         // Post the notification
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -9206,7 +9333,7 @@
 
     @Test
     public void testFlagBubbleNotifs_noFlag_notBubble() throws RemoteException {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -9215,13 +9342,13 @@
         Notification.Builder nb = getMessageStyleNotifBuilder(false /* addBubbleMetadata */,
                 null /* groupKey */, false /* isSummary */);
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
                 "testFlagBubbleNotifs_noFlag_notBubble", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
         // Post the notification
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -9232,7 +9359,7 @@
 
     @Test
     public void testFlagBubbleNotifs_noFlag_messaging_channelNotAllowed() throws RemoteException {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 false /* channel */);
@@ -9242,7 +9369,7 @@
         nr.getChannel().lockFields(USER_LOCKED_ALLOW_BUBBLE);
 
         // Post the notification
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -9257,22 +9384,22 @@
         nrBubble.getSbn().getNotification().flags |= FLAG_BUBBLE;
 
         // Post the notification
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testAppCancelNotifications_cancelsBubbles",
                 nrBubble.getSbn().getId(), nrBubble.getSbn().getNotification(),
                 nrBubble.getSbn().getUserId());
         waitForIdle();
 
-        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifs.length);
         assertEquals(1, mService.getNotificationRecordCount());
 
-        mBinderService.cancelNotificationWithTag(PKG, PKG,
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg,
                 "testAppCancelNotifications_cancelsBubbles", nrBubble.getSbn().getId(),
                 nrBubble.getSbn().getUserId());
         waitForIdle();
 
-        StatusBarNotification[] notifs2 = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs2 = mBinderService.getActiveNotifications(mPkg);
         assertEquals(0, notifs2.length);
         assertEquals(0, mService.getNotificationRecordCount());
     }
@@ -9283,10 +9410,10 @@
         nr.getSbn().getNotification().flags |= FLAG_BUBBLE;
         mService.addNotification(nr);
 
-        mBinderService.cancelAllNotifications(PKG, nr.getSbn().getUserId());
+        mBinderService.cancelAllNotifications(mPkg, nr.getSbn().getUserId());
         waitForIdle();
 
-        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(mPkg);
         assertEquals(0, notifs.length);
         assertEquals(0, mService.getNotificationRecordCount());
     }
@@ -9303,7 +9430,7 @@
         mService.getBinderService().cancelNotificationsFromListener(null, null);
         waitForIdle();
 
-        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifs.length);
         assertEquals(1, mService.getNotificationRecordCount());
     }
@@ -9320,7 +9447,7 @@
         waitForIdle();
 
         // Notif not active anymore
-        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(mPkg);
         assertEquals(0, notifs.length);
         assertEquals(0, mService.getNotificationRecordCount());
         // Cancel event is logged
@@ -9332,13 +9459,13 @@
     @Test
     public void testCancelNotificationsFromListener_suppressesBubble() throws Exception {
         // Add bubble notif
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
             true /* global */,
             BUBBLE_PREFERENCE_ALL /* app */,
             true /* channel */);
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "tag");
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
             nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -9348,7 +9475,7 @@
         waitForIdle();
 
         // Bubble notif active and suppressed
-        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifs.length);
         assertEquals(1, mService.getNotificationRecordCount());
         assertTrue(notifs[0].getNotification().getBubbleMetadata().isNotificationSuppressed());
@@ -9367,7 +9494,7 @@
         waitForIdle();
 
         // THEN the bubble notification does not get removed
-        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifs.length);
         assertEquals(1, mService.getNotificationRecordCount());
     }
@@ -9498,13 +9625,13 @@
 
         AutomaticZenRule rule = new AutomaticZenRule.Builder("rule", Uri.parse("uri"))
                 .setType(AutomaticZenRule.TYPE_MANAGED)
-                .setOwner(new ComponentName(PKG, "cls"))
+                .setOwner(new ComponentName(mPkg, "cls"))
                 .build();
         when(mDevicePolicyManager.isActiveDeviceOwner(anyInt())).thenReturn(true);
 
-        mBinderService.addAutomaticZenRule(rule, PKG, /* fromUser= */ false);
+        mBinderService.addAutomaticZenRule(rule, mPkg, /* fromUser= */ false);
 
-        verify(zenModeHelper).addAutomaticZenRule(eq(PKG), eq(rule), anyInt(), any(), anyInt());
+        verify(zenModeHelper).addAutomaticZenRule(eq(mPkg), eq(rule), anyInt(), any(), anyInt());
     }
 
     @Test
@@ -9526,27 +9653,27 @@
         ZenModeHelper zenModeHelper = setUpMockZenTest();
         mService.setCallerIsNormalPackage();
         reset(mPackageManagerInternal);
-        when(mPackageManagerInternal.isSameApp(eq(PKG), eq(mUid), anyInt())).thenReturn(true);
+        when(mPackageManagerInternal.isSameApp(eq(mPkg), eq(mUid), anyInt())).thenReturn(true);
         when(mResources
                 .getString(com.android.internal.R.string.config_systemWellbeing))
-                .thenReturn(PKG);
+                .thenReturn(mPkg);
         when(mContext.getResources()).thenReturn(mResources);
 
         AutomaticZenRule rule = new AutomaticZenRule.Builder("rule", Uri.parse("uri"))
                 .setType(AutomaticZenRule.TYPE_BEDTIME)
-                .setOwner(new ComponentName(PKG, "cls"))
+                .setOwner(new ComponentName(mPkg, "cls"))
                 .build();
 
-        mBinderService.addAutomaticZenRule(rule, PKG, /* fromUser= */ false);
+        mBinderService.addAutomaticZenRule(rule, mPkg, /* fromUser= */ false);
 
-        verify(zenModeHelper).addAutomaticZenRule(eq(PKG), eq(rule), anyInt(), any(), anyInt());
+        verify(zenModeHelper).addAutomaticZenRule(eq(mPkg), eq(rule), anyInt(), any(), anyInt());
     }
 
     @Test
     @EnableFlags(android.app.Flags.FLAG_MODES_API)
     public void testAddAutomaticZenRule_typeBedtimeCanBeUsedBySystem() throws Exception {
         reset(mPackageManagerInternal);
-        when(mPackageManagerInternal.isSameApp(eq(PKG), eq(mUid), anyInt())).thenReturn(true);
+        when(mPackageManagerInternal.isSameApp(eq(mPkg), eq(mUid), anyInt())).thenReturn(true);
         addAutomaticZenRule_restrictedRuleTypeCanBeUsedBySystem(AutomaticZenRule.TYPE_BEDTIME);
     }
 
@@ -9554,7 +9681,7 @@
     @EnableFlags(android.app.Flags.FLAG_MODES_API)
     public void testAddAutomaticZenRule_typeBedtimeCannotBeUsedByRegularApps() throws Exception {
         reset(mPackageManagerInternal);
-        when(mPackageManagerInternal.isSameApp(eq(PKG), eq(mUid), anyInt())).thenReturn(true);
+        when(mPackageManagerInternal.isSameApp(eq(mPkg), eq(mUid), anyInt())).thenReturn(true);
         addAutomaticZenRule_restrictedRuleTypeCannotBeUsedByRegularApps(
                 AutomaticZenRule.TYPE_BEDTIME);
     }
@@ -9566,13 +9693,13 @@
 
         AutomaticZenRule rule = new AutomaticZenRule.Builder("rule", Uri.parse("uri"))
                 .setType(ruleType)
-                .setOwner(new ComponentName(PKG, "cls"))
+                .setOwner(new ComponentName(mPkg, "cls"))
                 .build();
         when(mDevicePolicyManager.isActiveDeviceOwner(anyInt())).thenReturn(true);
 
-        mBinderService.addAutomaticZenRule(rule, PKG, /* fromUser= */ false);
+        mBinderService.addAutomaticZenRule(rule, mPkg, /* fromUser= */ false);
 
-        verify(zenModeHelper).addAutomaticZenRule(eq(PKG), eq(rule), anyInt(), any(), anyInt());
+        verify(zenModeHelper).addAutomaticZenRule(eq(mPkg), eq(rule), anyInt(), any(), anyInt());
     }
 
     private void addAutomaticZenRule_restrictedRuleTypeCannotBeUsedByRegularApps(
@@ -9584,12 +9711,12 @@
 
         AutomaticZenRule rule = new AutomaticZenRule.Builder("rule", Uri.parse("uri"))
                 .setType(ruleType)
-                .setOwner(new ComponentName(PKG, "cls"))
+                .setOwner(new ComponentName(mPkg, "cls"))
                 .build();
         when(mDevicePolicyManager.isActiveDeviceOwner(anyInt())).thenReturn(false);
 
         assertThrows(IllegalArgumentException.class,
-                () -> mBinderService.addAutomaticZenRule(rule, PKG, /* fromUser= */ false));
+                () -> mBinderService.addAutomaticZenRule(rule, mPkg, /* fromUser= */ false));
     }
 
     @Test
@@ -9871,7 +9998,7 @@
 
     @Test
     public void testNotificationBubbleChanged_false() throws Exception {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -9880,7 +10007,7 @@
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                 "testNotificationBubbleChanged_false");
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -9888,7 +10015,7 @@
         reset(mListeners);
 
         // First we were a bubble
-        StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifsBefore.length);
         assertTrue((notifsBefore[0].getNotification().flags & FLAG_BUBBLE) != 0);
 
@@ -9897,14 +10024,14 @@
         waitForIdle();
 
         // Make sure we are not a bubble
-        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifsAfter.length);
         assertEquals((notifsAfter[0].getNotification().flags & FLAG_BUBBLE), 0);
     }
 
     @Test
     public void testNotificationBubbleChanged_true() throws Exception {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -9912,19 +10039,19 @@
         // Notif that is not a bubble
         NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel,
                 1, null, false);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // Would be a normal notification because wouldn't have met requirements to bubble
-        StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifsBefore.length);
         assertEquals((notifsBefore[0].getNotification().flags & FLAG_BUBBLE), 0);
 
         // Update the notification to be message style / meet bubble requirements
         NotificationRecord nr2 = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                 nr.getSbn().getTag());
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr2.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr2.getSbn().getTag(),
                 nr2.getSbn().getId(), nr2.getSbn().getNotification(), nr2.getSbn().getUserId());
         waitForIdle();
 
@@ -9936,21 +10063,21 @@
         waitForIdle();
 
         // Make sure we are a bubble
-        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifsAfter.length);
         assertTrue((notifsAfter[0].getNotification().flags & FLAG_BUBBLE) != 0);
     }
 
     @Test
     public void testNotificationBubbleChanged_true_notAllowed() throws Exception {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
 
         // Notif that is not a bubble
         NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -9958,7 +10085,7 @@
         reset(mListeners);
 
         // Would be a normal notification because wouldn't have met requirements to bubble
-        StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifsBefore.length);
         assertEquals((notifsBefore[0].getNotification().flags & FLAG_BUBBLE), 0);
 
@@ -9967,14 +10094,14 @@
         waitForIdle();
 
         // We still wouldn't be a bubble because the notification didn't meet requirements
-        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifsAfter.length);
         assertEquals((notifsAfter[0].getNotification().flags & FLAG_BUBBLE), 0);
     }
 
     @Test
     public void testNotificationBubbleIsFlagRemoved_resetOnUpdate() throws Exception {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -9983,7 +10110,7 @@
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                 "testNotificationBubbleIsFlagRemoved_resetOnUpdate");
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
         // Flag shouldn't be modified
@@ -9999,7 +10126,7 @@
 
 
         // Update the notif
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
         // And the flag is reset
@@ -10009,7 +10136,7 @@
 
     @Test
     public void testNotificationBubbleIsFlagRemoved_resetOnBubbleChangedTrue() throws Exception {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -10018,7 +10145,7 @@
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                 "testNotificationBubbleIsFlagRemoved_trueOnBubbleChangedTrue");
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
         // Flag shouldn't be modified
@@ -10041,7 +10168,7 @@
 
     @Test
     public void testOnBubbleMetadataFlagChanged() throws Exception {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -10051,12 +10178,12 @@
         // Set this so that the bubble can be suppressed
         nr.getNotification().getBubbleMetadata().setFlags(
                 Notification.BubbleMetadata.FLAG_SUPPRESSABLE_BUBBLE);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // Check the flags
-        Notification n =  mBinderService.getActiveNotifications(PKG)[0].getNotification();
+        Notification n =  mBinderService.getActiveNotifications(mPkg)[0].getNotification();
         assertFalse(n.getBubbleMetadata().isNotificationSuppressed());
         assertFalse(n.getBubbleMetadata().getAutoExpandBubble());
         assertFalse(n.getBubbleMetadata().isBubbleSuppressed());
@@ -10074,7 +10201,7 @@
         waitForIdle();
 
         // Check
-        n =  mBinderService.getActiveNotifications(PKG)[0].getNotification();
+        n =  mBinderService.getActiveNotifications(mPkg)[0].getNotification();
         assertEquals(flags, n.getBubbleMetadata().getFlags());
 
         // Reset to check again
@@ -10085,7 +10212,7 @@
         waitForIdle();
 
         // Check
-        n = mBinderService.getActiveNotifications(PKG)[0].getNotification();
+        n = mBinderService.getActiveNotifications(mPkg)[0].getNotification();
         assertEquals(0, n.getBubbleMetadata().getFlags());
     }
 
@@ -10093,14 +10220,14 @@
     public void testOnBubbleMetadataChangedToSuppressNotification_soundStopped()
             throws RemoteException {
 
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
 
         // Post a bubble notification
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel, "tag");
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -10120,12 +10247,12 @@
                 : USER_SYSTEM;
 
         NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel, userId);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag",
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // A notification exists for the given record
-        StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifsBefore.length);
 
         reset(mPackageManager);
@@ -10152,7 +10279,7 @@
         waitForIdle();
 
         // No notifications exist for the given record
-        StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(mPkg);
         assertEquals(0, notifsBefore.length);
 
         Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 1);
@@ -10172,12 +10299,12 @@
         // generate a NotificationRecord for USER_ALL to make sure it's converted into USER_SYSTEM
         NotificationRecord nr =
                 generateNotificationRecord(mTestNotificationChannel, UserHandle.USER_ALL);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag",
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // A notification exists for the given record
-        StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifsBefore.length);
 
         reset(mPackageManager);
@@ -10202,13 +10329,13 @@
         int otherUserId = 11;
         NotificationRecord nr =
                 generateNotificationRecord(mTestNotificationChannel, otherUserId);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag",
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // A notification exists for the given record
         List<StatusBarNotification> notifsBefore =
-                mBinderService.getAppActiveNotifications(PKG, nr.getSbn().getUserId()).getList();
+                mBinderService.getAppActiveNotifications(mPkg, nr.getSbn().getUserId()).getList();
         assertEquals(1, notifsBefore.size());
 
         reset(mPackageManager);
@@ -10310,7 +10437,7 @@
 
     @Test
     public void testNotificationBubbles_disabled_lowRamDevice() throws Exception {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -10321,12 +10448,12 @@
         // Notification that would typically bubble
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                 "testNotificationBubbles_disabled_lowRamDevice");
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         // But we wouldn't be a bubble because the device is low ram & all bubbles are disabled.
-        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifsAfter.length);
         assertEquals((notifsAfter[0].getNotification().flags & FLAG_BUBBLE), 0);
     }
@@ -10381,7 +10508,7 @@
         assertNotNull(n.publicVersion.bigContentView);
         assertNotNull(n.publicVersion.headsUpContentView);
 
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         assertNull(n.contentView);
         assertNull(n.bigContentView);
@@ -10390,13 +10517,13 @@
         assertNull(n.publicVersion.bigContentView);
         assertNull(n.publicVersion.headsUpContentView);
 
-        verify(mUsageStats, times(5)).registerImageRemoved(PKG);
+        verify(mUsageStats, times(5)).registerImageRemoved(mPkg);
     }
 
     @Test
     public void testNotificationBubbles_flagAutoExpandForeground_fails_notForeground()
             throws Exception {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -10412,7 +10539,7 @@
         when(mActivityManager.getPackageImportance(nr.getSbn().getPackageName())).thenReturn(
                 IMPORTANCE_VISIBLE);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -10427,7 +10554,7 @@
     @Test
     public void testNotificationBubbles_flagAutoExpandForeground_succeeds_foreground()
             throws RemoteException {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -10443,7 +10570,7 @@
         when(mActivityManager.getPackageImportance(nr.getSbn().getPackageName())).thenReturn(
                 IMPORTANCE_FOREGROUND);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -10459,7 +10586,7 @@
     @Test
     public void testNotificationBubbles_flagRemoved_whenShortcutRemoved()
             throws RemoteException {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -10474,12 +10601,12 @@
                 null /* groupKey */, false /* isSummary */);
         nb.setShortcutId(VALID_CONVO_SHORTCUT_ID);
         nb.setBubbleMetadata(metadata);
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
                 "tag", mUid, 0, nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
         // Test: Send the bubble notification
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -10494,12 +10621,12 @@
 
         // Make sure the shortcut is cached.
         verify(mShortcutServiceInternal).cacheShortcuts(
-                anyInt(), any(), eq(PKG), eq(singletonList(VALID_CONVO_SHORTCUT_ID)),
+                anyInt(), any(), eq(mPkg), eq(singletonList(VALID_CONVO_SHORTCUT_ID)),
                 eq(USER_SYSTEM), eq(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS));
 
         // Test: Remove the shortcut
         when(mLauncherApps.getShortcuts(any(), any())).thenReturn(null);
-        launcherAppsCallback.getValue().onShortcutsChanged(PKG, emptyList(),
+        launcherAppsCallback.getValue().onShortcutsChanged(mPkg, emptyList(),
                 UserHandle.getUserHandleForUid(mUid));
         waitForIdle();
 
@@ -10519,7 +10646,7 @@
     public void testNotificationBubbles_shortcut_stopListeningWhenNotifRemoved()
             throws RemoteException {
         final String shortcutId = "someshortcutId";
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -10534,14 +10661,14 @@
                 null /* groupKey */, false /* isSummary */);
         nb.setShortcutId(shortcutId);
         nb.setBubbleMetadata(metadata);
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
                 "tag", mUid, 0, nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
         // Pretend the shortcut exists
         List<ShortcutInfo> shortcutInfos = new ArrayList<>();
         ShortcutInfo info = mock(ShortcutInfo.class);
-        when(info.getPackage()).thenReturn(PKG);
+        when(info.getPackage()).thenReturn(mPkg);
         when(info.getId()).thenReturn(shortcutId);
         when(info.getUserId()).thenReturn(USER_SYSTEM);
         when(info.isLongLived()).thenReturn(true);
@@ -10552,7 +10679,7 @@
                 anyString(), anyInt(), any())).thenReturn(true);
 
         // Test: Send the bubble notification
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -10567,11 +10694,11 @@
 
         // Make sure the shortcut is cached.
         verify(mShortcutServiceInternal).cacheShortcuts(
-                anyInt(), any(), eq(PKG), eq(singletonList(shortcutId)),
+                anyInt(), any(), eq(mPkg), eq(singletonList(shortcutId)),
                 eq(USER_SYSTEM), eq(ShortcutInfo.FLAG_CACHED_NOTIFICATIONS));
 
         // Test: Remove the notification
-        mBinderService.cancelNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -10584,7 +10711,7 @@
     @Test
     public void testNotificationBubbles_bubbleChildrenStay_whenGroupSummaryDismissed()
             throws Exception {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -10595,21 +10722,21 @@
         // Dismiss summary
         final NotificationVisibility nv = NotificationVisibility.obtain(nrSummary.getKey(), 1, 2,
                 true);
-        mService.mNotificationDelegate.onNotificationClear(mUid, 0, PKG,
+        mService.mNotificationDelegate.onNotificationClear(mUid, 0, mPkg,
                 nrSummary.getUserId(), nrSummary.getKey(),
                 NotificationStats.DISMISSAL_SHADE,
                 NotificationStats.DISMISS_SENTIMENT_NEUTRAL, nv);
         waitForIdle();
 
         // The bubble should still exist
-        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifsAfter.length);
     }
 
     @Test
     public void testNotificationBubbles_bubbleChildrenStay_whenGroupSummaryClicked()
             throws Exception {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -10625,7 +10752,7 @@
         waitForIdle();
 
         // The bubble should still exist
-        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifsAfter.length);
 
         // Check we got the click log and associated dismissal logs
@@ -10643,7 +10770,7 @@
     @Test
     public void testNotificationBubbles_bubbleStays_whenClicked()
             throws Exception {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -10660,7 +10787,7 @@
         waitForIdle();
 
         // THEN the bubble should still exist
-        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifsAfter.length);
 
         // Check we got the click log
@@ -10677,7 +10804,7 @@
     @Test
     public void testNotificationBubbles_bubbleStays_whenClicked_afterBubbleDismissed()
             throws Exception {
-        setUpPrefsForBubbles(PKG, mUid,
+        setUpPrefsForBubbles(mPkg, mUid,
                 true /* global */,
                 BUBBLE_PREFERENCE_ALL /* app */,
                 true /* channel */);
@@ -10701,7 +10828,7 @@
         waitForIdle();
 
         // THEN the bubble should still exist
-        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(mPkg);
         assertEquals(1, notifsAfter.length);
 
         // Check we got the click log
@@ -10761,7 +10888,7 @@
 
     @Test
     public void testHandleOnPackageChanged() {
-        String[] pkgs = new String[] {PKG, PKG_N_MR1};
+        String[] pkgs = new String[] {mPkg, PKG_N_MR1};
         int[] uids = new int[] {mUid, UserHandle.PER_USER_RANGE + 1};
 
         mService.handleOnPackageChanged(false, USER_SYSTEM, pkgs, uids);
@@ -10788,25 +10915,25 @@
         assertEquals(1, notifs.length);
 
         // Cancels all notifications.
-        mService.cancelAllNotificationsInt(mUid, 0, PKG, null, 0, 0,
+        mService.cancelAllNotificationsInt(mUid, 0, mPkg, null, 0, 0,
                 notif.getUserId(), REASON_CANCEL);
         waitForIdle();
         notifs = mBinderService.getActiveNotifications(notif.getSbn().getPackageName());
         assertEquals(0, notifs.length);
 
         // Checks that notification history's recently canceled archive contains the notification.
-        notifs = mBinderService.getHistoricalNotificationsWithAttribution(PKG,
+        notifs = mBinderService.getHistoricalNotificationsWithAttribution(mPkg,
                         mContext.getAttributionTag(), 5 /* count */, false /* includeSnoozed */);
         waitForIdle();
         assertEquals(1, notifs.length);
 
         // Remove sthe package that contained the channel
-        simulatePackageRemovedBroadcast(PKG, mUid);
+        simulatePackageRemovedBroadcast(mPkg, mUid);
         waitForIdle();
 
         // Checks that notification history no longer contains the notification.
         notifs = mBinderService.getHistoricalNotificationsWithAttribution(
-                PKG, mContext.getAttributionTag(), 5 /* count */, false /* includeSnoozed */);
+                mPkg, mContext.getAttributionTag(), 5 /* count */, false /* includeSnoozed */);
         waitForIdle();
         assertEquals(0, notifs.length);
     }
@@ -10815,7 +10942,7 @@
     public void testNotificationHistory_addNoisyNotification() throws Exception {
         NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel,
                 null /* tvExtender */);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -10839,14 +10966,14 @@
         assertEquals(original, orig);
         assertFalse(TextUtils.isEmpty(orig.getName()));
 
-        mBinderService.createNotificationChannels(PKG, new ParceledListSlice(Arrays.asList(
+        mBinderService.createNotificationChannels(mPkg, new ParceledListSlice(Arrays.asList(
                 orig)));
 
         mBinderService.createConversationNotificationChannelForPackage(
-                PKG, mUid, orig, "friend");
+                mPkg, mUid, orig, "friend");
 
         NotificationChannel friendChannel = mBinderService.getConversationNotificationChannel(
-                PKG, userId, PKG, original.getId(), false, "friend");
+                mPkg, userId, mPkg, original.getId(), false, "friend");
 
         assertEquals(original.getName(), friendChannel.getName());
         assertEquals(original.getId(), friendChannel.getParentChannelId());
@@ -10911,15 +11038,15 @@
         NotificationChannel parentChannel = parcelAndUnparcel(originalChannel,
                 NotificationChannel.CREATOR);
         assertEquals(originalChannel, parentChannel);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(parentChannel)));
 
         //Create deleted conversation channel
         mBinderService.createConversationNotificationChannelForPackage(
-                PKG, mUid, parentChannel, VALID_CONVO_SHORTCUT_ID);
+                mPkg, mUid, parentChannel, VALID_CONVO_SHORTCUT_ID);
         final NotificationChannel conversationChannel =
                 mBinderService.getConversationNotificationChannel(
-                PKG, mUserId, PKG, originalChannel.getId(), false, VALID_CONVO_SHORTCUT_ID);
+                        mPkg, mUserId, mPkg, originalChannel.getId(), false, VALID_CONVO_SHORTCUT_ID);
         conversationChannel.setDeleted(true);
 
         //Create notification record
@@ -10927,12 +11054,12 @@
                 null /* groupKey */, false /* isSummary */);
         nb.setShortcutId(VALID_CONVO_SHORTCUT_ID);
         nb.setChannelId(originalChannel.getId());
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
                 "tag", mUid, 0, nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord nr = new NotificationRecord(mContext, sbn, originalChannel);
         assertThat(nr.getChannel()).isEqualTo(originalChannel);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -10954,7 +11081,7 @@
         NotificationChannel parentChannel = parcelAndUnparcel(originalChannel,
                 NotificationChannel.CREATOR);
         assertEquals(originalChannel, parentChannel);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(parentChannel)));
         parentChannel.setDeleted(true);
 
@@ -10963,14 +11090,14 @@
                 null /* groupKey */, false /* isSummary */);
         nb.setShortcutId(VALID_CONVO_SHORTCUT_ID);
         nb.setChannelId(originalChannel.getId());
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
                 "tag", mUid, 0, nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord nr = new NotificationRecord(mContext, sbn, originalChannel);
         assertThat(nr.getChannel()).isEqualTo(originalChannel);
 
         when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -10992,27 +11119,27 @@
         NotificationChannel parentChannel = parcelAndUnparcel(originalChannel,
                 NotificationChannel.CREATOR);
         assertEquals(originalChannel, parentChannel);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(parentChannel)));
 
         //Create conversation channel
         mBinderService.createConversationNotificationChannelForPackage(
-                PKG, mUid, parentChannel, VALID_CONVO_SHORTCUT_ID);
+                mPkg, mUid, parentChannel, VALID_CONVO_SHORTCUT_ID);
         final NotificationChannel conversationChannel =
                 mBinderService.getConversationNotificationChannel(
-                    PKG, mUserId, PKG, originalChannel.getId(), false, VALID_CONVO_SHORTCUT_ID);
+                        mPkg, mUserId, mPkg, originalChannel.getId(), false, VALID_CONVO_SHORTCUT_ID);
 
         //Create notification record
         Notification.Builder nb = getMessageStyleNotifBuilder(false /* addDefaultMetadata */,
                 null /* groupKey */, false /* isSummary */);
         nb.setShortcutId(VALID_CONVO_SHORTCUT_ID);
         nb.setChannelId(originalChannel.getId());
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
                 "tag", mUid, 0, nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord nr = new NotificationRecord(mContext, sbn, originalChannel);
         assertThat(nr.getChannel()).isEqualTo(originalChannel);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -11037,27 +11164,27 @@
         NotificationChannel parentChannel = parcelAndUnparcel(originalChannel,
                 NotificationChannel.CREATOR);
         assertEquals(originalChannel, parentChannel);
-        mBinderService.createNotificationChannels(PKG,
+        mBinderService.createNotificationChannels(mPkg,
                 new ParceledListSlice(Arrays.asList(parentChannel)));
 
         //Create deleted conversation channel
         mBinderService.createConversationNotificationChannelForPackage(
-                PKG, mUid, parentChannel, VALID_CONVO_SHORTCUT_ID);
+                mPkg, mUid, parentChannel, VALID_CONVO_SHORTCUT_ID);
         final NotificationChannel conversationChannel =
                 mBinderService.getConversationNotificationChannel(
-                    PKG, mUserId, PKG, originalChannel.getId(), false, VALID_CONVO_SHORTCUT_ID);
+                        mPkg, mUserId, mPkg, originalChannel.getId(), false, VALID_CONVO_SHORTCUT_ID);
 
         //Create notification record without a shortcutId
         Notification.Builder nb = getMessageStyleNotifBuilder(false /* addDefaultMetadata */,
                 null /* groupKey */, false /* isSummary */);
         nb.setShortcutId(null);
         nb.setChannelId(originalChannel.getId());
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
                 "tag", mUid, 0, nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord nr = new NotificationRecord(mContext, sbn, originalChannel);
         assertThat(nr.getChannel()).isEqualTo(originalChannel);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -11173,7 +11300,7 @@
                 generateMessageBubbleNotifRecord(mTestNotificationChannel,
                         "testShortcutHelperNull_doesntCrashEnqueue");
         try {
-            mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+            mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                     nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
             waitForIdle();
         } catch (Exception e) {
@@ -11252,23 +11379,23 @@
     public void testRecordMessages_invalidMsg_afterValidMsg() throws RemoteException {
         NotificationRecord nr = generateMessageBubbleNotifRecord(mTestNotificationChannel,
                 "testRecordMessages_invalidMsg_afterValidMsg_1");
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
         assertTrue(mService.getNotificationRecord(nr.getKey()).isConversation());
 
-        mBinderService.cancelAllNotifications(PKG, mUid);
+        mBinderService.cancelAllNotifications(mPkg, mUid);
         waitForIdle();
 
         Notification.Builder nb = getMessageStyleNotifBuilder(false /* addDefaultMetadata */,
                 null /* groupKey */, false /* isSummary */);
         nb.setShortcutId(null);
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1,
                 "testRecordMessages_invalidMsg_afterValidMsg_2", mUid, 0, nb.build(),
                 UserHandle.getUserHandleForUid(mUid), null, 0);
          nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, nr.getSbn().getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -11283,14 +11410,14 @@
         for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) {
             StatusBarNotification sbn = generateNotificationRecord(mTestNotificationChannel,
                     i, null, false).getSbn();
-            mBinderService.enqueueNotificationWithTag(PKG, PKG,
+            mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                     "testCanPostFgsWhenOverLimit",
                     sbn.getId(), sbn.getNotification(), sbn.getUserId());
         }
 
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCanPostFgsWhenOverLimit - fgs over limit!",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
 
@@ -11311,7 +11438,7 @@
         for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) {
             StatusBarNotification sbn = generateNotificationRecord(mTestNotificationChannel,
                     i, null, false).getSbn();
-            mBinderService.enqueueNotificationWithTag(PKG, PKG,
+            mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                     "testCanPostFgsWhenOverLimit",
                     sbn.getId(), sbn.getNotification(), sbn.getUserId());
             waitForIdle();
@@ -11320,13 +11447,13 @@
         final StatusBarNotification sbn = generateNotificationRecord(mTestNotificationChannel,
                 100, null, false).getSbn();
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCanPostFgsWhenOverLimit - fgs over limit!",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
 
         final StatusBarNotification sbn2 = generateNotificationRecord(mTestNotificationChannel,
                 101, null, false).getSbn();
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCanPostFgsWhenOverLimit - non fgs over limit!",
                 sbn2.getId(), sbn2.getNotification(), sbn2.getUserId());
 
@@ -11337,7 +11464,7 @@
         final StatusBarNotification sbn3 = generateNotificationRecord(mTestNotificationChannel,
                 101, null, false).getSbn();
         sbn3.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCanPostFgsWhenOverLimit - fake fgs over limit!",
                 sbn3.getId(), sbn3.getNotification(), sbn3.getUserId());
 
@@ -11486,7 +11613,7 @@
         NotificationRecord r = generateMessageBubbleNotifRecord(true,
                 mTestNotificationChannel, 7, "testImmutableBubbleIntent", null, false);
         try {
-            mBinderService.enqueueNotificationWithTag(PKG, PKG, r.getSbn().getTag(),
+            mBinderService.enqueueNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(),
                     r.getSbn().getId(), r.getNotification(), r.getSbn().getUserId());
 
             waitForIdle();
@@ -11503,7 +11630,7 @@
         NotificationRecord r = generateMessageBubbleNotifRecord(true,
                 mTestNotificationChannel, 7, "testMutableBubbleIntent", null, false);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, r.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(),
                 r.getSbn().getId(), r.getNotification(), r.getSbn().getUserId());
 
         waitForIdle();
@@ -11519,7 +11646,7 @@
         NotificationRecord r = generateMessageBubbleNotifRecord(false,
                 mTestNotificationChannel, 7, "testImmutableDirectReplyActionIntent", null, false);
         try {
-            mBinderService.enqueueNotificationWithTag(PKG, PKG, r.getSbn().getTag(),
+            mBinderService.enqueueNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(),
                     r.getSbn().getId(), r.getNotification(), r.getSbn().getUserId());
 
             waitForIdle();
@@ -11535,7 +11662,7 @@
                 .thenReturn(FLAG_MUTABLE | FLAG_ONE_SHOT);
         NotificationRecord r = generateMessageBubbleNotifRecord(false,
                 mTestNotificationChannel, 7, "testMutableDirectReplyActionIntent", null, false);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, r.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(),
                 r.getSbn().getId(), r.getNotification(), r.getSbn().getUserId());
 
         waitForIdle();
@@ -11609,7 +11736,7 @@
                 .thenReturn(FLAG_IMMUTABLE | FLAG_ONE_SHOT);
         NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, r.getSbn().getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(),
                 r.getSbn().getId(), r.getNotification(), r.getSbn().getUserId());
 
         waitForIdle();
@@ -11779,9 +11906,9 @@
 
         when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
 
-        assertThat(mBinderService.getNotificationChannelsBypassingDnd(PKG, mUid).getList())
+        assertThat(mBinderService.getNotificationChannelsBypassingDnd(mPkg, mUid).getList())
                 .isEmpty();
-        verify(mPreferencesHelper, never()).getNotificationChannelsBypassingDnd(PKG, mUid);
+        verify(mPreferencesHelper, never()).getNotificationChannelsBypassingDnd(mPkg, mUid);
     }
 
     @Test
@@ -11873,7 +12000,7 @@
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
                 .addAction(new Notification.Action.Builder(null, "test", null).build());
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -11885,7 +12012,7 @@
 
         // just using the style - blocked
         nb.setStyle(new Notification.MediaStyle());
-        sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -11897,7 +12024,7 @@
         Bundle extras = new Bundle();
         extras.putParcelable(Notification.EXTRA_MEDIA_SESSION, new Intent());
         nb.addExtras(extras);
-        sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -11906,7 +12033,7 @@
 
         // style + media session - bypasses block
         nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class)));
-        sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -11924,7 +12051,7 @@
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
                 .addAction(new Notification.Action.Builder(null, "test", null).build());
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -11944,7 +12071,7 @@
         mService.clearNotifications();
         reset(mUsageStats);
         nb.setStyle(new Notification.MediaStyle());
-        sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -11961,7 +12088,7 @@
         mService.clearNotifications();
         reset(mUsageStats);
         nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class)));
-        sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -11986,7 +12113,7 @@
                 .setContentTitle("foo")
                 .setSmallIcon(android.R.drawable.sym_def_app_icon)
                 .addAction(new Notification.Action.Builder(null, "test", null).build());
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -12003,7 +12130,7 @@
         nb.setStyle(Notification.CallStyle.forOngoingCall(
                 person, mock(PendingIntent.class)));
         nb.setFullScreenIntent(mock(PendingIntent.class), true);
-        sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -12051,7 +12178,7 @@
                         .setContentTitle("foo")
                         .setSmallIcon(android.R.drawable.sym_def_app_icon)
                         .addAction(new Notification.Action.Builder(null, "test", null).build());
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -12072,7 +12199,7 @@
         Person person = new Person.Builder().setName("caller").build();
         nb.setStyle(Notification.CallStyle.forOngoingCall(person, mock(PendingIntent.class)));
         nb.setFullScreenIntent(mock(PendingIntent.class), true);
-        sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, nb.build(),
+        sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0, nb.build(),
                 UserHandle.getUserHandleForUid(mUid), null, 0);
         r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -12194,21 +12321,21 @@
 
         NotificationRecord nr0 =
                 generateNotificationRecord(mTestNotificationChannel, mUserId);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag0",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag0",
                 nr0.getSbn().getId(), nr0.getSbn().getNotification(), nr0.getSbn().getUserId());
 
         NotificationRecord nr10 =
                 generateNotificationRecord(mTestNotificationChannel, 10);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag10",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag10",
                 nr10.getSbn().getId(), nr10.getSbn().getNotification(), nr10.getSbn().getUserId());
 
         NotificationRecord nr11 =
                 generateNotificationRecord(mTestNotificationChannel, 11);
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag11",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag11",
                 nr11.getSbn().getId(), nr11.getSbn().getNotification(), nr11.getSbn().getUserId());
         waitForIdle();
 
-        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifs = mBinderService.getActiveNotifications(mPkg);
         assertEquals(2, notifs.length);
         for (StatusBarNotification sbn : notifs) {
             if (sbn.getUserId() == 11) {
@@ -12297,9 +12424,9 @@
                     VISIBILITY_PRIVATE));
 
         // cancel both children
-        mBinderService.cancelNotificationWithTag(PKG, PKG, nr0.getSbn().getTag(),
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0.getSbn().getTag(),
                 nr0.getSbn().getId(), nr0.getSbn().getUserId());
-        mBinderService.cancelNotificationWithTag(PKG, PKG, nr1.getSbn().getTag(),
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr1.getSbn().getTag(),
                 nr1.getSbn().getId(), nr1.getSbn().getUserId());
         waitForIdle();
 
@@ -12339,9 +12466,9 @@
                 nr0_all.getKey(), GroupHelper.BASE_FLAGS, mock(Icon.class), 0, VISIBILITY_PRIVATE));
 
         // cancel both children for USER_ALL
-        mBinderService.cancelNotificationWithTag(PKG, PKG, nr0_all.getSbn().getTag(),
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr0_all.getSbn().getTag(),
                 nr0_all.getSbn().getId(), UserHandle.USER_ALL);
-        mBinderService.cancelNotificationWithTag(PKG, PKG, nr1_all.getSbn().getTag(),
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, nr1_all.getSbn().getTag(),
                 nr1_all.getSbn().getId(), UserHandle.USER_ALL);
         waitForIdle();
 
@@ -12641,7 +12768,7 @@
             boolean isSticky) throws Exception {
 
         when(mPermissionHelper.hasRequestedPermission(Manifest.permission.USE_FULL_SCREEN_INTENT,
-                PKG, mUserId)).thenReturn(appRequested);
+                mPkg, mUserId)).thenReturn(appRequested);
 
         when(mPermissionManager.checkPermissionForDataDelivery(
                 eq(Manifest.permission.USE_FULL_SCREEN_INTENT), any(), any()))
@@ -12651,7 +12778,7 @@
                 .setFullScreenIntent(mock(PendingIntent.class), true)
                 .build();
 
-        mService.fixNotification(n, PKG, "tag", 9, mUserId, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, mUserId, mUid, NOT_FOREGROUND_SERVICE, true);
 
         final int stickyFlag = n.flags & Notification.FLAG_FSI_REQUESTED_BUT_DENIED;
 
@@ -12705,7 +12832,7 @@
                 .setFlag(FLAG_CAN_COLORIZE, true)
                 .build();
 
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         assertFalse(n.isForegroundService());
         assertFalse(n.hasColorizedPermission());
@@ -12718,7 +12845,7 @@
                 .setStyle(Notification.CallStyle.forOngoingCall(
                         person, mock(PendingIntent.class)))
                 .build();
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -12739,7 +12866,7 @@
                 .setStyle(Notification.CallStyle.forOngoingCall(
                         person, mock(PendingIntent.class)))
                 .build();
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -12769,7 +12896,7 @@
         if (isExpired) {
             timePostedMs -= BITMAP_DURATION.toMillis();
         }
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 notification, UserHandle.getUserHandleForUid(mUid), null, timePostedMs);
 
         return new NotificationRecord(mContext, sbn, mTestNotificationChannel);
@@ -12899,7 +13026,7 @@
                 .setStyle(Notification.CallStyle.forOngoingCall(
                         person, mock(PendingIntent.class)))
                 .build();
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -12916,7 +13043,7 @@
                 .setStyle(Notification.CallStyle.forOngoingCall(
                         person, mock(PendingIntent.class)))
                 .build();
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -12932,7 +13059,7 @@
                 .setStyle(Notification.CallStyle.forOngoingCall(
                         person, mock(PendingIntent.class)))
                 .build();
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -12948,7 +13075,7 @@
                 .setStyle(Notification.CallStyle.forOngoingCall(
                         person, mock(PendingIntent.class)))
                 .build();
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 8, "tag", mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
@@ -12976,7 +13103,7 @@
                 .build();
 
         // When: fix the notification with NotificationManagerService
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         // Then: the notification's flag FLAG_NO_DISMISS should not be set
         assertSame(0, n.flags & Notification.FLAG_NO_DISMISS);
@@ -12993,7 +13120,7 @@
                 .build();
 
         // When: fix the notification with NotificationManagerService
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         // Then: the notification's flag FLAG_NO_DISMISS should be set
         assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS);
@@ -13019,7 +13146,7 @@
                 .build();
 
         // When: fix the notification with NotificationManagerService
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         // Then: the notification's flag FLAG_NO_DISMISS should be set
         assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS);
@@ -13039,7 +13166,7 @@
                 .build();
 
         // When: fix the notification with NotificationManagerService
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         // Then: the notification's flag FLAG_NO_DISMISS should be set
         assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS);
@@ -13054,7 +13181,7 @@
                 .build();
 
         // When: fix the notification with NotificationManagerService
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         // Then: the notification's flag FLAG_NO_DISMISS should not be set
         assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS);
@@ -13070,7 +13197,7 @@
         n.flags |= Notification.FLAG_NO_DISMISS;
 
         // When: fix the notification with NotificationManagerService
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         // Then: the notification's flag FLAG_NO_DISMISS should be cleared
         assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS);
@@ -13086,7 +13213,7 @@
                 .build();
 
         // When: fix the notification with NotificationManagerService
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         // Then: the notification's flag FLAG_NO_DISMISS should not be set
         assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS);
@@ -13105,7 +13232,7 @@
         n.flags |= Notification.FLAG_NO_DISMISS;
 
         // When: fix the notification with NotificationManagerService
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         // Then: the notification's flag FLAG_NO_DISMISS should be cleared
         assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS);
@@ -13120,7 +13247,7 @@
                 .build();
 
         // When: fix the notification with NotificationManagerService
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         // Then: the notification's flag FLAG_NO_DISMISS should not be set
         assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS);
@@ -13137,7 +13264,7 @@
                 .build();
 
         // When: fix the notification with NotificationManagerService
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         // Then: the notification's flag FLAG_NO_DISMISS should be set
         assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS);
@@ -13147,7 +13274,7 @@
     public void fixExemptAppOpNotification_withFlag_shouldBeNonDismissible()
             throws Exception {
         final ApplicationInfo ai = new ApplicationInfo();
-        ai.packageName = PKG;
+        ai.packageName = mPkg;
         ai.uid = mUid;
         ai.flags |= ApplicationInfo.FLAG_SYSTEM;
 
@@ -13155,7 +13282,7 @@
                 .thenReturn(ai);
         when(mAppOpsManager.checkOpNoThrow(
                 AppOpsManager.OP_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS, mUid,
-                PKG)).thenReturn(AppOpsManager.MODE_ALLOWED);
+                mPkg)).thenReturn(AppOpsManager.MODE_ALLOWED);
         // Given: a notification has the flag FLAG_ONGOING_EVENT set
         setDpmAppOppsExemptFromDismissal(true);
         Notification n = new Notification.Builder(mContext, "test")
@@ -13163,7 +13290,7 @@
                 .build();
 
         // When: fix the notification with NotificationManagerService
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         // Then: the notification's flag FLAG_NO_DISMISS should be cleared
         assertEquals(0, n.flags & Notification.FLAG_NO_DISMISS);
@@ -13174,7 +13301,7 @@
             throws Exception {
         when(mAppOpsManager.checkOpNoThrow(
                 AppOpsManager.OP_SYSTEM_EXEMPT_FROM_DISMISSIBLE_NOTIFICATIONS, mUid,
-                PKG)).thenReturn(AppOpsManager.MODE_ALLOWED);
+                mPkg)).thenReturn(AppOpsManager.MODE_ALLOWED);
         // Given: a notification has the flag FLAG_ONGOING_EVENT set
         setDpmAppOppsExemptFromDismissal(false);
         Notification n = new Notification.Builder(mContext, "test")
@@ -13182,7 +13309,7 @@
                 .build();
 
         // When: fix the notification with NotificationManagerService
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         // Then: the notification's flag FLAG_NO_DISMISS should not be set
         assertSame(0, n.flags & Notification.FLAG_NO_DISMISS);
@@ -13194,10 +13321,10 @@
                 .thenReturn(true);
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= FLAG_USER_INITIATED_JOB;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelAllNotifications_IgnoreUserInitiatedJob",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
-        mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
+        mBinderService.cancelAllNotifications(mPkg, sbn.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
@@ -13211,10 +13338,10 @@
                 .thenReturn(false);
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= FLAG_USER_INITIATED_JOB;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelAllNotifications_UijFlag_NoUij_Allowed",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
-        mBinderService.cancelAllNotifications(PKG, sbn.getUserId());
+        mBinderService.cancelAllNotifications(mPkg, sbn.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
                 mBinderService.getActiveNotifications(sbn.getPackageName());
@@ -13227,7 +13354,7 @@
                 .thenReturn(true);
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= FLAG_USER_INITIATED_JOB;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCancelAllNotifications_IgnoreOtherPackages",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         mBinderService.cancelAllNotifications("other_pkg_name", sbn.getUserId());
@@ -13248,9 +13375,9 @@
         StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, null, mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         sbn.getNotification().flags |= FLAG_USER_INITIATED_JOB;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, null,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, null,
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
-        mInternalService.removeUserInitiatedJobFlagFromNotification(PKG, sbn.getId(),
+        mInternalService.removeUserInitiatedJobFlagFromNotification(mPkg, sbn.getId(),
                 sbn.getUserId());
         waitForIdle();
         StatusBarNotification[] notifs =
@@ -13262,12 +13389,12 @@
     public void testCancelAfterSecondEnqueueDoesNotSpecifyUserInitiatedJobFlag() throws Exception {
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT | FLAG_USER_INITIATED_JOB;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, sbn.getTag(),
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         sbn.getNotification().flags = Notification.FLAG_ONGOING_EVENT;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, sbn.getTag(),
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
-        mBinderService.cancelNotificationWithTag(PKG, PKG, sbn.getTag(), sbn.getId(),
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, sbn.getTag(), sbn.getId(),
                 sbn.getUserId());
         waitForIdle();
         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
@@ -13535,10 +13662,10 @@
 
     @Test
     public void testDeleteChannelGroupChecksForUijs() throws Exception {
-        when(mCompanionMgr.getAssociations(PKG, UserHandle.getUserId(mUid)))
+        when(mCompanionMgr.getAssociations(mPkg, UserHandle.getUserId(mUid)))
                 .thenReturn(singletonList(mock(AssociationInfo.class)));
         CountDownLatch latch = new CountDownLatch(2);
-        mService.createNotificationChannelGroup(PKG, mUid,
+        mService.createNotificationChannelGroup(mPkg, mUid,
                 new NotificationChannelGroup("group", "group"), true, false);
         new Thread(() -> {
             NotificationChannel notificationChannel = new NotificationChannel("id", "id",
@@ -13547,7 +13674,7 @@
             ParceledListSlice<NotificationChannel> pls =
                     new ParceledListSlice(ImmutableList.of(notificationChannel));
             try {
-                mBinderService.createNotificationChannelsForPackage(PKG, mUid, pls);
+                mBinderService.createNotificationChannelsForPackage(mPkg, mUid, pls);
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
@@ -13558,7 +13685,7 @@
                 synchronized (this) {
                     wait(5000);
                 }
-                mService.createNotificationChannelGroup(PKG, mUid,
+                mService.createNotificationChannelGroup(mPkg, mUid,
                         new NotificationChannelGroup("new", "new group"), true, false);
                 NotificationChannel notificationChannel =
                         new NotificationChannel("id", "id", NotificationManager.IMPORTANCE_HIGH);
@@ -13566,8 +13693,8 @@
                 ParceledListSlice<NotificationChannel> pls =
                         new ParceledListSlice(ImmutableList.of(notificationChannel));
                 try {
-                    mBinderService.createNotificationChannelsForPackage(PKG, mUid, pls);
-                    mBinderService.deleteNotificationChannelGroup(PKG, "group");
+                    mBinderService.createNotificationChannelsForPackage(mPkg, mUid, pls);
+                    mBinderService.deleteNotificationChannelGroup(mPkg, "group");
                 } catch (RemoteException e) {
                     throw new RuntimeException(e);
                 }
@@ -13589,14 +13716,14 @@
         Notification n = new Notification.Builder(mContext, "").build();
         n.flags |= FLAG_USER_INITIATED_JOB;
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 9, null, mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 9, null, mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
         mService.addEnqueuedNotification(r);
 
         mInternalService.removeUserInitiatedJobFlagFromNotification(
-                PKG, r.getSbn().getId(), r.getSbn().getUserId());
+                mPkg, r.getSbn().getId(), r.getSbn().getUserId());
 
         waitForIdle();
 
@@ -13610,14 +13737,14 @@
         Notification n = new Notification.Builder(mContext, "").build();
         n.flags |= FLAG_USER_INITIATED_JOB;
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 9, null, mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 9, null, mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
         mService.addNotification(r);
 
         mInternalService.removeUserInitiatedJobFlagFromNotification(
-                PKG, r.getSbn().getId(), r.getSbn().getUserId());
+                mPkg, r.getSbn().getId(), r.getSbn().getUserId());
 
         waitForIdle();
 
@@ -13632,7 +13759,7 @@
     public void testCannotRemoveUserInitiatedJobFlagWhenOverLimit_enqueued() {
         for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) {
             Notification n = new Notification.Builder(mContext, "").build();
-            StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, i, null, mUid, 0,
+            StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, i, null, mUid, 0,
                     n, UserHandle.getUserHandleForUid(mUid), null, 0);
             NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
             mService.addEnqueuedNotification(r);
@@ -13640,7 +13767,7 @@
         Notification n = new Notification.Builder(mContext, "").build();
         n.flags |= FLAG_USER_INITIATED_JOB;
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg,
                 NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS, null, mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
@@ -13648,7 +13775,7 @@
         mService.addEnqueuedNotification(r);
 
         mInternalService.removeUserInitiatedJobFlagFromNotification(
-                PKG, r.getSbn().getId(), r.getSbn().getUserId());
+                mPkg, r.getSbn().getId(), r.getSbn().getUserId());
 
         waitForIdle();
 
@@ -13662,7 +13789,7 @@
                 .thenReturn(true);
         for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) {
             Notification n = new Notification.Builder(mContext, "").build();
-            StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, i, null, mUid, 0,
+            StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, i, null, mUid, 0,
                     n, UserHandle.getUserHandleForUid(mUid), null, 0);
             NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
             mService.addNotification(r);
@@ -13670,7 +13797,7 @@
         Notification n = new Notification.Builder(mContext, "").build();
         n.flags |= FLAG_USER_INITIATED_JOB;
 
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg,
                 NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS, null, mUid, 0,
                 n, UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
@@ -13678,7 +13805,7 @@
         mService.addNotification(r);
 
         mInternalService.removeUserInitiatedJobFlagFromNotification(
-                PKG, r.getSbn().getId(), r.getSbn().getUserId());
+                mPkg, r.getSbn().getId(), r.getSbn().getUserId());
 
         waitForIdle();
 
@@ -13693,13 +13820,13 @@
         for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) {
             StatusBarNotification sbn = generateNotificationRecord(mTestNotificationChannel,
                     i, null, false).getSbn();
-            mBinderService.enqueueNotificationWithTag(PKG, PKG, "testCanPostUijWhenOverLimit",
+            mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testCanPostUijWhenOverLimit",
                     sbn.getId(), sbn.getNotification(), sbn.getUserId());
         }
 
         final StatusBarNotification sbn = generateNotificationRecord(null).getSbn();
         sbn.getNotification().flags |= FLAG_USER_INITIATED_JOB;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCanPostUijWhenOverLimit - uij over limit!",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
 
@@ -13719,7 +13846,7 @@
         for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_NOTIFICATIONS; i++) {
             StatusBarNotification sbn = generateNotificationRecord(mTestNotificationChannel,
                     i, null, false).getSbn();
-            mBinderService.enqueueNotificationWithTag(PKG, PKG, "testCannotPostNonUijWhenOverLimit",
+            mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "testCannotPostNonUijWhenOverLimit",
                     sbn.getId(), sbn.getNotification(), sbn.getUserId());
             waitForIdle();
         }
@@ -13727,13 +13854,13 @@
         final StatusBarNotification sbn = generateNotificationRecord(mTestNotificationChannel,
                 100, null, false).getSbn();
         sbn.getNotification().flags |= FLAG_USER_INITIATED_JOB;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCannotPostNonUijWhenOverLimit - uij over limit!",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
 
         final StatusBarNotification sbn2 = generateNotificationRecord(mTestNotificationChannel,
                 101, null, false).getSbn();
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCannotPostNonUijWhenOverLimit - non uij over limit!",
                 sbn2.getId(), sbn2.getNotification(), sbn2.getUserId());
 
@@ -13742,7 +13869,7 @@
         final StatusBarNotification sbn3 = generateNotificationRecord(mTestNotificationChannel,
                 101, null, false).getSbn();
         sbn3.getNotification().flags |= FLAG_USER_INITIATED_JOB;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg,
                 "testCannotPostNonUijWhenOverLimit - fake uij over limit!",
                 sbn3.getId(), sbn3.getNotification(), sbn3.getUserId());
 
@@ -13765,7 +13892,7 @@
                 .setFlag(FLAG_USER_INITIATED_JOB, true)
                 .build();
 
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
         assertFalse(n.isUserInitiatedJob());
     }
 
@@ -13773,11 +13900,11 @@
     public void enqueue_updatesEnqueueRate() throws Exception {
         Notification n = generateNotificationRecord(null).getNotification();
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, n, mUserId);
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 0, n, mUserId);
         // Don't waitForIdle() here. We want to verify the "intermediate" state.
 
-        verify(mUsageStats).registerEnqueuedByApp(eq(PKG));
-        verify(mUsageStats).registerEnqueuedByAppAndAccepted(eq(PKG));
+        verify(mUsageStats).registerEnqueuedByApp(eq(mPkg));
+        verify(mUsageStats).registerEnqueuedByAppAndAccepted(eq(mPkg));
         verify(mUsageStats, never()).registerPostedByApp(any());
 
         waitForIdle();
@@ -13787,26 +13914,26 @@
     public void enqueue_withPost_updatesEnqueueRateAndPost() throws Exception {
         Notification n = generateNotificationRecord(null).getNotification();
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, n, mUserId);
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 0, n, mUserId);
         waitForIdle();
 
-        verify(mUsageStats).registerEnqueuedByApp(eq(PKG));
-        verify(mUsageStats).registerEnqueuedByAppAndAccepted(eq(PKG));
+        verify(mUsageStats).registerEnqueuedByApp(eq(mPkg));
+        verify(mUsageStats).registerEnqueuedByAppAndAccepted(eq(mPkg));
         verify(mUsageStats).registerPostedByApp(any());
     }
 
     @Test
     public void enqueueNew_whenOverEnqueueRate_accepts() throws Exception {
         Notification n = generateNotificationRecord(null).getNotification();
-        when(mUsageStats.getAppEnqueueRate(eq(PKG)))
+        when(mUsageStats.getAppEnqueueRate(eq(mPkg)))
                 .thenReturn(DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE + 1f);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, n, mUserId);
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 0, n, mUserId);
         waitForIdle();
 
         assertThat(mService.mNotificationsByKey).hasSize(1);
-        verify(mUsageStats).registerEnqueuedByApp(eq(PKG));
-        verify(mUsageStats).registerEnqueuedByAppAndAccepted(eq(PKG));
+        verify(mUsageStats).registerEnqueuedByApp(eq(mPkg));
+        verify(mUsageStats).registerEnqueuedByAppAndAccepted(eq(mPkg));
         verify(mUsageStats).registerPostedByApp(any());
     }
 
@@ -13815,23 +13942,23 @@
         // Post the first version.
         Notification original = generateNotificationRecord(null).getNotification();
         original.when = 111;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, original, mUserId);
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 0, original, mUserId);
         waitForIdle();
         assertThat(mService.mNotificationList).hasSize(1);
         assertThat(mService.mNotificationList.get(0).getNotification().when).isEqualTo(111);
 
         reset(mUsageStats);
-        when(mUsageStats.getAppEnqueueRate(eq(PKG)))
+        when(mUsageStats.getAppEnqueueRate(eq(mPkg)))
                 .thenReturn(DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE - 1f);
 
         // Post the update.
         Notification update = generateNotificationRecord(null).getNotification();
         update.when = 222;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, update, mUserId);
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 0, update, mUserId);
         waitForIdle();
 
-        verify(mUsageStats).registerEnqueuedByApp(eq(PKG));
-        verify(mUsageStats).registerEnqueuedByAppAndAccepted(eq(PKG));
+        verify(mUsageStats).registerEnqueuedByApp(eq(mPkg));
+        verify(mUsageStats).registerEnqueuedByAppAndAccepted(eq(mPkg));
         verify(mUsageStats, never()).registerPostedByApp(any());
         verify(mUsageStats).registerUpdatedByApp(any(), any());
         assertThat(mService.mNotificationList).hasSize(1);
@@ -13843,22 +13970,22 @@
         // Post the first version.
         Notification original = generateNotificationRecord(null).getNotification();
         original.when = 111;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, original, mUserId);
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 0, original, mUserId);
         waitForIdle();
         assertThat(mService.mNotificationList).hasSize(1);
         assertThat(mService.mNotificationList.get(0).getNotification().when).isEqualTo(111);
 
         reset(mUsageStats);
-        when(mUsageStats.getAppEnqueueRate(eq(PKG)))
+        when(mUsageStats.getAppEnqueueRate(eq(mPkg)))
                 .thenReturn(DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE + 1f);
 
         // Post the update.
         Notification update = generateNotificationRecord(null).getNotification();
         update.when = 222;
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 0, update, mUserId);
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 0, update, mUserId);
         waitForIdle();
 
-        verify(mUsageStats).registerEnqueuedByApp(eq(PKG));
+        verify(mUsageStats).registerEnqueuedByApp(eq(mPkg));
         verify(mUsageStats, never()).registerEnqueuedByAppAndAccepted(any());
         verify(mUsageStats, never()).registerPostedByApp(any());
         verify(mUsageStats, never()).registerUpdatedByApp(any(), any());
@@ -13877,7 +14004,7 @@
                 .addAction(new Notification.Action.Builder(null, "action2", actionIntent2).build())
                 .build();
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 1,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 1,
                 parcelAndUnparcel(n, Notification.CREATOR), mUserId);
 
         verify(mAmi, times(3)).setPendingIntentAllowlistDuration(
@@ -13905,7 +14032,7 @@
                         .build())
                 .build();
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag", 1,
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag", 1,
                 parcelAndUnparcel(source, Notification.CREATOR), mUserId);
 
         verify(mAmi, times(4)).setPendingIntentAllowlistDuration(
@@ -14377,7 +14504,7 @@
         assertThat(mBinderService.getAutomaticZenRules()).isEmpty();
 
         // Create an implicit zen rule by calling setNotificationPolicy from an app.
-        mBinderService.setNotificationPolicy(PKG, new NotificationManager.Policy(0, 0, 0), false);
+        mBinderService.setNotificationPolicy(mPkg, new NotificationManager.Policy(0, 0, 0), false);
         assertThat(mBinderService.getAutomaticZenRules()).hasSize(1);
         Map.Entry<String, AutomaticZenRule> rule = getOnlyElement(
                 mBinderService.getAutomaticZenRules().entrySet());
@@ -14403,7 +14530,7 @@
         assertThat(mBinderService.getAutomaticZenRules()).isEmpty();
 
         // Create an implicit zen rule by calling setNotificationPolicy from an app.
-        mBinderService.setNotificationPolicy(PKG, new NotificationManager.Policy(0, 0, 0), false);
+        mBinderService.setNotificationPolicy(mPkg, new NotificationManager.Policy(0, 0, 0), false);
         assertThat(mBinderService.getAutomaticZenRules()).hasSize(1);
         Map.Entry<String, AutomaticZenRule> rule = getOnlyElement(
                 mBinderService.getAutomaticZenRules().entrySet());
@@ -14447,7 +14574,7 @@
 
         assertThat(n.flags & FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY).isGreaterThan(0);
 
-        mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
+        mService.fixNotification(n, mPkg, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE, true);
 
         assertThat(n.flags & FLAG_LIFETIME_EXTENDED_BY_DIRECT_REPLY).isEqualTo(0);
     }
@@ -14474,12 +14601,12 @@
         waitForIdle();
 
         // Notifications should not be active anymore.
-        StatusBarNotification[] notifications = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifications = mBinderService.getActiveNotifications(mPkg);
         assertThat(notifications).isEmpty();
         assertEquals(0, mService.getNotificationRecordCount());
         // Ensure cancel event is logged.
         verify(mAppOpsManager).noteOpNoThrow(
-                AppOpsManager.OP_RAPID_CLEAR_NOTIFICATIONS_BY_LISTENER, mUid, PKG, null, null);
+                AppOpsManager.OP_RAPID_CLEAR_NOTIFICATIONS_BY_LISTENER, mUid, mPkg, null, null);
     }
 
     @Test
@@ -14502,7 +14629,7 @@
         waitForIdle();
 
         // Notifications should not be active anymore.
-        StatusBarNotification[] notifications = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifications = mBinderService.getActiveNotifications(mPkg);
         assertThat(notifications).isEmpty();
         assertEquals(0, mService.getNotificationRecordCount());
         // Ensure cancel event is not logged.
@@ -14533,7 +14660,7 @@
         waitForIdle();
 
         // Notifications should not be active anymore.
-        StatusBarNotification[] notifications = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifications = mBinderService.getActiveNotifications(mPkg);
         assertThat(notifications).isEmpty();
         assertEquals(0, mService.getNotificationRecordCount());
         // Ensure cancel event is not logged due to flag being disabled.
@@ -14563,12 +14690,12 @@
         waitForIdle();
 
         // Notifications should not be active anymore.
-        StatusBarNotification[] notifications = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifications = mBinderService.getActiveNotifications(mPkg);
         assertThat(notifications).isEmpty();
         assertEquals(0, mService.getNotificationRecordCount());
         // Ensure cancel event is logged.
         verify(mAppOpsManager).noteOpNoThrow(
-                AppOpsManager.OP_RAPID_CLEAR_NOTIFICATIONS_BY_LISTENER, mUid, PKG, null, null);
+                AppOpsManager.OP_RAPID_CLEAR_NOTIFICATIONS_BY_LISTENER, mUid, mPkg, null, null);
     }
 
     @Test
@@ -14590,7 +14717,7 @@
         waitForIdle();
 
         // Notifications should not be active anymore.
-        StatusBarNotification[] notifications = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifications = mBinderService.getActiveNotifications(mPkg);
         assertThat(notifications).isEmpty();
         assertEquals(0, mService.getNotificationRecordCount());
         // Ensure cancel event is not logged.
@@ -14620,7 +14747,7 @@
         waitForIdle();
 
         // Notifications should not be active anymore.
-        StatusBarNotification[] notifications = mBinderService.getActiveNotifications(PKG);
+        StatusBarNotification[] notifications = mBinderService.getActiveNotifications(mPkg);
         assertThat(notifications).isEmpty();
         assertEquals(0, mService.getNotificationRecordCount());
         // Ensure cancel event is not logged due to flag being disabled.
@@ -14651,20 +14778,20 @@
         ICallNotificationEventCallback listener = mock(
                 ICallNotificationEventCallback.class);
         when(listener.asBinder()).thenReturn(mock(IBinder.class));
-        mBinderService.registerCallNotificationEventListener(PKG, UserHandle.CURRENT, listener);
+        mBinderService.registerCallNotificationEventListener(mPkg, UserHandle.CURRENT, listener);
         waitForIdle();
 
         final UserHandle userHandle = UserHandle.getUserHandleForUid(mUid);
-        final NotificationRecord r = createAndPostCallStyleNotification(PKG, userHandle,
+        final NotificationRecord r = createAndPostCallStyleNotification(mPkg, userHandle,
                 "testCallNotificationListener_NotifiedOnPostCallStyle");
 
-        verify(listener, times(1)).onCallNotificationPosted(PKG, userHandle);
+        verify(listener, times(1)).onCallNotificationPosted(mPkg, userHandle);
 
-        mBinderService.cancelNotificationWithTag(PKG, PKG, r.getSbn().getTag(), r.getSbn().getId(),
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(), r.getSbn().getId(),
                 r.getSbn().getUserId());
         waitForIdle();
 
-        verify(listener, times(1)).onCallNotificationRemoved(PKG, userHandle);
+        verify(listener, times(1)).onCallNotificationRemoved(mPkg, userHandle);
     }
 
     @Test
@@ -14673,7 +14800,7 @@
         ICallNotificationEventCallback listener = mock(
                 ICallNotificationEventCallback.class);
         when(listener.asBinder()).thenReturn(mock(IBinder.class));
-        mBinderService.registerCallNotificationEventListener(PKG,
+        mBinderService.registerCallNotificationEventListener(mPkg,
                 UserHandle.getUserHandleForUid(mUid), listener);
         waitForIdle();
 
@@ -14684,7 +14811,7 @@
 
         verify(listener, never()).onCallNotificationPosted(anyString(), any());
 
-        mBinderService.cancelNotificationWithTag(PKG, PKG, r.getSbn().getTag(), r.getSbn().getId(),
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(), r.getSbn().getId(),
                 r.getSbn().getUserId());
         waitForIdle();
 
@@ -14698,20 +14825,20 @@
         ICallNotificationEventCallback listener = mock(
                 ICallNotificationEventCallback.class);
         when(listener.asBinder()).thenReturn(mock(IBinder.class));
-        mBinderService.registerCallNotificationEventListener(PKG, UserHandle.ALL, listener);
+        mBinderService.registerCallNotificationEventListener(mPkg, UserHandle.ALL, listener);
         waitForIdle();
 
         final UserHandle otherUser = UserHandle.of(2);
-        final NotificationRecord r = createAndPostCallStyleNotification(PKG,
+        final NotificationRecord r = createAndPostCallStyleNotification(mPkg,
                 otherUser, "testCallNotificationListener_registerForUserAll_notifiedOnAnyUserId");
 
-        verify(listener, times(1)).onCallNotificationPosted(PKG, otherUser);
+        verify(listener, times(1)).onCallNotificationPosted(mPkg, otherUser);
 
-        mBinderService.cancelNotificationWithTag(PKG, PKG, r.getSbn().getTag(), r.getSbn().getId(),
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(), r.getSbn().getId(),
                 r.getSbn().getUserId());
         waitForIdle();
 
-        verify(listener, times(1)).onCallNotificationRemoved(PKG, otherUser);
+        verify(listener, times(1)).onCallNotificationRemoved(mPkg, otherUser);
     }
 
     @Test
@@ -14724,13 +14851,13 @@
         mBinderService.registerCallNotificationEventListener(packageName, UserHandle.ALL, listener);
         waitForIdle();
 
-        final NotificationRecord r = createAndPostCallStyleNotification(PKG,
+        final NotificationRecord r = createAndPostCallStyleNotification(mPkg,
                 UserHandle.of(mUserId),
                 "testCallNotificationListener_differentPackage_notNotified");
 
         verify(listener, never()).onCallNotificationPosted(anyString(), any());
 
-        mBinderService.cancelNotificationWithTag(PKG, PKG, r.getSbn().getTag(), r.getSbn().getId(),
+        mBinderService.cancelNotificationWithTag(mPkg, mPkg, r.getSbn().getTag(), r.getSbn().getId(),
                 r.getSbn().getUserId());
         waitForIdle();
 
@@ -14742,7 +14869,7 @@
     public void rankingTime_newNotification_noisy_matchesSbn() throws Exception {
         NotificationRecord nr = generateNotificationRecord(mTestNotificationChannel, mUserId);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag0",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag0",
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -14757,7 +14884,7 @@
         NotificationChannel low = new NotificationChannel("low", "low", IMPORTANCE_LOW);
         NotificationRecord nr = generateNotificationRecord(low, mUserId);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag0",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag0",
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
@@ -14772,14 +14899,14 @@
         NotificationChannel low = new NotificationChannel("low", "low", IMPORTANCE_LOW);
         NotificationRecord nr = generateNotificationRecord(low, mUserId);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag0",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag0",
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
         NotificationRecord posted = mService.mNotificationList.get(0);
         long originalPostTime = posted.getSbn().getPostTime();
         assertThat(posted.getRankingTimeMs()).isEqualTo(originalPostTime);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag0",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag0",
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
         assertThat(mService.mNotificationList.get(0).getRankingTimeMs())
@@ -14792,7 +14919,7 @@
         NotificationChannel low = new NotificationChannel("low", "low", IMPORTANCE_LOW);
         NotificationRecord nr = generateNotificationRecord(low, 0, mUserId);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag0",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag0",
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
         NotificationRecord posted = mService.mNotificationList.get(0);
@@ -14801,7 +14928,7 @@
 
         NotificationRecord nrUpdate = generateNotificationRecord(low, 0, mUserId, "bar");
         // no attention helper mocked behavior needed because this does not make noise
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag0",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag0",
                 nrUpdate.getSbn().getId(), nrUpdate.getSbn().getNotification(),
                 nrUpdate.getSbn().getUserId());
         waitForIdle();
@@ -14817,7 +14944,7 @@
         NotificationChannel low = new NotificationChannel("low", "low", IMPORTANCE_LOW);
         NotificationRecord nr = generateNotificationRecord(low, mUserId);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag0",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag0",
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
         NotificationRecord posted = mService.mNotificationList.get(0);
@@ -14832,7 +14959,7 @@
                 return 2; // beep
             }
         });
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, "tag0",
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag0",
                 nrUpdate.getSbn().getId(), nrUpdate.getSbn().getNotification(),
                 nrUpdate.getSbn().getUserId());
         waitForIdle();
@@ -14841,6 +14968,58 @@
         assertThat(posted.getRankingTimeMs()).isEqualTo(posted.getSbn().getPostTime());
     }
 
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_MEDIA)
+    public void testRestrictAudioAttributes_listenersGetCorrectAttributes() throws Exception {
+        NotificationChannel sound = new NotificationChannel("a", "a", IMPORTANCE_DEFAULT);
+        sound.setSound(Uri.EMPTY, new AudioAttributes.Builder().setUsage(USAGE_MEDIA).build());
+        mBinderService.createNotificationChannels(mPkg, new ParceledListSlice(
+                Arrays.asList(sound)));
+
+        Notification n = new Notification.Builder(mContext, "a")
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 9, null, mUid, 0,
+                n, UserHandle.getUserHandleForUid(mUid), null, 0);
+
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, sbn.getTag(),
+                sbn.getId(), sbn.getNotification(), sbn.getUserId());
+        waitForIdle();
+
+        ArgumentCaptor<NotificationRecord> captor =
+                ArgumentCaptor.forClass(NotificationRecord.class);
+        verify(mListeners, times(1)).prepareNotifyPostedLocked(
+                captor.capture(), any(), anyBoolean());
+
+        assertThat(captor.getValue().getChannel().getAudioAttributes().getUsage())
+                .isEqualTo(USAGE_NOTIFICATION);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ALL_NOTIFS_NEED_TTL)
+    public void testFixNotification_missingTtl() throws Exception {
+        Notification n = new Notification.Builder(mContext, mTestNotificationChannel.getId())
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .build();
+
+        mService.fixNotification(n, mPkg, "tag", 0, mUserId, mUid, NOT_FOREGROUND_SERVICE, true);
+
+        assertThat(n.getTimeoutAfter()).isEqualTo(NOTIFICATION_TTL);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ALL_NOTIFS_NEED_TTL)
+    public void testFixNotification_doesNotOverwriteTtl() throws Exception {
+        Notification n = new Notification.Builder(mContext, mTestNotificationChannel.getId())
+                .setSmallIcon(android.R.drawable.sym_def_app_icon)
+                .setTimeoutAfter(20)
+                .build();
+
+        mService.fixNotification(n, mPkg, "tag", 0, mUserId, mUid, NOT_FOREGROUND_SERVICE, true);
+
+        assertThat(n.getTimeoutAfter()).isEqualTo(20);
+    }
+
     private NotificationRecord createAndPostCallStyleNotification(String packageName,
             UserHandle userHandle, String testName) throws Exception {
         Person person = new Person.Builder().setName("caller").build();
@@ -14865,16 +15044,16 @@
 
     private NotificationRecord createAndPostNotification(Notification.Builder nb, String testName)
             throws RemoteException {
-        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1, testName, mUid, 0,
+        StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, 1, testName, mUid, 0,
                 nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
         NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
 
-        mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
+        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, sbn.getTag(),
                 nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
         waitForIdle();
 
         return mService.findNotificationLocked(
-                PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
+                mPkg, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
     }
 
     private static <T extends Parcelable> T parcelAndUnparcel(T source,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationTimeComparatorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationTimeComparatorTest.java
new file mode 100644
index 0000000..c39961e
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationTimeComparatorTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.notification;
+
+import static android.app.Notification.CATEGORY_MESSAGE;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.PendingIntent;
+import android.app.Person;
+import android.graphics.Color;
+import android.media.session.MediaSession;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.service.notification.StatusBarNotification;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+import com.android.server.UiServiceTestCase;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NotificationTimeComparatorTest extends UiServiceTestCase {
+
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
+
+    @Test
+    @EnableFlags({android.app.Flags.FLAG_SORT_SECTION_BY_TIME})
+    public void testCompare() {
+        NotificationRecord one = mock(NotificationRecord.class);
+        when(one.getRankingTimeMs()).thenReturn(1L);
+
+        NotificationRecord five = mock(NotificationRecord.class);
+        when(five.getRankingTimeMs()).thenReturn(5L);
+
+        NotificationRecord ten = mock(NotificationRecord.class);
+        when(ten.getRankingTimeMs()).thenReturn(10L);
+
+        List<NotificationRecord> expected = new ArrayList<>();
+        expected.add(ten);
+        expected.add(five);
+        expected.add(one);
+
+        List<NotificationRecord> actual = new ArrayList<>();
+        actual.addAll(expected);
+        Collections.shuffle(actual);
+
+        Collections.sort(actual, new NotificationTimeComparator());
+
+        assertThat(actual).containsExactlyElementsIn(expected).inOrder();
+    }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index cee6cdb..aeeca2ae 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -173,11 +173,8 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class PreferencesHelperTest extends UiServiceTestCase {
-    private static final int UID_N_MR1 = 0;
     private static final int UID_HEADLESS = 1000000;
     private static final UserHandle USER = UserHandle.of(0);
-    private static final int UID_O = 1111;
-    private static final int UID_P = 2222;
     private static final String SYSTEM_PKG = "android";
     private static final int SYSTEM_UID = 1000;
     private static final UserHandle USER2 = UserHandle.of(10);
@@ -1102,18 +1099,15 @@
                 + "<package name=\"com.example.o\" show_badge=\"true\" "
                 + "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" "
                 + "sent_valid_msg=\"false\" user_demote_msg_app=\"false\" sent_valid_bubble"
-                + "=\"false\" uid=\"1111\">\n"
+                + "=\"false\" uid=\"10002\">\n"
                 + "<channel id=\"id\" name=\"name\" importance=\"2\" "
                 + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
                 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" orig_imp=\"2\" />\n"
                 + "</package>\n"
-                + "<package name=\"com.example.p\" show_badge=\"true\" "
-                + "app_user_locked_fields=\"0\" sent_invalid_msg=\"true\" sent_valid_msg=\"true\""
-                + " user_demote_msg_app=\"true\" sent_valid_bubble=\"false\" uid=\"2222\" />\n"
                 + "<package name=\"com.example.n_mr1\" show_badge=\"true\" "
                 + "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" "
                 + "sent_valid_msg=\"false\" user_demote_msg_app=\"false\" sent_valid_bubble"
-                + "=\"false\" uid=\"0\">\n"
+                + "=\"false\" uid=\"10001\">\n"
                 + "<channelGroup id=\"1\" name=\"bye\" blocked=\"false\" locked=\"0\" />\n"
                 + "<channelGroup id=\"2\" name=\"hello\" blocked=\"false\" locked=\"0\" />\n"
                 + "<channel id=\"id1\" name=\"name1\" importance=\"4\" show_badge=\"true\" "
@@ -1129,6 +1123,9 @@
                 + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
                 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
                 + "</package>\n"
+                + "<package name=\"com.example.p\" show_badge=\"true\" "
+                + "app_user_locked_fields=\"0\" sent_invalid_msg=\"true\" sent_valid_msg=\"true\""
+                + " user_demote_msg_app=\"true\" sent_valid_bubble=\"false\" uid=\"10003\" />\n"
                 + "</ranking>";
         assertThat(baos.toString()).contains(expected);
     }
@@ -1194,10 +1191,6 @@
                 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" orig_imp=\"2\" />\n"
                 + "</package>\n"
                 // Importance default because on in permission helper
-                + "<package name=\"com.example.p\" importance=\"3\" show_badge=\"true\" "
-                + "app_user_locked_fields=\"0\" sent_invalid_msg=\"true\" sent_valid_msg=\"true\""
-                + " user_demote_msg_app=\"true\" sent_valid_bubble=\"false\" />\n"
-                // Importance default because on in permission helper
                 + "<package name=\"com.example.n_mr1\" importance=\"3\" show_badge=\"true\" "
                 + "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" "
                 + "sent_valid_msg=\"false\" user_demote_msg_app=\"false\" sent_valid_bubble"
@@ -1217,6 +1210,10 @@
                 + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
                 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
                 + "</package>\n"
+                // Importance default because on in permission helper
+                + "<package name=\"com.example.p\" importance=\"3\" show_badge=\"true\" "
+                + "app_user_locked_fields=\"0\" sent_invalid_msg=\"true\" sent_valid_msg=\"true\""
+                + " user_demote_msg_app=\"true\" sent_valid_bubble=\"false\" />\n"
                 // Packages that exist solely in permissionhelper
                 + "<package name=\"first\" importance=\"3\" />\n"
                 + "<package name=\"third\" importance=\"0\" />\n"
@@ -1280,12 +1277,8 @@
                 + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
                 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" orig_imp=\"2\" />\n"
                 + "</package>\n"
-                // Importance default because on in permission helper
-                + "<package name=\"com.example.p\" importance=\"3\" show_badge=\"true\" "
-                + "app_user_locked_fields=\"0\" sent_invalid_msg=\"true\" sent_valid_msg=\"true\""
-                + " user_demote_msg_app=\"true\" sent_valid_bubble=\"false\" />\n"
-                // Importance missing because missing from permission helper
-                + "<package name=\"com.example.n_mr1\" show_badge=\"true\" "
+                // Importance 0 because missing from permission helper
+                + "<package name=\"com.example.n_mr1\" importance=\"0\" show_badge=\"true\" "
                 + "app_user_locked_fields=\"0\" sent_invalid_msg=\"false\" "
                 + "sent_valid_msg=\"false\" user_demote_msg_app=\"false\" sent_valid_bubble"
                 + "=\"false\">\n"
@@ -1304,6 +1297,10 @@
                 + "sound=\"content://settings/system/notification_sound\" usage=\"5\" "
                 + "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
                 + "</package>\n"
+                // Importance default because on in permission helper
+                + "<package name=\"com.example.p\" importance=\"3\" show_badge=\"true\" "
+                + "app_user_locked_fields=\"0\" sent_invalid_msg=\"true\" sent_valid_msg=\"true\""
+                + " user_demote_msg_app=\"true\" sent_valid_bubble=\"false\" />\n"
                 + "</ranking>";
         assertThat(baos.toString()).contains(expected);
     }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
index d2c6028..ad420f6 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -18,6 +18,8 @@
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 import static android.app.NotificationManager.IMPORTANCE_LOW;
 
+import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT;
+import static com.google.common.truth.Truth.assertThat;
 import static junit.framework.TestCase.assertEquals;
 
 import static org.junit.Assert.assertTrue;
@@ -27,6 +29,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.app.Flags;
 import android.app.Notification;
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
@@ -42,6 +45,9 @@
 import android.os.Build;
 import android.os.UserHandle;
 import android.os.Vibrator;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.service.notification.StatusBarNotification;
 import android.testing.TestableContentResolver;
 
@@ -52,24 +58,23 @@
 import com.android.server.UiServiceTestCase;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class RankingHelperTest extends UiServiceTestCase {
-    private static final String PKG = "com.android.server.notification";
-    private static final int UID = 0;
-    private static final UserHandle USER = UserHandle.of(0);
-    private static final String UPDATED_PKG = "updatedPkg";
+    private static final String UPDATED_PKG = "updatedmPkg";
     private static final int UID2 = 1111;
     private static final String SYSTEM_PKG = "android";
     private static final int SYSTEM_UID= 1000;
-    private static final UserHandle USER2 = UserHandle.of(10);
     private static final String TEST_CHANNEL_ID = "test_channel_id";
     private static final String TEST_AUTHORITY = "test";
     private static final Uri SOUND_URI =
@@ -98,28 +103,32 @@
     private NotificationRecord mRecordNoGroup;
     private NotificationRecord mRecordNoGroup2;
     private NotificationRecord mRecordNoGroupSortA;
+    private NotificationRecord mRecentlyIntrusive;
+    private NotificationRecord mNewest;
     private RankingHelper mHelper;
-    private AudioAttributes mAudioAttributes;
+
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(DEVICE_DEFAULT);
 
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        UserHandle user = UserHandle.ALL;
+        UserHandle mUser = UserHandle.ALL;
 
         final ApplicationInfo legacy = new ApplicationInfo();
         legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
         final ApplicationInfo upgrade = new ApplicationInfo();
         upgrade.targetSdkVersion = Build.VERSION_CODES.O;
-        when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(legacy);
+        when(mPm.getApplicationInfoAsUser(eq(mPkg), anyInt(), anyInt())).thenReturn(legacy);
         when(mPm.getApplicationInfoAsUser(eq(UPDATED_PKG), anyInt(), anyInt())).thenReturn(upgrade);
         when(mPm.getApplicationInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(upgrade);
-        when(mPm.getPackageUidAsUser(eq(PKG), anyInt())).thenReturn(UID);
+        when(mPm.getPackageUidAsUser(eq(mPkg), anyInt())).thenReturn(mUid);
         when(mPm.getPackageUidAsUser(eq(UPDATED_PKG), anyInt())).thenReturn(UID2);
         when(mPm.getPackageUidAsUser(eq(SYSTEM_PKG), anyInt())).thenReturn(SYSTEM_UID);
         PackageInfo info = mock(PackageInfo.class);
         info.signatures = new Signature[] {mock(Signature.class)};
         when(mPm.getPackageInfoAsUser(eq(SYSTEM_PKG), anyInt(), anyInt())).thenReturn(info);
-        when(mPm.getPackageInfoAsUser(eq(PKG), anyInt(), anyInt()))
+        when(mPm.getPackageInfoAsUser(eq(mPkg), anyInt(), anyInt()))
                 .thenReturn(mock(PackageInfo.class));
         when(mContext.getResources()).thenReturn(
                 InstrumentationRegistry.getContext().getResources());
@@ -155,7 +164,7 @@
                 .setWhen(1205)
                 .build();
         mRecordGroupGSortA = new NotificationRecord(mContext, new StatusBarNotification(
-                PKG, PKG, 1, null, 0, 0, mNotiGroupGSortA, user,
+                mPkg, mPkg, 1, null, 0, 0, mNotiGroupGSortA, mUser,
                 null, System.currentTimeMillis()), getLowChannel());
 
         mNotiGroupGSortB = new Notification.Builder(mContext, TEST_CHANNEL_ID)
@@ -165,7 +174,7 @@
                 .setWhen(1200)
                 .build();
         mRecordGroupGSortB = new NotificationRecord(mContext, new StatusBarNotification(
-                PKG, PKG, 1, null, 0, 0, mNotiGroupGSortB, user,
+                mPkg, mPkg, 1, null, 0, 0, mNotiGroupGSortB, mUser,
                 null, System.currentTimeMillis()), getLowChannel());
 
         mNotiNoGroup = new Notification.Builder(mContext, TEST_CHANNEL_ID)
@@ -173,7 +182,7 @@
                 .setWhen(1201)
                 .build();
         mRecordNoGroup = new NotificationRecord(mContext, new StatusBarNotification(
-                PKG, PKG, 1, null, 0, 0, mNotiNoGroup, user,
+                mPkg, mPkg, 1, null, 0, 0, mNotiNoGroup, mUser,
                 null, System.currentTimeMillis()), getLowChannel());
 
         mNotiNoGroup2 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
@@ -181,7 +190,7 @@
                 .setWhen(1202)
                 .build();
         mRecordNoGroup2 = new NotificationRecord(mContext, new StatusBarNotification(
-                PKG, PKG, 1, null, 0, 0, mNotiNoGroup2, user,
+                mPkg, mPkg, 1, null, 0, 0, mNotiNoGroup2, mUser,
                 null, System.currentTimeMillis()), getLowChannel());
 
         mNotiNoGroupSortA = new Notification.Builder(mContext, TEST_CHANNEL_ID)
@@ -190,14 +199,20 @@
                 .setSortKey("A")
                 .build();
         mRecordNoGroupSortA = new NotificationRecord(mContext, new StatusBarNotification(
-                PKG, PKG, 1, null, 0, 0, mNotiNoGroupSortA, user,
+                mPkg, mPkg, 1, null, 0, 0, mNotiNoGroupSortA, mUser,
                 null, System.currentTimeMillis()), getLowChannel());
 
-        mAudioAttributes = new AudioAttributes.Builder()
-                .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
-                .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
-                .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
+        Notification n = new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                .setContentTitle("D")
                 .build();
+        mRecentlyIntrusive = new NotificationRecord(mContext, new StatusBarNotification(
+                mPkg, mPkg, 1, null, 0, 0, n, mUser,
+                null, 100), getDefaultChannel());
+        mRecentlyIntrusive.setRecentlyIntrusive(true);
+
+        mNewest = new NotificationRecord(mContext, new StatusBarNotification(
+                mPkg, mPkg, 2, null, 0, 0, n, mUser,
+                null, 10000), getDefaultChannel());
     }
 
     private NotificationChannel getLowChannel() {
@@ -303,13 +318,13 @@
                 .setGroupSummary(true)
                 .build();
         NotificationRecord lowSummary = new NotificationRecord(mContext, new StatusBarNotification(
-                PKG, PKG, 1, "summary", 0, 0, lowSummaryN, USER,
+                mPkg, mPkg, 1, "summary", 0, 0, lowSummaryN, mUser,
                 null, System.currentTimeMillis()), getLowChannel());
         notificationList.add(lowSummary);
 
         Notification lowN = new Notification.Builder(mContext, "").build();
         NotificationRecord low = new NotificationRecord(mContext, new StatusBarNotification(
-                PKG, PKG, 1, "low", 0, 0, lowN, USER,
+                mPkg, mPkg, 1, "low", 0, 0, lowN, mUser,
                 null, System.currentTimeMillis()), getLowChannel());
         low.setContactAffinity(0.5f);
         notificationList.add(low);
@@ -319,7 +334,7 @@
                 .setGroupSummary(false)
                 .build();
         NotificationRecord highChild = new NotificationRecord(mContext, new StatusBarNotification(
-                PKG, PKG, 1, "child", 0, 0, highChildN, USER,
+                mPkg, mPkg, 1, "child", 0, 0, highChildN, mUser,
                 null, System.currentTimeMillis()), getDefaultChannel());
         notificationList.add(highChild);
 
@@ -329,4 +344,187 @@
         assertEquals(highChild, notificationList.get(1));
         assertEquals(low, notificationList.get(2));
     }
+
+    @Test
+    @DisableFlags({android.app.Flags.FLAG_SORT_SECTION_BY_TIME})
+    public void testSortByIntrusivenessNotRecency() {
+        ArrayList<NotificationRecord> expected = new ArrayList<>();
+        expected.add(mRecentlyIntrusive);
+        expected.add(mNewest);
+
+        ArrayList<NotificationRecord> actual = new ArrayList<>();
+        actual.addAll(expected);
+        Collections.shuffle(actual);
+
+        mHelper.sort(actual);
+        assertThat(actual).containsExactlyElementsIn(expected).inOrder();
+    }
+
+    @Test
+    @EnableFlags({android.app.Flags.FLAG_SORT_SECTION_BY_TIME})
+    public void testSortByRecencyNotIntrusiveness() {
+        ArrayList<NotificationRecord> expected = new ArrayList<>();
+        expected.add(mNewest);
+        expected.add(mRecentlyIntrusive);
+
+        ArrayList<NotificationRecord> actual = new ArrayList<>();
+        actual.addAll(expected);
+        Collections.shuffle(actual);
+
+        mHelper.sort(actual);
+        assertThat(actual).containsExactlyElementsIn(expected).inOrder();
+    }
+
+    @Test
+    @EnableFlags({android.app.Flags.FLAG_SORT_SECTION_BY_TIME, Flags.FLAG_UPDATE_RANKING_TIME})
+    public void testSort_oldWhenChildren_unspecifiedSummary() {
+        NotificationRecord child1 = new NotificationRecord(mContext,
+                new StatusBarNotification(
+                    mPkg, mPkg, 1, null, 0, 0,
+                        new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                            .setGroup("G")
+                            .setWhen(1200)
+                            .build(),
+                        mUser, null, System.currentTimeMillis()), getLowChannel());
+        NotificationRecord child2 = new NotificationRecord(mContext,
+                new StatusBarNotification(
+                        mPkg, mPkg, 2, null, 0, 0,
+                        new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                                .setGroup("G")
+                                .setWhen(1300)
+                                .build(),
+                        mUser, null, System.currentTimeMillis()), getLowChannel());
+        NotificationRecord summary = new NotificationRecord(mContext,
+                new StatusBarNotification(
+                        mPkg, mPkg, 3, null, 0, 0,
+                        new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                                .setGroup("G")
+                                .setGroupSummary(true)
+                                .build(),
+                        mUser, null, System.currentTimeMillis()), getLowChannel());
+
+        // in time slightly before the children, but much earlier than the summary.
+        // will only be sorted first if the summary is not the group proxy for group G.
+        NotificationRecord unrelated = new NotificationRecord(mContext,
+                new StatusBarNotification(
+                        mPkg, mPkg, 11, null, 0, 0,
+                        new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                                .setWhen(1500)
+                                .build(),
+                        mUser, null, System.currentTimeMillis()), getLowChannel());
+
+        ArrayList<NotificationRecord> expected = new ArrayList<>();
+        expected.add(unrelated);
+        expected.add(summary);
+        expected.add(child2);
+        expected.add(child1);
+
+        ArrayList<NotificationRecord> actual = new ArrayList<>();
+        actual.addAll(expected);
+        Collections.shuffle(actual);
+
+        mHelper.sort(actual);
+        assertThat(actual).containsExactlyElementsIn(expected).inOrder();
+    }
+
+    @Test
+    @EnableFlags({android.app.Flags.FLAG_SORT_SECTION_BY_TIME, Flags.FLAG_UPDATE_RANKING_TIME})
+    public void testSort_oldChildren_unspecifiedSummary() {
+        NotificationRecord child1 = new NotificationRecord(mContext,
+                new StatusBarNotification(
+                        mPkg, mPkg, 1, null, 0, 0,
+                        new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                                .setGroup("G")
+                                .build(),
+                        mUser, null, 1200), getLowChannel());
+        NotificationRecord child2 = new NotificationRecord(mContext,
+                new StatusBarNotification(
+                        mPkg, mPkg, 2, null, 0, 0,
+                        new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                                .setGroup("G")
+                                .build(),
+                        mUser, null, 1300), getLowChannel());
+        NotificationRecord summary = new NotificationRecord(mContext,
+                new StatusBarNotification(
+                        mPkg, mPkg, 3, null, 0, 0,
+                        new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                                .setGroup("G")
+                                .setGroupSummary(true)
+                                .build(),
+                        mUser, null, System.currentTimeMillis()), getLowChannel());
+
+        // in time slightly before the children, but much earlier than the summary.
+        // will only be sorted first if the summary is not the group proxy for group G.
+        NotificationRecord unrelated = new NotificationRecord(mContext,
+                new StatusBarNotification(
+                        mPkg, mPkg, 11, null, 0, 0,
+                        new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                                .setWhen(1500)
+                                .build(),
+                        mUser, null, System.currentTimeMillis()), getLowChannel());
+
+        ArrayList<NotificationRecord> expected = new ArrayList<>();
+        expected.add(unrelated);
+        expected.add(summary);
+        expected.add(child2);
+        expected.add(child1);
+
+        ArrayList<NotificationRecord> actual = new ArrayList<>();
+        actual.addAll(expected);
+        Collections.shuffle(actual);
+
+        mHelper.sort(actual);
+        assertThat(actual).containsExactlyElementsIn(expected).inOrder();
+    }
+
+    @Test
+    @EnableFlags({android.app.Flags.FLAG_SORT_SECTION_BY_TIME, Flags.FLAG_UPDATE_RANKING_TIME})
+    public void testSort_oldChildren_oldSummary() {
+        NotificationRecord child1 = new NotificationRecord(mContext,
+                new StatusBarNotification(
+                        mPkg, mPkg, 1, null, 0, 0,
+                        new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                                .setGroup("G")
+                                .build(),
+                        mUser, null, 1200), getLowChannel());
+        NotificationRecord child2 = new NotificationRecord(mContext,
+                new StatusBarNotification(
+                        mPkg, mPkg, 2, null, 0, 0,
+                        new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                                .setGroup("G")
+                                .build(),
+                        mUser, null, 1300), getLowChannel());
+        NotificationRecord summary = new NotificationRecord(mContext,
+                new StatusBarNotification(
+                        mPkg, mPkg, 3, null, 0, 0,
+                        new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                                .setGroup("G")
+                                .setGroupSummary(true)
+                                .setWhen(1600)
+                                .build(),
+                        mUser, null, System.currentTimeMillis()), getLowChannel());
+
+        // in time slightly before the children, but much earlier than the summary.
+        // will only be sorted first if the summary is not the group proxy for group G.
+        NotificationRecord unrelated = new NotificationRecord(mContext,
+                new StatusBarNotification(
+                        mPkg, mPkg, 11, null, 0, 0,
+                        new Notification.Builder(mContext, TEST_CHANNEL_ID)
+                                .setWhen(1500)
+                                .build(),
+                        mUser, null, System.currentTimeMillis()), getLowChannel());
+
+        ArrayList<NotificationRecord> expected = new ArrayList<>();
+        expected.add(summary);
+        expected.add(child2);
+        expected.add(child1);
+        expected.add(unrelated);
+
+        ArrayList<NotificationRecord> actual = new ArrayList<>();
+        actual.addAll(expected);
+        Collections.shuffle(actual);
+
+        mHelper.sort(actual);
+        assertThat(actual).containsExactlyElementsIn(expected).inOrder();
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 173a1b6..1355092 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -1634,6 +1634,28 @@
         assertThat(transition.isInTransientHide(top.getTask())).isTrue();
     }
 
+    /**
+     * Tests ATMS#startActivityWithScreenshot should collect display content for creating snapshot.
+     */
+    @Test
+    public void testActivityStartWithScreenshot() {
+        final ActivityStarter starter = prepareStarter(0 /* flags */);
+        starter.setFreezeScreen(true);
+
+        registerTestTransitionPlayer();
+
+        final Intent intent = new Intent();
+        intent.setComponent(ActivityBuilder.getDefaultComponent());
+        starter.setReason("testActivityStartWithScreenshot")
+                .setIntent(intent)
+                .execute();
+
+        final TransitionController controller = mRootWindowContainer.mTransitionController;
+        final Transition transition = controller.getCollectingTransition();
+        final Transition.ChangeInfo targetChangeInfo = transition.mChanges.get(mDisplayContent);
+        assertThat(targetChangeInfo).isNotNull();
+    }
+
     @Test
     public void testActivityStart_expectAddedToRecentTask() {
         RecentTasks recentTasks = mock(RecentTasks.class);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index ed99108..400f9bb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -38,18 +38,22 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.never;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.ActivityManager;
+import android.app.ActivityManager.TaskDescription;
 import android.app.IApplicationThread;
 import android.app.PictureInPictureParams;
 import android.app.servertransaction.ClientTransactionItem;
@@ -62,6 +66,7 @@
 import android.os.LocaleList;
 import android.os.PowerManagerInternal;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.platform.test.annotations.Presubmit;
 import android.view.Display;
 import android.view.DisplayInfo;
@@ -1099,4 +1104,61 @@
 
         verify(mClientLifecycleManager).onLayoutContinued();
     }
+
+    @Test
+    public void testGetTaskDescriptionIcon_matchingUid() {
+        // Ensure that we do not hold MANAGE_ACTIVITY_TASKS
+        doThrow(new SecurityException()).when(mAtm).enforceActivityTaskPermission(any());
+
+        final String filePath = "abc/def";
+        // Create an activity with a task description at the test icon filepath
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setUid(android.os.Process.myUid())
+                .setCreateTask(true)
+                .build();
+        final TaskDescription td = new TaskDescription.Builder().build();
+        td.setIconFilename(filePath);
+        activity.setTaskDescription(td);
+
+        // Verify this calls and does not throw a security exception
+        try {
+            mAtm.getTaskDescriptionIcon(filePath, activity.mUserId);
+        } catch (SecurityException e) {
+            fail("Unexpected security exception: " + e);
+        } catch (IllegalArgumentException e) {
+            // Ok, the file doesn't actually exist
+        }
+    }
+
+    @Test
+    public void testGetTaskDescriptionIcon_noMatchingActivity_expectException() {
+        // Ensure that we do not hold MANAGE_ACTIVITY_TASKS
+        doThrow(new SecurityException()).when(mAtm).enforceActivityTaskPermission(any());
+
+        final String filePath = "abc/def";
+
+        // Verify this throws a security exception due to no matching activity
+        assertThrows(SecurityException.class,
+                () -> mAtm.getTaskDescriptionIcon(filePath, UserHandle.myUserId()));
+    }
+
+    @Test
+    public void testGetTaskDescriptionIcon_noMatchingUid_expectException() {
+        // Ensure that we do not hold MANAGE_ACTIVITY_TASKS
+        doThrow(new SecurityException()).when(mAtm).enforceActivityTaskPermission(any());
+
+        final String filePath = "abc/def";
+        // Create an activity with a task description at the test icon filepath
+        final ActivityRecord activity = new ActivityBuilder(mAtm)
+                .setCreateTask(true)
+                .setUid(101010)
+                .build();
+        final TaskDescription td = new TaskDescription.Builder().build();
+        td.setIconFilename(filePath);
+        activity.setTaskDescription(td);
+
+        // Verify this throws a security exception due to no matching UID
+        assertThrows(SecurityException.class,
+                () -> mAtm.getTaskDescriptionIcon(filePath, activity.mUserId));
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
index 21251c3..a911131 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackNavigationControllerTests.java
@@ -94,6 +94,7 @@
     private BackNavigationController mBackNavigationController;
     private WindowManagerInternal mWindowManagerInternal;
     private BackAnimationAdapter mBackAnimationAdapter;
+    private BackNavigationController.NavigationMonitor mNavigationMonitor;
     private Task mRootHomeTask;
 
     @Before
@@ -105,6 +106,7 @@
         mWindowManagerInternal = mock(WindowManagerInternal.class);
         LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal);
         mBackAnimationAdapter = mock(BackAnimationAdapter.class);
+        mNavigationMonitor = mock(BackNavigationController.NavigationMonitor.class);
         mRootHomeTask = initHomeActivity();
     }
 
@@ -813,6 +815,7 @@
                 animationHandler.prepareAnimation(
                         BackNavigationInfo.TYPE_RETURN_TO_HOME,
                         mBackAnimationAdapter,
+                        mNavigationMonitor,
                         task,
                         mRootHomeTask,
                         bottomActivity,
@@ -832,6 +835,7 @@
                 animationHandler.prepareAnimation(
                         BackNavigationInfo.TYPE_CROSS_ACTIVITY,
                         mBackAnimationAdapter,
+                        mNavigationMonitor,
                         task,
                         task,
                         topActivity,
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentDeferredUpdateTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentDeferredUpdateTests.java
index b11f9b2..073b551 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentDeferredUpdateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentDeferredUpdateTests.java
@@ -31,6 +31,7 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.when;
 
+import android.os.Message;
 import android.platform.test.annotations.Presubmit;
 import android.view.DisplayInfo;
 
@@ -60,6 +61,8 @@
     private int mColorMode;
     private int mLogicalDensityDpi;
 
+    private final Message mScreenUnblocker = mock(Message.class);
+
     @Override
     protected void onBeforeSystemServicesCreated() {
         // Set other flags to their default values
@@ -73,12 +76,11 @@
         doReturn(true).when(mDisplayContent).getLastHasContent();
         mockTransitionsController(/* enabled= */ true);
         mockRemoteDisplayChangeController();
+        performInitialDisplayUpdate();
     }
 
     @Test
     public void testUpdate_deferrableFieldChangedTransitionStarted_deferrableFieldUpdated() {
-        performInitialDisplayUpdate();
-
         mUniqueId = "old";
         Runnable onUpdated = mock(Runnable.class);
         mDisplayContent.requestDisplayUpdate(onUpdated);
@@ -107,8 +109,6 @@
 
     @Test
     public void testUpdate_nonDeferrableUpdateAndTransitionDeferred_nonDeferrableFieldUpdated() {
-        performInitialDisplayUpdate();
-
         // Update only color mode (non-deferrable field) and keep the same unique id
         mUniqueId = "initial_unique_id";
         mColorMode = 123;
@@ -121,8 +121,6 @@
 
     @Test
     public void testUpdate_nonDeferrableUpdateTwiceAndTransitionDeferred_fieldHasLatestValue() {
-        performInitialDisplayUpdate();
-
         // Update only color mode (non-deferrable field) and keep the same unique id
         mUniqueId = "initial_unique_id";
         mColorMode = 123;
@@ -163,7 +161,6 @@
 
     @Test
     public void testUpdate_deferrableFieldUpdatedTransitionPending_fieldNotUpdated() {
-        performInitialDisplayUpdate();
         mUniqueId = "old";
         Runnable onUpdated = mock(Runnable.class);
         mDisplayContent.requestDisplayUpdate(onUpdated);
@@ -181,7 +178,6 @@
 
     @Test
     public void testTwoDisplayUpdates_transitionStarted_displayUpdated() {
-        performInitialDisplayUpdate();
         mUniqueId = "old";
         Runnable onUpdated = mock(Runnable.class);
         mDisplayContent.requestDisplayUpdate(onUpdated);
@@ -212,6 +208,51 @@
         assertThat(mDisplayContent.getDisplayInfo().uniqueId).isEqualTo("new2");
     }
 
+    @Test
+    public void testWaitForTransition_displaySwitching_waitsForTransitionToBeStarted() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_WAIT_FOR_TRANSITION_ON_DISPLAY_SWITCH);
+        mDisplayContent.mDisplayUpdater.onDisplaySwitching(/* switching= */ true);
+        boolean willWait = mDisplayContent.mDisplayUpdater.waitForTransition(mScreenUnblocker);
+        assertThat(willWait).isTrue();
+        mUniqueId = "new";
+        mDisplayContent.requestDisplayUpdate(mock(Runnable.class));
+        when(mDisplayContent.mTransitionController.inTransition()).thenReturn(true);
+        captureStartTransitionCollection().getValue().onCollectStarted(/* deferred= */ true);
+
+        // Verify that screen is not unblocked yet as the start transaction hasn't been presented
+        verify(mScreenUnblocker, never()).sendToTarget();
+
+        when(mDisplayContent.mTransitionController.inTransition()).thenReturn(false);
+        final Transition transition = captureRequestedTransition().getValue();
+        makeTransitionTransactionCompleted(transition);
+
+        // Verify that screen is unblocked as start transaction of the transition
+        // has been completed
+        verify(mScreenUnblocker).sendToTarget();
+    }
+
+    @Test
+    public void testWaitForTransition_displayNotSwitching_doesNotWait() {
+        mSetFlagsRule.enableFlags(Flags.FLAG_WAIT_FOR_TRANSITION_ON_DISPLAY_SWITCH);
+        mDisplayContent.mDisplayUpdater.onDisplaySwitching(/* switching= */ false);
+
+        boolean willWait = mDisplayContent.mDisplayUpdater.waitForTransition(mScreenUnblocker);
+
+        assertThat(willWait).isFalse();
+        verify(mScreenUnblocker, never()).sendToTarget();
+    }
+
+    @Test
+    public void testWaitForTransition_displayIsSwitchingButFlagDisabled_doesNotWait() {
+        mSetFlagsRule.disableFlags(Flags.FLAG_WAIT_FOR_TRANSITION_ON_DISPLAY_SWITCH);
+        mDisplayContent.mDisplayUpdater.onDisplaySwitching(/* switching= */ true);
+
+        boolean willWait = mDisplayContent.mDisplayUpdater.waitForTransition(mScreenUnblocker);
+
+        assertThat(willWait).isFalse();
+        verify(mScreenUnblocker, never()).sendToTarget();
+    }
+
     private void mockTransitionsController(boolean enabled) {
         spyOn(mDisplayContent.mTransitionController);
         when(mDisplayContent.mTransitionController.isShellTransitionsEnabled()).thenReturn(enabled);
@@ -233,6 +274,23 @@
         return callbackCaptor;
     }
 
+    private ArgumentCaptor<Transition> captureRequestedTransition() {
+        ArgumentCaptor<Transition> callbackCaptor =
+                ArgumentCaptor.forClass(Transition.class);
+        verify(mDisplayContent.mTransitionController, atLeast(1))
+                .requestStartTransition(callbackCaptor.capture(), any(), any(), any());
+        return callbackCaptor;
+    }
+
+    private void makeTransitionTransactionCompleted(Transition transition) {
+        if (transition.mTransactionCompletedListeners != null) {
+            for (int i = 0; i < transition.mTransactionCompletedListeners.size(); i++) {
+                final Runnable listener = transition.mTransactionCompletedListeners.get(i);
+                listener.run();
+            }
+        }
+    }
+
     private void performInitialDisplayUpdate() {
         mUniqueId = "initial_unique_id";
         mColorMode = 0;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
index faa6d97..7380aec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
@@ -16,8 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.view.InsetsSource.ID_IME;
-import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 
@@ -26,7 +24,6 @@
 
 import android.graphics.PixelFormat;
 import android.platform.test.annotations.Presubmit;
-import android.view.InsetsSource;
 import android.view.inputmethod.ImeTracker;
 
 import androidx.test.filters.SmallTest;
@@ -46,57 +43,148 @@
 @RunWith(WindowTestRunner.class)
 public class ImeInsetsSourceProviderTest extends WindowTestsBase {
 
-    private InsetsSource mImeSource = new InsetsSource(ID_IME, ime());
     private ImeInsetsSourceProvider mImeProvider;
 
     @Before
     public void setUp() throws Exception {
-        mImeSource.setVisible(true);
-        mImeProvider = new ImeInsetsSourceProvider(mImeSource,
-                mDisplayContent.getInsetsStateController(), mDisplayContent);
+        mImeProvider = mDisplayContent.getInsetsStateController().getImeSourceProvider();
+        mImeProvider.getSource().setVisible(true);
     }
 
     @Test
     public void testTransparentControlTargetWindowCanShowIme() {
+        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+        makeWindowVisibleAndDrawn(ime);
+        mImeProvider.setWindowContainer(ime, null, null);
+
         final WindowState appWin = createWindow(null, TYPE_APPLICATION, "app");
         final WindowState popup = createWindow(appWin, TYPE_APPLICATION, "popup");
-        mDisplayContent.setImeControlTarget(popup);
-        mDisplayContent.setImeLayeringTarget(appWin);
         popup.mAttrs.format = PixelFormat.TRANSPARENT;
+        mDisplayContent.setImeLayeringTarget(appWin);
+        mDisplayContent.updateImeInputAndControlTarget(popup);
+        performSurfacePlacementAndWaitForWindowAnimator();
+
         mImeProvider.scheduleShowImePostLayout(appWin, ImeTracker.Token.empty());
         assertTrue(mImeProvider.isReadyToShowIme());
     }
 
+    /**
+     * Checks that scheduling with all the state set and manually triggering the show does succeed.
+     */
     @Test
-    public void testInputMethodInputTargetCanShowIme() {
-        WindowState target = createWindow(null, TYPE_APPLICATION, "app");
-        mDisplayContent.setImeLayeringTarget(target);
-        mDisplayContent.updateImeInputAndControlTarget(target);
-        mImeProvider.scheduleShowImePostLayout(target, ImeTracker.Token.empty());
-        assertTrue(mImeProvider.isReadyToShowIme());
-    }
-
-    @Test
-    public void testIsImeShowing() {
-        WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+    public void testScheduleShowIme() {
+        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
         makeWindowVisibleAndDrawn(ime);
         mImeProvider.setWindowContainer(ime, null, null);
 
-        WindowState target = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState target = createWindow(null, TYPE_APPLICATION, "app");
         mDisplayContent.setImeLayeringTarget(target);
-        mDisplayContent.setImeControlTarget(target);
+        mDisplayContent.updateImeInputAndControlTarget(target);
+        performSurfacePlacementAndWaitForWindowAnimator();
 
+        // Schedule (without triggering) after everything is ready.
         mImeProvider.scheduleShowImePostLayout(target, ImeTracker.Token.empty());
+        assertTrue(mImeProvider.isReadyToShowIme());
         assertFalse(mImeProvider.isImeShowing());
+
+        // Manually trigger the show.
         mImeProvider.checkShowImePostLayout();
+        // No longer ready as it was already shown.
+        assertFalse(mImeProvider.isReadyToShowIme());
         assertTrue(mImeProvider.isImeShowing());
-        mImeProvider.setImeShowing(false);
+    }
+
+    /**
+     * Checks that scheduling to show before any state is set does succeed when
+     * all the state becomes available.
+     */
+    @Test
+    public void testScheduleShowIme_noInitialState() {
+        final WindowState target = createWindow(null, TYPE_APPLICATION, "app");
+
+        // Schedule before anything is ready.
+        mImeProvider.scheduleShowImePostLayout(target, ImeTracker.Token.empty());
+        assertFalse(mImeProvider.isReadyToShowIme());
         assertFalse(mImeProvider.isImeShowing());
+
+        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+        makeWindowVisibleAndDrawn(ime);
+        mImeProvider.setWindowContainer(ime, null, null);
+
+        mDisplayContent.setImeLayeringTarget(target);
+        mDisplayContent.updateImeInputAndControlTarget(target);
+        // Performing surface placement picks up the show scheduled above.
+        performSurfacePlacementAndWaitForWindowAnimator();
+        // No longer ready as it was already shown.
+        assertFalse(mImeProvider.isReadyToShowIme());
+        assertTrue(mImeProvider.isImeShowing());
+    }
+
+    /**
+     * Checks that scheduling to show before starting the {@code afterPrepareSurfacesRunnable}
+     * from {@link InsetsStateController#notifyPendingInsetsControlChanged}
+     * does continue and succeed when the runnable is started.
+     */
+    @Test
+    public void testScheduleShowIme_delayedAfterPrepareSurfaces() {
+        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+        makeWindowVisibleAndDrawn(ime);
+        mImeProvider.setWindowContainer(ime, null, null);
+
+        final WindowState target = createWindow(null, TYPE_APPLICATION, "app");
+        mDisplayContent.setImeLayeringTarget(target);
+        mDisplayContent.updateImeInputAndControlTarget(target);
+
+        // Schedule before starting the afterPrepareSurfacesRunnable.
+        mImeProvider.scheduleShowImePostLayout(target, ImeTracker.Token.empty());
+        assertFalse(mImeProvider.isReadyToShowIme());
+        assertFalse(mImeProvider.isImeShowing());
+
+        // This tries to pick up the show scheduled above, but must fail as the
+        // afterPrepareSurfacesRunnable was not started yet.
+        mDisplayContent.applySurfaceChangesTransaction();
+        assertFalse(mImeProvider.isReadyToShowIme());
+        assertFalse(mImeProvider.isImeShowing());
+
+        // Starting the afterPrepareSurfacesRunnable picks up the show scheduled above.
+        mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+        // No longer ready as it was already shown.
+        assertFalse(mImeProvider.isReadyToShowIme());
+        assertTrue(mImeProvider.isImeShowing());
+    }
+
+    /**
+     * Checks that scheduling to show before the surface placement does continue and succeed
+     * when the surface placement happens.
+     */
+    @Test
+    public void testScheduleShowIme_delayedSurfacePlacement() {
+        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+        makeWindowVisibleAndDrawn(ime);
+        mImeProvider.setWindowContainer(ime, null, null);
+
+        final WindowState target = createWindow(null, TYPE_APPLICATION, "app");
+        mDisplayContent.setImeLayeringTarget(target);
+        mDisplayContent.updateImeInputAndControlTarget(target);
+
+        // Schedule before surface placement.
+        mImeProvider.scheduleShowImePostLayout(target, ImeTracker.Token.empty());
+        assertFalse(mImeProvider.isReadyToShowIme());
+        assertFalse(mImeProvider.isImeShowing());
+
+        // Performing surface placement picks up the show scheduled above, and succeeds.
+        // This first executes the afterPrepareSurfacesRunnable, and then
+        // applySurfaceChangesTransaction. Both of them try to trigger the show,
+        // but only the second one can succeed, as it comes after onPostLayout.
+        performSurfacePlacementAndWaitForWindowAnimator();
+        // No longer ready as it was already shown.
+        assertFalse(mImeProvider.isReadyToShowIme());
+        assertTrue(mImeProvider.isImeShowing());
     }
 
     @Test
     public void testSetFrozen() {
-        WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
+        final WindowState ime = createWindow(null, TYPE_INPUT_METHOD, "ime");
         makeWindowVisibleAndDrawn(ime);
         mImeProvider.setWindowContainer(ime, null, null);
         mImeProvider.setServerVisible(true);
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index 4034dbc..2a025cd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -24,6 +24,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -163,6 +164,48 @@
     }
 
     @Test
+    public void testGetLeash() {
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+        final WindowState target = createWindow(null, TYPE_APPLICATION, "target");
+        final WindowState fakeTarget = createWindow(null, TYPE_APPLICATION, "fakeTarget");
+        final WindowState otherTarget = createWindow(null, TYPE_APPLICATION, "otherTarget");
+        statusBar.getFrame().set(0, 0, 500, 100);
+
+        // We must not have control or control target before we have the insets source window,
+        // so also no leash.
+        mProvider.updateControlForTarget(target, true /* force */);
+        assertNull(mProvider.getControl(target));
+        assertNull(mProvider.getControlTarget());
+        assertNull(mProvider.getLeash(target));
+
+        // We can have the control or the control target after we have the insets source window,
+        // but no leash as this is not yet ready for dispatching.
+        mProvider.setWindowContainer(statusBar, null, null);
+        mProvider.updateControlForTarget(target, false /* force */);
+        assertNotNull(mProvider.getControl(target));
+        assertNotNull(mProvider.getControlTarget());
+        assertEquals(mProvider.getControlTarget(), target);
+        assertNull(mProvider.getLeash(target));
+
+        // After surface transactions are applied, the leash is ready for dispatching.
+        mProvider.onSurfaceTransactionApplied();
+        assertNotNull(mProvider.getLeash(target));
+
+        // We do have fake control for the fake control target, but that has no leash.
+        mProvider.updateFakeControlTarget(fakeTarget);
+        assertNotNull(mProvider.getControl(fakeTarget));
+        assertNotNull(mProvider.getFakeControlTarget());
+        assertNotEquals(mProvider.getControlTarget(), fakeTarget);
+        assertNull(mProvider.getLeash(fakeTarget));
+
+        // We don't have any control for a different (non-fake control target), so also no leash.
+        assertNull(mProvider.getControl(otherTarget));
+        assertNotNull(mProvider.getControlTarget());
+        assertNotEquals(mProvider.getControlTarget(), otherTarget);
+        assertNull(mProvider.getLeash(otherTarget));
+    }
+
+    @Test
     public void testUpdateSourceFrame() {
         final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
         mProvider.setWindowContainer(statusBar, null, null);
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 2085d61..0e1a1af 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -552,6 +552,24 @@
                 control2.getInsetsHint().bottom);
     }
 
+    @Test
+    public void testHasPendingControls() {
+        final WindowState statusBar = createWindow(null, TYPE_APPLICATION, "statusBar");
+        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        getController().getOrCreateSourceProvider(ID_STATUS_BAR, statusBars())
+                .setWindowContainer(statusBar, null, null);
+        // No controls dispatched yet.
+        assertFalse(getController().hasPendingControls(app));
+
+        getController().onBarControlTargetChanged(app, null, null, null);
+        // Controls pending to be dispatched.
+        assertTrue(getController().hasPendingControls(app));
+
+        performSurfacePlacementAndWaitForWindowAnimator();
+        // Pending controls were dispatched.
+        assertFalse(getController().hasPendingControls(app));
+    }
+
     /** Creates a window which is associated with ActivityRecord. */
     private WindowState createTestWindow(String name) {
         final WindowState win = createWindow(null, TYPE_APPLICATION, name);
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index bfa191e..75b84d1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -1472,7 +1472,6 @@
         assertSecurityException(expectCallable, () -> mAtm.registerTaskStackListener(null));
         assertSecurityException(expectCallable,
                 () -> mAtm.unregisterTaskStackListener(null));
-        assertSecurityException(expectCallable, () -> mAtm.getTaskDescription(0));
         assertSecurityException(expectCallable, () -> mAtm.cancelTaskWindowTransition(0));
         assertSecurityException(expectCallable, () -> mAtm.startRecentsActivity(null, 0,
                 null));
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 680738b..856ad2a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -27,7 +27,6 @@
 import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_16_9;
 import static android.content.pm.PackageManager.USER_MIN_ASPECT_RATIO_3_2;
@@ -1943,7 +1942,8 @@
         assertThat(mActivity.inSizeCompatMode()).isTrue();
         assertActivityMaxBoundsSandboxed();
 
-        final int scale = dh / dw;
+
+	final int scale = dh / dw;
 
         // App bounds should be dh / scale x dw / scale
         assertEquals(dw, rotatedDisplayBounds.width());
@@ -4148,37 +4148,6 @@
     }
 
     @Test
-    public void testFixedAspectRatioAppInPortraitCloseToSquareDisplay_notInSizeCompat() {
-        setUpDisplaySizeWithApp(2200, 2280);
-        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
-        final DisplayContent display = mActivity.mDisplayContent;
-        // Simulate taskbar, final app bounds are (0, 0, 2200, 2130) - landscape
-        final WindowState navbar = createWindow(null, TYPE_NAVIGATION_BAR, mDisplayContent,
-                "navbar");
-        final Binder owner = new Binder();
-        navbar.mAttrs.providedInsets = new InsetsFrameProvider[] {
-                new InsetsFrameProvider(owner, 0, WindowInsets.Type.navigationBars())
-                        .setInsetsSize(Insets.of(0, 0, 0, 150))
-        };
-        display.getDisplayPolicy().addWindowLw(navbar, navbar.mAttrs);
-        assertTrue(navbar.providesDisplayDecorInsets()
-                && display.getDisplayPolicy().updateDecorInsetsInfo());
-        display.sendNewConfiguration();
-
-        prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE,
-                SCREEN_ORIENTATION_LANDSCAPE);
-        // To force config to update again but with the same landscape orientation.
-        mActivity.setRequestedOrientation(SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
-
-        assertTrue(mActivity.shouldCreateCompatDisplayInsets());
-        assertNotNull(mActivity.getCompatDisplayInsets());
-        // Activity is not letterboxed for fixed orientation because orientation is respected
-        // with insets, and should not be in size compat mode
-        assertFalse(mActivity.isLetterboxedForFixedOrientationAndAspectRatio());
-        assertFalse(mActivity.inSizeCompatMode());
-    }
-
-    @Test
     public void testApplyAspectRatio_activityAlignWithParentAppVertical() {
         if (Flags.insetsDecoupledConfiguration()) {
             // TODO (b/151861875): Re-enable it. This is disabled temporarily because the config
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index dab966b..1ca808f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -833,7 +833,7 @@
         final ActivityRecord activity = new ActivityBuilder(mAtm).setTask(task).build();
         final ActivityRecord.CompatDisplayInsets compatInsets =
                 new ActivityRecord.CompatDisplayInsets(
-                        display, activity, /* letterboxedContainerBounds */ null);
+                        display, activity, /* fixedOrientationBounds= */ null);
         task.computeConfigResourceOverrides(inOutConfig, parentConfig, compatInsets);
 
         assertEquals(largerLandscapeBounds, inOutConfig.windowConfiguration.getAppBounds());
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 1233686..00a8842 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -167,6 +167,10 @@
     }
 
     @Override
+    public void onDisplaySwitchStart(int displayId) {
+    }
+
+    @Override
     public boolean okToAnimate(boolean ignoreScreenOn) {
         return mOkToAnimate;
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index e37da20..ec2c968 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -28,6 +28,7 @@
 import static android.view.flags.Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION;
 import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
 import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
+import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SENSITIVE_FOR_TRACING;
 import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY;
 import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
@@ -100,6 +101,7 @@
 import android.view.WindowInsets;
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
+import android.view.WindowManagerGlobal;
 import android.window.ActivityWindowInfo;
 import android.window.ClientWindowFrames;
 import android.window.InputTransferToken;
@@ -243,15 +245,6 @@
     }
 
     @Test
-    public void testDismissKeyguardCanWakeUp() {
-        doReturn(true).when(mWm).checkCallingPermission(anyString(), anyString());
-        doReturn(true).when(mWm.mAtmService.mKeyguardController).isShowingDream();
-        doNothing().when(mWm.mAtmService.mTaskSupervisor).wakeUp(anyString());
-        mWm.dismissKeyguard(null, "test-dismiss-keyguard");
-        verify(mWm.mAtmService.mTaskSupervisor).wakeUp(anyString());
-    }
-
-    @Test
     public void testTrackOverlayWindow() {
         final WindowProcessController wpc = mSystemServicesTestRule.addProcess(
                 "pkgName", "processName", 1000 /* pid */, Process.SYSTEM_UID);
@@ -319,7 +312,8 @@
         // Non activity window can still get the last config.
         win.mActivityRecord = null;
         win.fillClientWindowFramesAndConfiguration(outFrames, outConfig,
-                false /* useLatestConfig */, true /* relayoutVisible */);
+                null /* outActivityWindowInfo*/, false /* useLatestConfig */,
+                true /* relayoutVisible */);
         assertEquals(win.getConfiguration().densityDpi,
                 outConfig.getMergedConfiguration().densityDpi);
     }
@@ -554,6 +548,7 @@
                 .hasListener(eq(windowContextToken));
         doReturn(TYPE_INPUT_METHOD).when(mWm.mWindowContextListenerController)
                 .getWindowType(eq(windowContextToken));
+        doReturn(true).when(mWm.mUmInternal).isUserVisible(anyInt(), anyInt());
 
         mWm.addWindow(session, new TestIWindow(), params, View.VISIBLE, DEFAULT_DISPLAY,
                 UserHandle.USER_SYSTEM, WindowInsets.Type.defaultVisible(), null, new InsetsState(),
@@ -1115,6 +1110,34 @@
                 argThat(h -> (h.inputConfig & InputConfig.SPY) == InputConfig.SPY));
     }
 
+    @Test
+    public void testUpdateInputChannel_sanitizeInputFeatureSensitive_forUntrustedWindows() {
+        final Session session = mock(Session.class);
+        final int callingUid = Process.FIRST_APPLICATION_UID;
+        final int callingPid = 1234;
+        final SurfaceControl surfaceControl = mock(SurfaceControl.class);
+        final IBinder window = new Binder();
+        final InputTransferToken inputTransferToken = mock(InputTransferToken.class);
+
+        final InputChannel inputChannel = new InputChannel();
+        mWm.grantInputChannel(session, callingUid, callingPid, DEFAULT_DISPLAY, surfaceControl,
+                window, null /* hostInputToken */, FLAG_NOT_FOCUSABLE, 0 /* privateFlags */,
+                INPUT_FEATURE_SENSITIVE_FOR_TRACING, TYPE_APPLICATION, null /* windowToken */,
+                inputTransferToken,
+                "TestInputChannel", inputChannel);
+        verify(mTransaction).setInputWindowInfo(
+                eq(surfaceControl),
+                argThat(h -> (h.inputConfig & InputConfig.SENSITIVE_FOR_TRACING) == 0));
+
+        mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl,
+                FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY,
+                INPUT_FEATURE_SENSITIVE_FOR_TRACING,
+                null /* region */);
+        verify(mTransaction).setInputWindowInfo(
+                eq(surfaceControl),
+                argThat(h -> (h.inputConfig & InputConfig.SENSITIVE_FOR_TRACING) != 0));
+    }
+
     @RequiresFlagsDisabled(Flags.FLAG_ALWAYS_DRAW_MAGNIFICATION_FULLSCREEN_BORDER)
     @Test
     public void testDrawMagnifiedViewport() {
@@ -1239,12 +1262,61 @@
         final InsetsSourceControl.Array outControls = new InsetsSourceControl.Array();
         final Bundle outBundle = new Bundle();
 
-        mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.GONE, 0, 0, 0,
+        final ActivityRecord activity = win.mActivityRecord;
+        final ActivityWindowInfo expectedInfo = new ActivityWindowInfo();
+        expectedInfo.set(true, new Rect(0, 0, 1000, 2000), new Rect(0, 0, 500, 2000));
+        doReturn(expectedInfo).when(activity).getActivityWindowInfo();
+        activity.setVisibleRequested(false);
+        activity.setVisible(false);
+
+        mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.VISIBLE, 0, 0, 0,
                 outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle);
 
+        // No latest reported value, so return empty when activity is invisible
         final ActivityWindowInfo activityWindowInfo = outBundle.getParcelable(
                 IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO, ActivityWindowInfo.class);
-        assertEquals(win.mActivityRecord.getActivityWindowInfo(), activityWindowInfo);
+        assertEquals(new ActivityWindowInfo(), activityWindowInfo);
+
+        activity.setVisibleRequested(true);
+        activity.setVisible(true);
+
+        mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.VISIBLE, 0, 0, 0,
+                outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle);
+
+        // Report the latest when activity is visible.
+        final ActivityWindowInfo activityWindowInfo2 = outBundle.getParcelable(
+                IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO, ActivityWindowInfo.class);
+        assertEquals(expectedInfo, activityWindowInfo2);
+
+        expectedInfo.set(false, new Rect(0, 0, 1000, 2000), new Rect(0, 0, 1000, 2000));
+        activity.setVisibleRequested(false);
+        activity.setVisible(false);
+
+        mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.VISIBLE, 0, 0, 0,
+                outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle);
+
+        // Report the last reported value when activity is invisible.
+        final ActivityWindowInfo activityWindowInfo3 = outBundle.getParcelable(
+                IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO, ActivityWindowInfo.class);
+        assertEquals(activityWindowInfo2, activityWindowInfo3);
+    }
+
+    @Test
+    public void testAddOverlayWindowToUnassignedDisplay_notAllowed() {
+        int uid = 100000; // uid for non-system user
+        Session session = createTestSession(mAtm, 1234 /* pid */, uid);
+        DisplayContent dc = createNewDisplay();
+        int displayId = dc.getDisplayId();
+        int userId = UserHandle.getUserId(uid);
+        doReturn(false).when(mWm.mUmInternal).isUserVisible(eq(userId), eq(displayId));
+        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
+                LayoutParams.TYPE_APPLICATION_OVERLAY);
+
+        int result = mWm.addWindow(session, new TestIWindow(), params, View.VISIBLE, displayId,
+                userId, WindowInsets.Type.defaultVisible(), null, new InsetsState(),
+                new InsetsSourceControl.Array(), new Rect(), new float[1]);
+
+        assertThat(result).isEqualTo(WindowManagerGlobal.ADD_INVALID_DISPLAY);
     }
 
     class TestResultReceiver implements IResultReceiver {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 28e03bf..6bd0874 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -107,6 +107,7 @@
 import android.view.WindowManager;
 import android.view.WindowManager.DisplayImePolicy;
 import android.view.inputmethod.ImeTracker;
+import android.window.ActivityWindowInfo;
 import android.window.ClientWindowFrames;
 import android.window.ITaskFragmentOrganizer;
 import android.window.ITransitionPlayer;
@@ -694,7 +695,8 @@
 
     static void makeLastConfigReportedToClient(WindowState w, boolean visible) {
         w.fillClientWindowFramesAndConfiguration(new ClientWindowFrames(),
-                new MergedConfiguration(), true /* useLatestConfig */, visible);
+                new MergedConfiguration(), new ActivityWindowInfo(), true /* useLatestConfig */,
+                visible);
     }
 
     /**
diff --git a/services/usb/Android.bp b/services/usb/Android.bp
index e8ffe54..e00627e 100644
--- a/services/usb/Android.bp
+++ b/services/usb/Android.bp
@@ -44,6 +44,7 @@
 aconfig_declarations {
     name: "usb_flags",
     package: "com.android.server.usb.flags",
+    container: "system",
     srcs: ["**/usb_flags.aconfig"],
 }
 
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 2da352d..9470c0a 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -60,6 +60,7 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.DumpUtils;
@@ -222,6 +223,21 @@
         mContext.registerReceiverAsUser(receiver, UserHandle.ALL, filter, null, null);
     }
 
+    // Ideally we should use the injector pattern so we wouldn't need this constructor  for test
+    @VisibleForTesting
+    UsbService(Context context,
+                      UsbPortManager usbPortManager,
+                      UsbAlsaManager usbAlsaManager,
+                      UserManager userManager,
+                      UsbSettingsManager usbSettingsManager) {
+        mContext = context;
+        mPortManager = usbPortManager;
+        mAlsaManager = usbAlsaManager;
+        mUserManager = userManager;
+        mSettingsManager = usbSettingsManager;
+        mPermissionManager = new UsbPermissionManager(context, this);
+    }
+
     /**
      * Set new {@link #mCurrentUserId} and propagate it to other modules.
      *
@@ -886,7 +902,16 @@
 
     @Override
     public boolean enableUsbData(String portId, boolean enable, int operationId,
-            IUsbOperationInternal callback) {
+                                 IUsbOperationInternal callback) {
+        return enableUsbDataInternal(portId, enable, operationId, callback, Binder.getCallingUid());
+    }
+
+    /**
+     *  Internal function abstracted for testing with callerUid
+     */
+    @VisibleForTesting
+    boolean enableUsbDataInternal(String portId, boolean enable, int operationId,
+            IUsbOperationInternal callback, int callerUid) {
         Objects.requireNonNull(portId, "enableUsbData: portId must not be null. opId:"
                 + operationId);
         Objects.requireNonNull(callback, "enableUsbData: callback must not be null. opId:"
@@ -894,7 +919,14 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
 
         if (android.hardware.usb.flags.Flags.enableUsbDataSignalStaking()) {
-            if (!shouldUpdateUsbSignaling(portId, enable, Binder.getCallingUid())) return false;
+            if (!shouldUpdateUsbSignaling(portId, enable, callerUid)) {
+                try {
+                    callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "enableUsbData: Failed to call onOperationComplete", e);
+                }
+                return false;
+            }
         }
 
         final long ident = Binder.clearCallingIdentity();
@@ -943,15 +975,35 @@
 
     @Override
     public void enableUsbDataWhileDocked(String portId, int operationId,
-            IUsbOperationInternal callback) {
+                                         IUsbOperationInternal callback) {
+        enableUsbDataWhileDockedInternal(portId, operationId, callback, Binder.getCallingUid());
+    }
+
+    /**
+     *  Internal function abstracted for testing with callerUid
+     */
+    @VisibleForTesting
+     void enableUsbDataWhileDockedInternal(String portId, int operationId,
+            IUsbOperationInternal callback, int callerUid) {
         Objects.requireNonNull(portId, "enableUsbDataWhileDocked: portId must not be null. opId:"
                 + operationId);
         Objects.requireNonNull(callback,
                 "enableUsbDataWhileDocked: callback must not be null. opId:"
                 + operationId);
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+
+        if (android.hardware.usb.flags.Flags.enableUsbDataSignalStaking()) {
+            if (!shouldUpdateUsbSignaling(portId, true, callerUid)) {
+                try {
+                    callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "enableUsbDataWhileDocked: Failed to call onOperationComplete", e);
+                }
+                return;
+            }
+        }
+
         final long ident = Binder.clearCallingIdentity();
-        boolean wait;
         try {
             if (mPortManager != null) {
                 mPortManager.enableUsbDataWhileDocked(portId, operationId, callback, null);
diff --git a/services/usb/java/com/android/server/usb/flags/usb_flags.aconfig b/services/usb/java/com/android/server/usb/flags/usb_flags.aconfig
index ea6e502..a7c5ddb 100644
--- a/services/usb/java/com/android/server/usb/flags/usb_flags.aconfig
+++ b/services/usb/java/com/android/server/usb/flags/usb_flags.aconfig
@@ -1,4 +1,5 @@
 package: "com.android.server.usb.flags"
+container: "system"
 
 flag {
     name: "allow_restriction_of_overlay_activities"
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index 86eed2f..ec60c67 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -793,7 +793,7 @@
         if (isGranted) return;
 
         if (allowCarrierPrivilegeOnAnySub) {
-            if (checkCarrierPrivilegeForAnySubId(context, Binder.getCallingUid())) return;
+            if (checkCarrierPrivilegeForAnySubId(context, uid)) return;
         } else {
             if (checkCarrierPrivilegeForSubId(context, subId)) return;
         }
diff --git a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
index a63db88..7b5b07c 100644
--- a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
+++ b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
@@ -16,6 +16,8 @@
 package com.android.internal.telephony.util;
 
 import static android.telephony.Annotation.DataState;
+import static android.telephony.NetworkRegistrationInfo.FIRST_SERVICE_TYPE;
+import static android.telephony.NetworkRegistrationInfo.LAST_SERVICE_TYPE;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -37,6 +39,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.TelephonyManager;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.internal.telephony.ITelephony;
@@ -48,6 +51,8 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Supplier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * This class provides various util functions
@@ -342,4 +347,31 @@
         return false;
 
     }
+
+    /**
+     * @param plmn target plmn for validation.
+     * @return {@code true} if the target plmn is valid {@code false} otherwise.
+     */
+    public static boolean isValidPlmn(@Nullable String plmn) {
+        if (TextUtils.isEmpty(plmn)) {
+            return false;
+        }
+        Pattern pattern = Pattern.compile("^(?:[0-9]{3})(?:[0-9]{2}|[0-9]{3})$");
+        Matcher matcher = pattern.matcher(plmn);
+        if (!matcher.matches()) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * @param serviceType target serviceType for validation.
+     * @return {@code true} if the target serviceType is valid {@code false} otherwise.
+     */
+    public static boolean isValidService(int serviceType) {
+        if (serviceType < FIRST_SERVICE_TYPE || serviceType > LAST_SERVICE_TYPE) {
+            return false;
+        }
+        return true;
+    }
 }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index ebdd556..98eeab4 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -9890,6 +9890,31 @@
             "satellite_entitlement_app_name_string";
 
     /**
+     * URL to redirect user to get more information about the carrier support for satellite.
+     *
+     * The default value is empty string.
+     *
+     * @hide
+     */
+    public static final String KEY_SATELLITE_INFORMATION_REDIRECT_URL_STRING =
+            "satellite_information_redirect_url_string";
+
+    /**
+     * An int array that contains default capabilities for carrier enabled satellite roaming.
+     * If any PLMN is provided from the entitlement server, and it is not listed in
+     * {@link #KEY_CARRIER_SUPPORTED_SATELLITE_SERVICES_PER_PROVIDER_BUNDLE}, default capabilities
+     * will be used instead.
+     * <p>
+     * The default capabilities are
+     * {@link NetworkRegistrationInfo#SERVICE_TYPE_SMS}, and
+     * {@link NetworkRegistrationInfo#SERVICE_TYPE_MMS}
+     *
+     * @hide
+     */
+    public static final String KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY =
+            "carrier_roaming_satellite_default_services_int_array";
+
+    /**
      * Indicating whether DUN APN should be disabled when the device is roaming. In that case,
      * the default APN (i.e. internet) will be used for tethering.
      *
@@ -11034,6 +11059,12 @@
         sDefaults.putInt(KEY_SATELLITE_ENTITLEMENT_STATUS_REFRESH_DAYS_INT, 7);
         sDefaults.putBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, false);
         sDefaults.putString(KEY_SATELLITE_ENTITLEMENT_APP_NAME_STRING, "androidSatmode");
+        sDefaults.putString(KEY_SATELLITE_INFORMATION_REDIRECT_URL_STRING, "");
+        sDefaults.putIntArray(KEY_CARRIER_ROAMING_SATELLITE_DEFAULT_SERVICES_INT_ARRAY,
+                new int[] {
+                        NetworkRegistrationInfo.SERVICE_TYPE_SMS,
+                        NetworkRegistrationInfo.SERVICE_TYPE_MMS
+                });
         sDefaults.putBoolean(KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL, false);
         sDefaults.putString(KEY_DEFAULT_PREFERRED_APN_NAME_STRING, "");
         sDefaults.putBoolean(KEY_SUPPORTS_CALL_COMPOSER_BOOL, false);
diff --git a/telephony/java/android/telephony/satellite/ISatelliteSupportedStateCallback.aidl b/telephony/java/android/telephony/satellite/ISatelliteSupportedStateCallback.aidl
new file mode 100644
index 0000000..0455090
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/ISatelliteSupportedStateCallback.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+/**
+ * Interface for satellite supported state change callback.
+ * @hide
+ */
+oneway interface ISatelliteSupportedStateCallback {
+    /**
+     * Called when satellite supported state has changed.
+     *
+     * @param supoprted Whether satellite is supported or not.
+     */
+    void onSatelliteSupportedStateChanged(in boolean supported);
+}
+
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index 4a61114..20b24b9 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -87,6 +87,9 @@
     private static final ConcurrentHashMap<SatelliteCapabilitiesCallback,
             ISatelliteCapabilitiesCallback>
             sSatelliteCapabilitiesCallbackMap = new ConcurrentHashMap<>();
+    private static final ConcurrentHashMap<SatelliteSupportedStateCallback,
+            ISatelliteSupportedStateCallback> sSatelliteSupportedStateCallbackMap =
+            new ConcurrentHashMap<>();
 
     private final int mSubId;
 
@@ -2284,6 +2287,88 @@
         return new ArrayList<>();
     }
 
+    /**
+     * Registers for the satellite supported state changed.
+     *
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback to handle the satellite supoprted state changed event.
+     *
+     * @return The {@link SatelliteResult} result of the operation.
+     *
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @SatelliteResult public int registerForSupportedStateChanged(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull SatelliteSupportedStateCallback callback) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                ISatelliteSupportedStateCallback internalCallback =
+                        new ISatelliteSupportedStateCallback.Stub() {
+                            @Override
+                            public void onSatelliteSupportedStateChanged(boolean supported) {
+                                executor.execute(() -> Binder.withCleanCallingIdentity(
+                                        () -> callback.onSatelliteSupportedStateChanged(
+                                                supported)));
+                            }
+                        };
+                sSatelliteSupportedStateCallbackMap.put(callback, internalCallback);
+                return telephony.registerForSatelliteSupportedStateChanged(
+                        mSubId, internalCallback);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("registerForSupportedStateChanged() RemoteException: " + ex);
+            ex.rethrowAsRuntimeException();
+        }
+        return SATELLITE_RESULT_REQUEST_FAILED;
+    }
+
+    /**
+     * Unregisters for the satellite supported state changed.
+     * If callback was not registered before, the request will be ignored.
+     *
+     * @param callback The callback that was passed to
+     * {@link #registerForSupportedStateChanged(Executor, SatelliteSupportedStateCallback)}
+     *
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+    public void unregisterForSupportedStateChanged(
+            @NonNull SatelliteSupportedStateCallback callback) {
+        Objects.requireNonNull(callback);
+        ISatelliteSupportedStateCallback internalCallback =
+                sSatelliteSupportedStateCallbackMap.remove(callback);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                if (internalCallback != null) {
+                    telephony.unregisterForSatelliteSupportedStateChanged(mSubId, internalCallback);
+                } else {
+                    loge("unregisterForSupportedStateChanged: No internal callback.");
+                }
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("unregisterForSupportedStateChanged() RemoteException: " + ex);
+            ex.rethrowAsRuntimeException();
+        }
+    }
+
     @Nullable private static ITelephony getITelephony() {
         ITelephony binder = ITelephony.Stub.asInterface(TelephonyFrameworkInitializer
                 .getTelephonyServiceManager()
diff --git a/telephony/java/android/telephony/satellite/SatelliteSupportedStateCallback.java b/telephony/java/android/telephony/satellite/SatelliteSupportedStateCallback.java
new file mode 100644
index 0000000..7e19bd1
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/SatelliteSupportedStateCallback.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+import android.annotation.FlaggedApi;
+
+import com.android.internal.telephony.flags.Flags;
+
+/**
+ * A callback class for monitoring satellite supported state change events.
+ *
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+public interface SatelliteSupportedStateCallback {
+    /**
+     * Called when satellite supported state changes.
+     *
+     * @param supported The new supported state. {@code true} means satellite is supported,
+     * {@code false} means satellite is not supported.
+     *
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+    void onSatelliteSupportedStateChanged(boolean supported);
+}
diff --git a/telephony/java/android/telephony/satellite/stub/ISatellite.aidl b/telephony/java/android/telephony/satellite/stub/ISatellite.aidl
index 36485c6..16983a0 100644
--- a/telephony/java/android/telephony/satellite/stub/ISatellite.aidl
+++ b/telephony/java/android/telephony/satellite/stub/ISatellite.aidl
@@ -83,6 +83,9 @@
      *
      * @param enableSatellite True to enable the satellite modem and false to disable.
      * @param enableDemoMode True to enable demo mode and false to disable.
+     * @param isEmergency To specify the satellite is enabled for emergency session and false for
+     * non emergency session. Note: it is possible that a emergency session started get converted
+     * to a non emergency session and vice versa.
      * @param resultCallback The callback to receive the error code result of the operation.
      *
      * Valid result codes returned:
@@ -96,7 +99,7 @@
      *   SatelliteResult:SATELLITE_RESULT_NO_RESOURCES
      */
     void requestSatelliteEnabled(in boolean enableSatellite, in boolean enableDemoMode,
-            in IIntegerConsumer resultCallback);
+            in boolean isEmergency, in IIntegerConsumer resultCallback);
 
     /**
      * Request to get whether the satellite modem is enabled.
diff --git a/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl b/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl
index ccca5ad..5b9dfc6 100644
--- a/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl
+++ b/telephony/java/android/telephony/satellite/stub/ISatelliteListener.aidl
@@ -74,4 +74,11 @@
      * @param SatelliteCapabilities The current satellite capabilities.
      */
     void onSatelliteCapabilitiesChanged(in SatelliteCapabilities capabilities);
+
+    /**
+     * Called when supported state of satellite has changed
+     *
+     * @param supported True means satellite service is supported and false means it is not.
+     */
+    void onSatelliteSupportedStateChanged(in boolean supported);
 }
diff --git a/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java b/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java
index b7dc79f..a623633 100644
--- a/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java
+++ b/telephony/java/android/telephony/satellite/stub/SatelliteImplBase.java
@@ -90,11 +90,11 @@
 
         @Override
         public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode,
-                IIntegerConsumer resultCallback) throws RemoteException {
+                boolean isEmergency, IIntegerConsumer resultCallback) throws RemoteException {
             executeMethodAsync(
                     () -> SatelliteImplBase.this
                             .requestSatelliteEnabled(
-                                    enableSatellite, enableDemoMode, resultCallback),
+                                    enableSatellite, enableDemoMode, isEmergency, resultCallback),
                     "requestSatelliteEnabled");
         }
 
@@ -337,6 +337,9 @@
      *
      * @param enableSatellite True to enable the satellite modem and false to disable.
      * @param enableDemoMode True to enable demo mode and false to disable.
+     * @param isEmergency To specify the satellite is enabled for emergency session and false for
+     * non emergency session. Note: it is possible that a emergency session started get converted
+     * to a non emergency session and vice versa.
      * @param resultCallback The callback to receive the error code result of the operation.
      *
      * Valid result codes returned:
@@ -350,7 +353,7 @@
      *   SatelliteResult:SATELLITE_RESULT_NO_RESOURCES
      */
     public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode,
-            @NonNull IIntegerConsumer resultCallback) {
+            boolean isEmergency, @NonNull IIntegerConsumer resultCallback) {
         // stub implementation
     }
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index ff2ee27..f25fc36 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -72,6 +72,7 @@
 import android.telephony.satellite.ISatelliteDatagramCallback;
 import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
 import android.telephony.satellite.ISatelliteProvisionStateCallback;
+import android.telephony.satellite.ISatelliteSupportedStateCallback;
 import android.telephony.satellite.ISatelliteModemStateCallback;
 import android.telephony.satellite.NtnSignalStrength;
 import android.telephony.satellite.SatelliteCapabilities;
@@ -3315,4 +3316,29 @@
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
             + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
     List<String> getSatellitePlmnsForCarrier(int subId);
+
+    /**
+     * Registers for supported state changed from satellite modem.
+     *
+     * @param subId The subId of the subscription to register for supported state changed.
+     * @param callback The callback to handle the satellite supported state changed event.
+     *
+     * @return The {@link SatelliteError} result of the operation.
+     */
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    int registerForSatelliteSupportedStateChanged(int subId,
+            in ISatelliteSupportedStateCallback callback);
+
+    /**
+     * Unregisters for supported state changed from satellite modem.
+     * If callback was not registered before, the request will be ignored.
+     *
+     * @param subId The subId of the subscription to unregister for supported state changed.
+     * @param callback The callback that was passed to registerForSatelliteSupportedStateChanged.
+     */
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void unregisterForSatelliteSupportedStateChanged(int subId,
+            in ISatelliteSupportedStateCallback callback);
 }
diff --git a/tests/FlickerTests/Notification/src/com/android/server/wm/flicker/notification/OpenAppFromLockscreenNotificationWithOverlayAppTest.kt b/tests/FlickerTests/Notification/src/com/android/server/wm/flicker/notification/OpenAppFromLockscreenNotificationWithOverlayAppTest.kt
index 8e210d4..f1df8a6 100644
--- a/tests/FlickerTests/Notification/src/com/android/server/wm/flicker/notification/OpenAppFromLockscreenNotificationWithOverlayAppTest.kt
+++ b/tests/FlickerTests/Notification/src/com/android/server/wm/flicker/notification/OpenAppFromLockscreenNotificationWithOverlayAppTest.kt
@@ -123,7 +123,9 @@
     @Test
     override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
 
-    @Presubmit @Test override fun entireScreenCovered() = super.entireScreenCovered()
+    @FlakyTest(bugId = 227143265)
+    @Test
+    override fun entireScreenCovered() = super.entireScreenCovered()
 
     @FlakyTest(bugId = 278227468)
     @Test
diff --git a/tests/FlickerTests/Rotation/src/com/android/server/wm/flicker/rotation/RotationTransition.kt b/tests/FlickerTests/Rotation/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
index c7da778..75b4bbd 100644
--- a/tests/FlickerTests/Rotation/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
+++ b/tests/FlickerTests/Rotation/src/com/android/server/wm/flicker/rotation/RotationTransition.kt
@@ -17,10 +17,14 @@
 package com.android.server.wm.flicker.rotation
 
 import android.platform.test.annotations.Presubmit
+import android.tools.Position
+import android.tools.datatypes.Rect
 import android.tools.device.apphelpers.StandardAppHelper
 import android.tools.flicker.legacy.FlickerBuilder
 import android.tools.flicker.legacy.LegacyFlickerTest
 import android.tools.flicker.subject.layers.LayerTraceEntrySubject
+import android.tools.traces.Condition
+import android.tools.traces.DeviceStateDump
 import android.tools.traces.component.ComponentNameMatcher
 import android.tools.traces.component.IComponentMatcher
 import android.tools.traces.surfaceflinger.Display
@@ -36,7 +40,12 @@
     override val transition: FlickerBuilder.() -> Unit = {
         setup { this.setRotation(flicker.scenario.startRotation) }
         teardown { testApp.exit(wmHelper) }
-        transitions { this.setRotation(flicker.scenario.endRotation) }
+        transitions {
+            this.setRotation(flicker.scenario.endRotation)
+            wmHelper.StateSyncBuilder()
+                .add(navBarInPosition(flicker.scenario.isGesturalNavigation))
+                .waitForAndVerify()
+        }
     }
 
     /** {@inheritDoc} */
@@ -89,4 +98,37 @@
         appLayerRotates_StartingPos()
         appLayerRotates_EndingPos()
     }
+
+    private fun navBarInPosition(isGesturalNavigation: Boolean): Condition<DeviceStateDump> {
+        return Condition("navBarPosition") { dump ->
+            val display =
+                dump.layerState.displays.filterNot { it.isOff }.minByOrNull { it.id }
+                    ?: error("There is no display!")
+            val displayArea = display.layerStackSpace
+            val navBarPosition = display.navBarPosition(isGesturalNavigation)
+            val navBarRegion = dump.layerState
+                .getLayerWithBuffer(ComponentNameMatcher.NAV_BAR)
+                ?.visibleRegion?.bounds ?: Rect.EMPTY
+
+            when (navBarPosition) {
+                Position.TOP ->
+                    navBarRegion.top == displayArea.top &&
+                        navBarRegion.left == displayArea.left &&
+                        navBarRegion.right == displayArea.right
+                Position.BOTTOM ->
+                    navBarRegion.bottom == displayArea.bottom &&
+                        navBarRegion.left == displayArea.left &&
+                        navBarRegion.right == displayArea.right
+                Position.LEFT ->
+                    navBarRegion.left == displayArea.left &&
+                        navBarRegion.top == displayArea.top &&
+                        navBarRegion.bottom == displayArea.bottom
+                Position.RIGHT ->
+                    navBarRegion.right == displayArea.right &&
+                        navBarRegion.top == displayArea.top &&
+                        navBarRegion.bottom == displayArea.bottom
+                else -> error("Unknown position $navBarPosition")
+            }
+        }
+    }
 }
diff --git a/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
index d9a4c26..5cdfb28 100644
--- a/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/LegacyProtoLogImplTest.java
@@ -90,7 +90,7 @@
         //noinspection ResultOfMethodCallIgnored
         mFile.delete();
         mProtoLog = new LegacyProtoLogImpl(mFile, mViewerConfigFilename,
-                1024 * 1024, mReader, 1024, new TreeMap<>());
+                1024 * 1024, mReader, 1024, new TreeMap<>(), () -> {});
     }
 
     @After
diff --git a/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java b/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java
index a963890..001a09a 100644
--- a/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/PerfettoDataSourceTest.java
@@ -67,7 +67,7 @@
 
     @Test
     public void allEnabledTraceMode() {
-        final ProtoLogDataSource ds = new ProtoLogDataSource(() -> {}, () -> {}, () -> {});
+        final ProtoLogDataSource ds = new ProtoLogDataSource((c) -> {}, () -> {}, (c) -> {});
 
         final ProtoLogDataSource.TlsState tlsState = createTlsState(
                 DataSourceConfigOuterClass.DataSourceConfig.newBuilder().setProtologConfig(
@@ -154,7 +154,7 @@
     private ProtoLogDataSource.TlsState createTlsState(
             DataSourceConfigOuterClass.DataSourceConfig config) {
         final ProtoLogDataSource ds =
-                Mockito.spy(new ProtoLogDataSource(() -> {}, () -> {}, () -> {}));
+                Mockito.spy(new ProtoLogDataSource((c) -> {}, () -> {}, (c) -> {}));
 
         ProtoInputStream configStream = new ProtoInputStream(config.toByteArray());
         final ProtoLogDataSource.Instance dsInstance = Mockito.spy(
diff --git a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
index 548adef..f6ac080 100644
--- a/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
+++ b/tests/Internal/src/com/android/internal/protolog/PerfettoProtoLogImplTest.java
@@ -65,6 +65,7 @@
 import java.util.List;
 import java.util.Random;
 import java.util.TreeMap;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import perfetto.protos.Protolog;
 import perfetto.protos.ProtologCommon;
@@ -95,6 +96,7 @@
     private PerfettoProtoLogImpl mProtoLog;
     private Protolog.ProtoLogViewerConfig.Builder mViewerConfigBuilder;
     private File mFile;
+    private Runnable mCacheUpdater;
 
     private ProtoLogViewerConfigReader mReader;
 
@@ -152,9 +154,11 @@
         Mockito.when(viewerConfigInputStreamProvider.getInputStream())
                 .thenAnswer(it -> new ProtoInputStream(mViewerConfigBuilder.build().toByteArray()));
 
+        mCacheUpdater = () -> {};
         mReader = Mockito.spy(new ProtoLogViewerConfigReader(viewerConfigInputStreamProvider));
-        mProtoLog =
-                new PerfettoProtoLogImpl(viewerConfigInputStreamProvider, mReader, new TreeMap<>());
+        mProtoLog = new PerfettoProtoLogImpl(
+                viewerConfigInputStreamProvider, mReader, new TreeMap<>(),
+                () -> mCacheUpdater.run());
     }
 
     @After
@@ -500,7 +504,8 @@
         PerfettoTraceMonitor traceMonitor =
                 PerfettoTraceMonitor.newBuilder().enableProtoLog(true,
                         List.of(new PerfettoTraceMonitor.Builder.ProtoLogGroupOverride(
-                                TestProtoLogGroup.TEST_GROUP.toString(), LogLevel.DEBUG, true)))
+                                TestProtoLogGroup.TEST_GROUP.toString(), LogLevel.DEBUG,
+                                true)))
                         .build();
         try {
             traceMonitor.start();
@@ -526,6 +531,142 @@
         Truth.assertThat(stacktrace).contains("stackTraceTrimmed");
     }
 
+    @Test
+    public void cacheIsUpdatedWhenTracesStartAndStop() {
+        final AtomicInteger cacheUpdateCallCount = new AtomicInteger(0);
+        mCacheUpdater = cacheUpdateCallCount::incrementAndGet;
+
+        PerfettoTraceMonitor traceMonitor1 =
+                PerfettoTraceMonitor.newBuilder().enableProtoLog(true,
+                                List.of(new PerfettoTraceMonitor.Builder.ProtoLogGroupOverride(
+                                        TestProtoLogGroup.TEST_GROUP.toString(), LogLevel.WARN,
+                                        false)))
+                        .build();
+
+        PerfettoTraceMonitor traceMonitor2 =
+                PerfettoTraceMonitor.newBuilder().enableProtoLog(true,
+                                List.of(new PerfettoTraceMonitor.Builder.ProtoLogGroupOverride(
+                                        TestProtoLogGroup.TEST_GROUP.toString(), LogLevel.DEBUG,
+                                        false)))
+                        .build();
+
+        Truth.assertThat(cacheUpdateCallCount.get()).isEqualTo(0);
+
+        try {
+            traceMonitor1.start();
+
+            Truth.assertThat(cacheUpdateCallCount.get()).isEqualTo(1);
+
+            try {
+                traceMonitor2.start();
+
+                Truth.assertThat(cacheUpdateCallCount.get()).isEqualTo(2);
+            } finally {
+                traceMonitor2.stop(mWriter);
+            }
+
+            Truth.assertThat(cacheUpdateCallCount.get()).isEqualTo(3);
+
+        } finally {
+            traceMonitor1.stop(mWriter);
+        }
+
+        Truth.assertThat(cacheUpdateCallCount.get()).isEqualTo(4);
+    }
+
+    @Test
+    public void isEnabledUpdatesBasedOnRunningTraces() {
+        Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.DEBUG))
+                .isFalse();
+        Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.VERBOSE))
+                .isFalse();
+        Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.INFO))
+                .isFalse();
+        Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WARN))
+                .isFalse();
+        Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.ERROR))
+                .isFalse();
+        Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF)).isTrue();
+
+        PerfettoTraceMonitor traceMonitor1 =
+                PerfettoTraceMonitor.newBuilder().enableProtoLog(true,
+                                List.of(new PerfettoTraceMonitor.Builder.ProtoLogGroupOverride(
+                                        TestProtoLogGroup.TEST_GROUP.toString(), LogLevel.WARN,
+                                        false)))
+                        .build();
+
+        PerfettoTraceMonitor traceMonitor2 =
+                PerfettoTraceMonitor.newBuilder().enableProtoLog(true,
+                                List.of(new PerfettoTraceMonitor.Builder.ProtoLogGroupOverride(
+                                        TestProtoLogGroup.TEST_GROUP.toString(), LogLevel.DEBUG,
+                                        false)))
+                        .build();
+
+        try {
+            traceMonitor1.start();
+
+            Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.DEBUG))
+                    .isFalse();
+            Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.VERBOSE))
+                    .isFalse();
+            Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.INFO))
+                    .isFalse();
+            Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WARN))
+                    .isTrue();
+            Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.ERROR))
+                    .isTrue();
+            Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF))
+                    .isTrue();
+
+            try {
+                traceMonitor2.start();
+
+                Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.DEBUG))
+                        .isTrue();
+                Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP,
+                        LogLevel.VERBOSE)).isTrue();
+                Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.INFO))
+                        .isTrue();
+                Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WARN))
+                        .isTrue();
+                Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.ERROR))
+                        .isTrue();
+                Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF))
+                        .isTrue();
+            } finally {
+                traceMonitor2.stop(mWriter);
+            }
+
+            Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.DEBUG))
+                    .isFalse();
+            Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.VERBOSE))
+                    .isFalse();
+            Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.INFO))
+                    .isFalse();
+            Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WARN))
+                    .isTrue();
+            Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.ERROR))
+                    .isTrue();
+            Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF))
+                    .isTrue();
+        } finally {
+            traceMonitor1.stop(mWriter);
+        }
+
+        Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.DEBUG))
+                .isFalse();
+        Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.VERBOSE))
+                .isFalse();
+        Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.INFO))
+                .isFalse();
+        Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WARN))
+                .isFalse();
+        Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.ERROR))
+                .isFalse();
+        Truth.assertThat(mProtoLog.isEnabled(TestProtoLogGroup.TEST_GROUP, LogLevel.WTF))
+                .isTrue();
+    }
+
     private enum TestProtoLogGroup implements IProtoLogGroup {
         TEST_GROUP(true, true, false, "TEST_TAG");
 
diff --git a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
index 081da11..489ef44 100644
--- a/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/CrashRecoveryTest.java
@@ -66,6 +66,7 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.mockito.MockitoSession;
 import org.mockito.quality.Strictness;
@@ -220,43 +221,36 @@
         RescuePartyObserver rescuePartyObserver = setUpRescuePartyObserver(watchdog);
 
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(1);
-        int bootCounter = 0;
+
         for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
             watchdog.noteBoot();
-            bootCounter += 1;
         }
+
         verify(rescuePartyObserver).executeBootLoopMitigation(1);
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
 
-        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) {
-            watchdog.noteBoot();
-            bootCounter += 1;
-        }
+        watchdog.noteBoot();
+
         verify(rescuePartyObserver).executeBootLoopMitigation(2);
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(3);
 
-        int bootLoopThreshold = PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - bootCounter;
-        for (int i = 0; i < bootLoopThreshold; i++) {
-            watchdog.noteBoot();
-        }
+        watchdog.noteBoot();
+
         verify(rescuePartyObserver).executeBootLoopMitigation(3);
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(4);
 
-        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) {
-            watchdog.noteBoot();
-        }
+        watchdog.noteBoot();
+
         verify(rescuePartyObserver).executeBootLoopMitigation(4);
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(5);
 
-        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) {
-            watchdog.noteBoot();
-        }
+        watchdog.noteBoot();
+
         verify(rescuePartyObserver).executeBootLoopMitigation(5);
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(6);
 
-        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) {
-            watchdog.noteBoot();
-        }
+        watchdog.noteBoot();
+
         verify(rescuePartyObserver).executeBootLoopMitigation(6);
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(7);
     }
@@ -268,11 +262,11 @@
                 setUpRollbackPackageHealthObserver(watchdog);
 
         verify(rollbackObserver, never()).executeBootLoopMitigation(1);
-        int bootCounter = 0;
+
         for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
             watchdog.noteBoot();
-            bootCounter += 1;
         }
+
         verify(rollbackObserver).executeBootLoopMitigation(1);
         verify(rollbackObserver, never()).executeBootLoopMitigation(2);
 
@@ -280,19 +274,16 @@
         when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_HIGH,
                 ROLLBACK_INFO_MANUAL));
 
-        int bootLoopThreshold = PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - bootCounter;
-        for (int i = 0; i < bootLoopThreshold; i++) {
-            watchdog.noteBoot();
-        }
+        watchdog.noteBoot();
+
         verify(rollbackObserver).executeBootLoopMitigation(2);
         verify(rollbackObserver, never()).executeBootLoopMitigation(3);
 
         // Update the list of available rollbacks after executing bootloop mitigation once
         when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_MANUAL));
 
-        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) {
-            watchdog.noteBoot();
-        }
+        watchdog.noteBoot();
+
         verify(rollbackObserver, never()).executeBootLoopMitigation(3);
     }
 
@@ -305,27 +296,21 @@
 
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(1);
         verify(rollbackObserver, never()).executeBootLoopMitigation(1);
-        int bootCounter = 0;
         for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
             watchdog.noteBoot();
-            bootCounter += 1;
         }
         verify(rescuePartyObserver).executeBootLoopMitigation(1);
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
         verify(rollbackObserver, never()).executeBootLoopMitigation(1);
 
-        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) {
-            watchdog.noteBoot();
-            bootCounter += 1;
-        }
+        watchdog.noteBoot();
+
         verify(rescuePartyObserver).executeBootLoopMitigation(2);
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(3);
         verify(rollbackObserver, never()).executeBootLoopMitigation(2);
 
-        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) {
-            watchdog.noteBoot();
-            bootCounter += 1;
-        }
+        watchdog.noteBoot();
+
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(3);
         verify(rollbackObserver).executeBootLoopMitigation(1);
         verify(rollbackObserver, never()).executeBootLoopMitigation(2);
@@ -333,43 +318,46 @@
         when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_HIGH,
                 ROLLBACK_INFO_MANUAL));
 
-        int bootLoopThreshold = PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - bootCounter;
-        for (int i = 0; i < bootLoopThreshold; i++) {
-            watchdog.noteBoot();
-        }
+        watchdog.noteBoot();
+
         verify(rescuePartyObserver).executeBootLoopMitigation(3);
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(4);
         verify(rollbackObserver, never()).executeBootLoopMitigation(2);
 
-        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) {
-            watchdog.noteBoot();
-        }
+        watchdog.noteBoot();
+
         verify(rescuePartyObserver).executeBootLoopMitigation(4);
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(5);
         verify(rollbackObserver, never()).executeBootLoopMitigation(2);
 
-        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) {
-            watchdog.noteBoot();
-        }
+        watchdog.noteBoot();
+
         verify(rescuePartyObserver).executeBootLoopMitigation(5);
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(6);
         verify(rollbackObserver, never()).executeBootLoopMitigation(2);
 
-        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) {
-            watchdog.noteBoot();
-        }
+        watchdog.noteBoot();
+
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(6);
         verify(rollbackObserver).executeBootLoopMitigation(2);
         verify(rollbackObserver, never()).executeBootLoopMitigation(3);
         // Update the list of available rollbacks after executing bootloop mitigation
         when(mRollbackManager.getAvailableRollbacks()).thenReturn(List.of(ROLLBACK_INFO_MANUAL));
 
-        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; i++) {
-            watchdog.noteBoot();
-        }
+        watchdog.noteBoot();
+
         verify(rescuePartyObserver).executeBootLoopMitigation(6);
         verify(rescuePartyObserver, never()).executeBootLoopMitigation(7);
         verify(rollbackObserver, never()).executeBootLoopMitigation(3);
+
+        moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1);
+        Mockito.reset(rescuePartyObserver);
+
+        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT; i++) {
+            watchdog.noteBoot();
+        }
+        verify(rescuePartyObserver).executeBootLoopMitigation(1);
+        verify(rescuePartyObserver, never()).executeBootLoopMitigation(2);
     }
 
     RollbackPackageHealthObserver setUpRollbackPackageHealthObserver(PackageWatchdog watchdog) {
@@ -506,16 +494,9 @@
         }
 
         try {
-            if (Flags.recoverabilityDetection()) {
-                mSpyBootThreshold = spy(watchdog.new BootThreshold(
-                    PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT,
-                    PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS,
-                    PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT));
-            } else {
-                mSpyBootThreshold = spy(watchdog.new BootThreshold(
+            mSpyBootThreshold = spy(watchdog.new BootThreshold(
                     PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT,
                     PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS));
-            }
 
             doAnswer((Answer<Integer>) invocationOnMock -> {
                 String storedValue = mCrashRecoveryPropertiesMap
@@ -640,5 +621,16 @@
         public long uptimeMillis() {
             return mUpTimeMillis;
         }
+        public void moveTimeForward(long milliSeconds) {
+            mUpTimeMillis += milliSeconds;
+        }
+    }
+
+    private void moveTimeForwardAndDispatch(long milliSeconds) {
+        // Exhaust all due runnables now which shouldn't be executed after time-leap
+        mTestLooper.dispatchAll();
+        mTestClock.moveTimeForward(milliSeconds);
+        mTestLooper.moveTimeForward(milliSeconds);
+        mTestLooper.dispatchAll();
     }
 }
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 4f27e06..093923f 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -45,13 +45,13 @@
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.provider.DeviceConfig;
 import android.util.AtomicFile;
+import android.util.LongArrayQueue;
 import android.util.Xml;
-import android.utils.LongArrayQueue;
-import android.utils.XmlUtils;
 
 import androidx.test.InstrumentationRegistry;
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.internal.util.XmlUtils;
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
 import com.android.server.PackageWatchdog.HealthCheckState;
@@ -1224,7 +1224,7 @@
         PackageWatchdog watchdog = createWatchdog();
         TestObserver bootObserver = new TestObserver(OBSERVER_NAME_1);
         watchdog.registerHealthObserver(bootObserver);
-        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD; i++) {
+        for (int i = 0; i < 15; i++) {
             watchdog.noteBoot();
         }
         assertThat(bootObserver.mitigatedBootLoop()).isTrue();
@@ -1262,22 +1262,6 @@
     }
 
     /**
-     * Ensure that boot loop mitigation is not done when the number of boots does not meet the
-     * threshold.
-     */
-    @Test
-    public void testBootLoopDetection_doesNotMeetThresholdRecoverabilityHighImpact() {
-        PackageWatchdog watchdog = createWatchdog();
-        TestObserver bootObserver = new TestObserver(OBSERVER_NAME_1,
-                PackageHealthObserverImpact.USER_IMPACT_LEVEL_80);
-        watchdog.registerHealthObserver(bootObserver);
-        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - 1; i++) {
-            watchdog.noteBoot();
-        }
-        assertThat(bootObserver.mitigatedBootLoop()).isFalse();
-    }
-
-    /**
      * Ensure that boot loop mitigation is done for the observer with the lowest user impact
      */
     @Test
@@ -1306,7 +1290,7 @@
         bootObserver2.setImpact(PackageHealthObserverImpact.USER_IMPACT_LEVEL_30);
         watchdog.registerHealthObserver(bootObserver1);
         watchdog.registerHealthObserver(bootObserver2);
-        for (int i = 0; i < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD; i++) {
+        for (int i = 0; i < 15; i++) {
             watchdog.noteBoot();
         }
         assertThat(bootObserver1.mitigatedBootLoop()).isTrue();
@@ -1349,9 +1333,7 @@
             watchdog.noteBoot();
         }
         for (int i = 0; i < 4; i++) {
-            for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; j++) {
                 watchdog.noteBoot();
-            }
         }
 
         moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1);
@@ -1360,38 +1342,7 @@
             watchdog.noteBoot();
         }
         for (int i = 0; i < 4; i++) {
-            for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; j++) {
                 watchdog.noteBoot();
-            }
-        }
-
-        assertThat(bootObserver.mBootMitigationCounts).isEqualTo(List.of(1, 2, 3, 4, 1, 2, 3, 4));
-    }
-
-    @Test
-    public void testMultipleBootLoopMitigationRecoverabilityHighImpact() {
-        PackageWatchdog watchdog = createWatchdog();
-        TestObserver bootObserver = new TestObserver(OBSERVER_NAME_1,
-                PackageHealthObserverImpact.USER_IMPACT_LEVEL_80);
-        watchdog.registerHealthObserver(bootObserver);
-        for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - 1; j++) {
-            watchdog.noteBoot();
-        }
-        for (int i = 0; i < 4; i++) {
-            for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; j++) {
-                watchdog.noteBoot();
-            }
-        }
-
-        moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS + 1);
-
-        for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_THRESHOLD - 1; j++) {
-            watchdog.noteBoot();
-        }
-        for (int i = 0; i < 4; i++) {
-            for (int j = 0; j < PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT; j++) {
-                watchdog.noteBoot();
-            }
         }
 
         assertThat(bootObserver.mBootMitigationCounts).isEqualTo(List.of(1, 2, 3, 4, 1, 2, 3, 4));
@@ -1642,8 +1593,7 @@
 
         mSpyBootThreshold = spy(watchdog.new BootThreshold(
                 PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT,
-                PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS,
-                PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT));
+                PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS));
 
         watchdog.saveAllObserversBootMitigationCountToMetadata(filePath);
 
@@ -1798,16 +1748,9 @@
         mCrashRecoveryPropertiesMap = new HashMap<>();
 
         try {
-            if (Flags.recoverabilityDetection()) {
-                mSpyBootThreshold = spy(watchdog.new BootThreshold(
-                    PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT,
-                    PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS,
-                    PackageWatchdog.DEFAULT_BOOT_LOOP_MITIGATION_INCREMENT));
-            } else {
-                mSpyBootThreshold = spy(watchdog.new BootThreshold(
+            mSpyBootThreshold = spy(watchdog.new BootThreshold(
                     PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_COUNT,
                     PackageWatchdog.DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS));
-            }
 
             doAnswer((Answer<Integer>) invocationOnMock -> {
                 String storedValue = mCrashRecoveryPropertiesMap
diff --git a/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/TelephonyUtilsTest.java b/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/TelephonyUtilsTest.java
index a62103e..7558332 100644
--- a/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/TelephonyUtilsTest.java
+++ b/tests/TelephonyCommonTests/src/com/android/internal/telephony/tests/TelephonyUtilsTest.java
@@ -16,10 +16,16 @@
 
 package com.android.internal.telephony.tests;
 
+import static android.telephony.NetworkRegistrationInfo.FIRST_SERVICE_TYPE;
+import static android.telephony.NetworkRegistrationInfo.LAST_SERVICE_TYPE;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.content.Context;
@@ -72,6 +78,22 @@
         // getSubscriptionUserHandle should be called if subID is active.
         verify(mSubscriptionManager, times(1)).getSubscriptionUserHandle(eq(activeSubId));
     }
+
+    @Test
+    public void testIsValidPlmn() {
+        assertTrue(TelephonyUtils.isValidPlmn("310260"));
+        assertTrue(TelephonyUtils.isValidPlmn("45006"));
+        assertFalse(TelephonyUtils.isValidPlmn("1234567"));
+        assertFalse(TelephonyUtils.isValidPlmn("1234"));
+    }
+
+    @Test
+    public void testIsValidService() {
+        assertTrue(TelephonyUtils.isValidService(FIRST_SERVICE_TYPE));
+        assertTrue(TelephonyUtils.isValidService(LAST_SERVICE_TYPE));
+        assertFalse(TelephonyUtils.isValidService(FIRST_SERVICE_TYPE - 1));
+        assertFalse(TelephonyUtils.isValidService(LAST_SERVICE_TYPE + 1));
+    }
 }
 
 
diff --git a/tests/UsbManagerTests/Android.bp b/tests/UsbManagerTests/Android.bp
index a16a7ea..f0bea3f 100644
--- a/tests/UsbManagerTests/Android.bp
+++ b/tests/UsbManagerTests/Android.bp
@@ -21,6 +21,7 @@
     // to get the below license kinds:
     //   SPDX-license-identifier-Apache-2.0
     default_applicable_licenses: ["frameworks_base_license"],
+    default_team: "trendy_team_android_usb",
 }
 
 android_test {
diff --git a/tests/UsbTests/Android.bp b/tests/UsbTests/Android.bp
index 92c2711..c012cce 100644
--- a/tests/UsbTests/Android.bp
+++ b/tests/UsbTests/Android.bp
@@ -21,6 +21,7 @@
     // to get the below license kinds:
     //   SPDX-license-identifier-Apache-2.0
     default_applicable_licenses: ["frameworks_base_license"],
+    default_team: "trendy_team_android_usb",
 }
 
 android_test {
@@ -36,6 +37,8 @@
         "services.usb",
         "truth",
         "UsbManagerTestLib",
+        "android.hardware.usb.flags-aconfig-java",
+        "flag-junit",
     ],
     jni_libs: [
         // Required for ExtendedMockito
diff --git a/tests/UsbTests/TEST_MAPPING b/tests/UsbTests/TEST_MAPPING
new file mode 100644
index 0000000..70134b8
--- /dev/null
+++ b/tests/UsbTests/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "postsubmit": [
+    {
+      "name": "UsbTests"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java b/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java
new file mode 100644
index 0000000..b506d74
--- /dev/null
+++ b/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.usb;
+
+import static android.hardware.usb.UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.hardware.usb.IUsbOperationInternal;
+import android.hardware.usb.flags.Flags;
+import android.os.RemoteException;
+import android.os.UserManager;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for {@link com.android.server.usb.UsbService}
+ */
+@RunWith(AndroidJUnit4.class)
+public class UsbServiceTest {
+
+    @Mock
+    private Context mContext;
+    @Mock
+    private UsbPortManager mUsbPortManager;
+    @Mock
+    private UsbAlsaManager mUsbAlsaManager;
+    @Mock
+    private UserManager mUserManager;
+    @Mock
+    private UsbSettingsManager mUsbSettingsManager;
+    @Mock
+    private IUsbOperationInternal mIUsbOperationInternal;
+
+    private static final String TEST_PORT_ID = "123";
+
+    private static final int TEST_TRANSACTION_ID = 1;
+
+    private static final int TEST_FIRST_CALLER_ID = 1000;
+
+    private static final int TEST_SECOND_CALLER_ID = 2000;
+
+    private UsbService mUsbService;
+
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mUsbService = new UsbService(mContext, mUsbPortManager, mUsbAlsaManager, mUserManager,
+                mUsbSettingsManager);
+    }
+
+    /**
+     * Verify enableUsbData successfully disables USB port without error
+     */
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_USB_DATA_SIGNAL_STAKING)
+    public void usbPort_SuccessfullyDisabled() {
+        boolean enableState = false;
+        when(mUsbPortManager.enableUsbData(TEST_PORT_ID, enableState, TEST_TRANSACTION_ID,
+                mIUsbOperationInternal, null)).thenReturn(true);
+
+        assertTrue(mUsbService.enableUsbDataInternal(TEST_PORT_ID, enableState,
+                TEST_TRANSACTION_ID, mIUsbOperationInternal, TEST_FIRST_CALLER_ID));
+
+        verify(mUsbPortManager, times(1)).enableUsbData(TEST_PORT_ID,
+                enableState, TEST_TRANSACTION_ID, mIUsbOperationInternal, null);
+        verifyZeroInteractions(mIUsbOperationInternal);
+    }
+
+    /**
+     * Verify enableUsbData successfully enables USB port without error given no other stakers
+     */
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_USB_DATA_SIGNAL_STAKING)
+    public void usbPortWhenNoOtherStakers_SuccessfullyEnabledUsb() {
+        boolean enableState = true;
+        when(mUsbPortManager.enableUsbData(TEST_PORT_ID, enableState, TEST_TRANSACTION_ID,
+                mIUsbOperationInternal, null))
+                .thenReturn(true);
+
+        assertTrue(mUsbService.enableUsbDataInternal(TEST_PORT_ID, enableState,
+                TEST_TRANSACTION_ID, mIUsbOperationInternal, TEST_FIRST_CALLER_ID));
+        verifyZeroInteractions(mIUsbOperationInternal);
+    }
+
+    /**
+     * Verify enableUsbData does not enable USB port if other stakers are present
+     */
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_USB_DATA_SIGNAL_STAKING)
+    public void usbPortWithOtherStakers_DoesNotToEnableUsb() throws RemoteException {
+        mUsbService.enableUsbDataInternal(TEST_PORT_ID, false, TEST_TRANSACTION_ID,
+                mIUsbOperationInternal, TEST_FIRST_CALLER_ID);
+        clearInvocations(mUsbPortManager);
+
+        assertFalse(mUsbService.enableUsbDataInternal(TEST_PORT_ID, true,
+                TEST_TRANSACTION_ID, mIUsbOperationInternal, TEST_SECOND_CALLER_ID));
+
+        verifyZeroInteractions(mUsbPortManager);
+        verify(mIUsbOperationInternal).onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+    }
+
+    /**
+     * Verify enableUsbDataWhileDockedInternal does not enable USB port if other stakers are present
+     */
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_USB_DATA_SIGNAL_STAKING)
+    public void enableUsbWhileDockedWhenThereAreOtherStakers_DoesNotEnableUsb()
+            throws RemoteException {
+        mUsbService.enableUsbDataInternal(TEST_PORT_ID, false, TEST_TRANSACTION_ID,
+                mIUsbOperationInternal, TEST_FIRST_CALLER_ID);
+
+        mUsbService.enableUsbDataWhileDockedInternal(TEST_PORT_ID, 0,
+                mIUsbOperationInternal, TEST_SECOND_CALLER_ID);
+
+        verify(mUsbPortManager, never()).enableUsbDataWhileDocked(any(),
+                anyLong(), any(), any());
+        verify(mIUsbOperationInternal).onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+    }
+
+    /**
+     * Verify enableUsbDataWhileDockedInternal does  enable USB port if other stakers are
+     * not present
+     */
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_ENABLE_USB_DATA_SIGNAL_STAKING)
+    public void enableUsbWhileDockedWhenThereAreNoStakers_SuccessfullyEnableUsb()
+            throws RemoteException {
+        mUsbService.enableUsbDataWhileDockedInternal(TEST_PORT_ID, TEST_TRANSACTION_ID,
+                mIUsbOperationInternal, TEST_SECOND_CALLER_ID);
+
+        verify(mUsbPortManager, times(1))
+                .enableUsbDataWhileDocked(TEST_PORT_ID, TEST_TRANSACTION_ID,
+                        mIUsbOperationInternal, null);
+        verifyZeroInteractions(mIUsbOperationInternal);
+    }
+}
diff --git a/tools/app_metadata_bundles/Android.bp b/tools/app_metadata_bundles/Android.bp
index be6bea6..dced50d 100644
--- a/tools/app_metadata_bundles/Android.bp
+++ b/tools/app_metadata_bundles/Android.bp
@@ -5,6 +5,7 @@
     // to get the below license kinds:
     //   SPDX-license-identifier-Apache-2.0
     default_applicable_licenses: ["frameworks_base_license"],
+    default_team: "trendy_team_preload_safety",
 }
 
 java_library_host {
@@ -12,6 +13,9 @@
     srcs: [
         "src/lib/java/**/*.java",
     ],
+    static_libs: [
+        "guava",
+    ],
 }
 
 java_binary_host {
@@ -24,3 +28,15 @@
         "asllib",
     ],
 }
+
+java_test_host {
+    name: "aslgen-test",
+    srcs: ["src/test/java/**/*.java"],
+    exclude_srcs: [
+    ],
+    java_resource_dirs: ["src/test/resources"],
+    static_libs: [
+        "aslgen",
+        "junit",
+    ],
+}
diff --git a/tools/app_metadata_bundles/src/aslgen/java/com/android/aslgen/Main.java b/tools/app_metadata_bundles/src/aslgen/java/com/android/aslgen/Main.java
index fb7a6ab..d7edfd4 100644
--- a/tools/app_metadata_bundles/src/aslgen/java/com/android/aslgen/Main.java
+++ b/tools/app_metadata_bundles/src/aslgen/java/com/android/aslgen/Main.java
@@ -16,8 +16,8 @@
 
 package com.android.aslgen;
 
-import com.android.asllib.AndroidSafetyLabel;
-import com.android.asllib.AndroidSafetyLabel.Format;
+import com.android.asllib.AslConverter;
+import com.android.asllib.AslConverter.Format;
 import com.android.asllib.util.MalformedXmlException;
 
 import org.xml.sax.SAXException;
@@ -41,9 +41,8 @@
 
         String inFile = null;
         String outFile = null;
-        Format inFormat = Format.NULL;
-        Format outFormat = Format.NULL;
-
+        Format inFormat = AslConverter.Format.NULL;
+        Format outFormat = AslConverter.Format.NULL;
 
         // Except for "--help", all arguments require a value currently.
         // So just make sure we have an even number and
@@ -79,11 +78,11 @@
             throw new IllegalArgumentException("output file is required");
         }
 
-        if (inFormat == Format.NULL) {
+        if (inFormat == AslConverter.Format.NULL) {
             throw new IllegalArgumentException("input format is required");
         }
 
-        if (outFormat == Format.NULL) {
+        if (outFormat == AslConverter.Format.NULL) {
             throw new IllegalArgumentException("output format is required");
         }
 
@@ -92,24 +91,23 @@
         System.out.println("in format: " + inFormat);
         System.out.println("out format: " + outFormat);
 
-        var asl = AndroidSafetyLabel.readFromStream(new FileInputStream(inFile), inFormat);
-        asl.writeToStream(new FileOutputStream(outFile), outFormat);
+        var asl = AslConverter.readFromStream(new FileInputStream(inFile), inFormat);
+        AslConverter.writeToStream(new FileOutputStream(outFile), asl, outFormat);
     }
 
     private static Format getFormat(String argValue) {
         if ("hr".equals(argValue)) {
-            return Format.HUMAN_READABLE;
+            return AslConverter.Format.HUMAN_READABLE;
         } else if ("od".equals(argValue)) {
-            return Format.ON_DEVICE;
+            return AslConverter.Format.ON_DEVICE;
         } else {
-            return Format.NULL;
+            return AslConverter.Format.NULL;
         }
     }
 
     private static void showUsage() {
-        AndroidSafetyLabel.test();
         System.err.println(
-                "Usage:\n"
-        );
+                "Usage: aslgen --in-path [input-file] --out-path [output-file] --in-format [hr|od]"
+                        + " --out-format [hr|od]");
     }
 }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AndroidSafetyLabelFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AndroidSafetyLabelFactory.java
deleted file mode 100644
index 7e7fcf9..0000000
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AndroidSafetyLabelFactory.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.asllib;
-
-import com.android.asllib.util.MalformedXmlException;
-
-import org.w3c.dom.Element;
-
-import java.util.List;
-
-public class AndroidSafetyLabelFactory implements AslMarshallableFactory<AndroidSafetyLabel> {
-
-    /** Creates an {@link AndroidSafetyLabel} from human-readable DOM element */
-    @Override
-    public AndroidSafetyLabel createFromHrElements(List<Element> appMetadataBundles)
-            throws MalformedXmlException {
-        Element appMetadataBundlesEle = XmlUtils.getSingleElement(appMetadataBundles);
-        Element safetyLabelsEle =
-                XmlUtils.getSingleChildElement(
-                        appMetadataBundlesEle, XmlUtils.HR_TAG_SAFETY_LABELS);
-        SafetyLabels safetyLabels =
-                new SafetyLabelsFactory().createFromHrElements(List.of(safetyLabelsEle));
-        return new AndroidSafetyLabel(safetyLabels);
-    }
-}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AndroidSafetyLabel.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslConverter.java
similarity index 72%
rename from tools/app_metadata_bundles/src/lib/java/com/android/asllib/AndroidSafetyLabel.java
rename to tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslConverter.java
index bc8063e..c1c520e 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AndroidSafetyLabel.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslConverter.java
@@ -16,16 +16,21 @@
 
 package com.android.asllib;
 
+import com.android.asllib.marshallable.AndroidSafetyLabel;
+import com.android.asllib.marshallable.AndroidSafetyLabelFactory;
 import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.xml.sax.SAXException;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.List;
+import java.nio.charset.StandardCharsets;
 
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
@@ -36,20 +41,11 @@
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
-public class AndroidSafetyLabel implements AslMarshallable {
-
+public class AslConverter {
     public enum Format {
-        NULL, HUMAN_READABLE, ON_DEVICE;
-    }
-
-    private final SafetyLabels mSafetyLabels;
-
-    public SafetyLabels getSafetyLabels() {
-        return mSafetyLabels;
-    }
-
-    public AndroidSafetyLabel(SafetyLabels safetyLabels) {
-        this.mSafetyLabels = safetyLabels;
+        NULL,
+        HUMAN_READABLE,
+        ON_DEVICE;
     }
 
     /** Reads a {@link AndroidSafetyLabel} from an {@link InputStream}. */
@@ -66,10 +62,7 @@
                         XmlUtils.getSingleElement(document, XmlUtils.HR_TAG_APP_METADATA_BUNDLES);
 
                 return new AndroidSafetyLabelFactory()
-                        .createFromHrElements(
-                                List.of(
-                                        XmlUtils.getSingleElement(
-                                                document, XmlUtils.HR_TAG_APP_METADATA_BUNDLES)));
+                        .createFromHrElements(XmlUtils.listOf(appMetadataBundles));
             case ON_DEVICE:
                 throw new IllegalArgumentException(
                         "Parsing from on-device format is not supported at this time.");
@@ -78,9 +71,17 @@
         }
     }
 
+    /** Reads a {@link AndroidSafetyLabel} from a String. */
+    public static AndroidSafetyLabel readFromString(String in, Format format)
+            throws IOException, ParserConfigurationException, SAXException, MalformedXmlException {
+        InputStream stream = new ByteArrayInputStream(in.getBytes(StandardCharsets.UTF_8));
+        return readFromStream(stream, format);
+    }
+
     /** Write the content of the {@link AndroidSafetyLabel} to a {@link OutputStream}. */
     // TODO(b/329902686): Support outputting human-readable format.
-    public void writeToStream(OutputStream out, Format format)
+    public static void writeToStream(
+            OutputStream out, AndroidSafetyLabel asl, AslConverter.Format format)
             throws IOException, ParserConfigurationException, TransformerException {
         var docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
         var document = docBuilder.newDocument();
@@ -90,7 +91,7 @@
                 throw new IllegalArgumentException(
                         "Outputting human-readable format is not supported at this time.");
             case ON_DEVICE:
-                for (var child : this.toOdDomElements(document)) {
+                for (var child : asl.toOdDomElements(document)) {
                     document.appendChild(child);
                 }
                 break;
@@ -108,15 +109,11 @@
         transformer.transform(domSource, streamResult);
     }
 
-    /** Creates an on-device DOM element from an {@link AndroidSafetyLabel} */
-    @Override
-    public List<Element> toOdDomElements(Document doc) {
-        Element aslEle = doc.createElement(XmlUtils.OD_TAG_BUNDLE);
-        XmlUtils.appendChildren(aslEle, mSafetyLabels.toOdDomElements(doc));
-        return List.of(aslEle);
-    }
-
-    public static void test() {
-        // TODO(b/329902686): Add tests.
+    /** Get the content of the {@link AndroidSafetyLabel} as String. */
+    public static String getXmlAsString(AndroidSafetyLabel asl, AslConverter.Format format)
+            throws IOException, ParserConfigurationException, TransformerException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        writeToStream(out, asl, format);
+        return out.toString(StandardCharsets.UTF_8);
     }
 }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataCategoryFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataCategoryFactory.java
deleted file mode 100644
index d946345..0000000
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataCategoryFactory.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.asllib;
-
-import com.android.asllib.util.MalformedXmlException;
-
-import org.w3c.dom.Element;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class DataCategoryFactory implements AslMarshallableFactory<DataCategory> {
-    @Override
-    public DataCategory createFromHrElements(List<Element> elements) throws MalformedXmlException {
-        String categoryName = null;
-        Map<String, DataType> dataTypeMap = new HashMap<String, DataType>();
-        for (Element ele : elements) {
-            categoryName = ele.getAttribute(XmlUtils.HR_ATTR_DATA_CATEGORY);
-            String dataTypeName = ele.getAttribute(XmlUtils.HR_ATTR_DATA_TYPE);
-            if (!DataTypeConstants.getValidDataTypes().contains(dataTypeName)) {
-                throw new MalformedXmlException(
-                        String.format("Unrecognized data type name: %s", dataTypeName));
-            }
-            dataTypeMap.put(dataTypeName, new DataTypeFactory().createFromHrElements(List.of(ele)));
-        }
-
-        return new DataCategory(categoryName, dataTypeMap);
-    }
-}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataTypeConstants.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataTypeConstants.java
deleted file mode 100644
index a0a7537..0000000
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataTypeConstants.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * 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.asllib;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Constants for determining valid {@link String} data types for usage within {@link SafetyLabels},
- * {@link DataCategory}, and {@link DataType}
- */
-public class DataTypeConstants {
-    /** Data types for {@link DataCategoryConstants.CATEGORY_PERSONAL} */
-    public static final String TYPE_NAME = "name";
-
-    public static final String TYPE_EMAIL_ADDRESS = "email_address";
-    public static final String TYPE_PHONE_NUMBER = "phone_number";
-    public static final String TYPE_RACE_ETHNICITY = "race_ethnicity";
-    public static final String TYPE_POLITICAL_OR_RELIGIOUS_BELIEFS =
-            "political_or_religious_beliefs";
-    public static final String TYPE_SEXUAL_ORIENTATION_OR_GENDER_IDENTITY =
-            "sexual_orientation_or_gender_identity";
-    public static final String TYPE_PERSONAL_IDENTIFIERS = "personal_identifiers";
-    public static final String TYPE_OTHER = "other";
-
-    /** Data types for {@link DataCategoryConstants.CATEGORY_FINANCIAL} */
-    public static final String TYPE_CARD_BANK_ACCOUNT = "card_bank_account";
-
-    public static final String TYPE_PURCHASE_HISTORY = "purchase_history";
-    public static final String TYPE_CREDIT_SCORE = "credit_score";
-    public static final String TYPE_FINANCIAL_OTHER = "other";
-
-    /** Data types for {@link DataCategoryConstants.CATEGORY_LOCATION} */
-    public static final String TYPE_APPROX_LOCATION = "approx_location";
-
-    public static final String TYPE_PRECISE_LOCATION = "precise_location";
-
-    /** Data types for {@link DataCategoryConstants.CATEGORY_EMAIL_TEXT_MESSAGE} */
-    public static final String TYPE_EMAILS = "emails";
-
-    public static final String TYPE_TEXT_MESSAGES = "text_messages";
-    public static final String TYPE_EMAIL_TEXT_MESSAGE_OTHER = "other";
-
-    /** Data types for {@link DataCategoryConstants.CATEGORY_PHOTO_VIDEO} */
-    public static final String TYPE_PHOTOS = "photos";
-
-    public static final String TYPE_VIDEOS = "videos";
-
-    /** Data types for {@link DataCategoryConstants.CATEGORY_AUDIO} */
-    public static final String TYPE_SOUND_RECORDINGS = "sound_recordings";
-
-    public static final String TYPE_MUSIC_FILES = "music_files";
-    public static final String TYPE_AUDIO_OTHER = "other";
-
-    /** Data types for {@link DataCategoryConstants.CATEGORY_STORAGE} */
-    public static final String TYPE_FILES_DOCS = "files_docs";
-
-    /** Data types for {@link DataCategoryConstants.CATEGORY_HEALTH_FITNESS} */
-    public static final String TYPE_HEALTH = "health";
-
-    public static final String TYPE_FITNESS = "fitness";
-
-    /** Data types for {@link DataCategoryConstants.CATEGORY_CONTACTS} */
-    public static final String TYPE_CONTACTS = "contacts";
-
-    /** Data types for {@link DataCategoryConstants.CATEGORY_CALENDAR} */
-    public static final String TYPE_CALENDAR = "calendar";
-
-    /** Data types for {@link DataCategoryConstants.CATEGORY_IDENTIFIERS} */
-    public static final String TYPE_IDENTIFIERS_OTHER = "other";
-
-    /** Data types for {@link DataCategoryConstants.CATEGORY_APP_PERFORMANCE} */
-    public static final String TYPE_CRASH_LOGS = "crash_logs";
-
-    public static final String TYPE_PERFORMANCE_DIAGNOSTICS = "performance_diagnostics";
-    public static final String TYPE_APP_PERFORMANCE_OTHER = "other";
-
-    /** Data types for {@link DataCategoryConstants.CATEGORY_ACTIONS_IN_APP} */
-    public static final String TYPE_USER_INTERACTION = "user_interaction";
-
-    public static final String TYPE_IN_APP_SEARCH_HISTORY = "in_app_search_history";
-    public static final String TYPE_INSTALLED_APPS = "installed_apps";
-    public static final String TYPE_USER_GENERATED_CONTENT = "user_generated_content";
-    public static final String TYPE_ACTIONS_IN_APP_OTHER = "other";
-
-    /** Data types for {@link DataCategoryConstants.CATEGORY_SEARCH_AND_BROWSING} */
-    public static final String TYPE_WEB_BROWSING_HISTORY = "web_browsing_history";
-
-    /** Set of valid categories */
-    public static final Set<String> VALID_TYPES =
-            Collections.unmodifiableSet(
-                    new HashSet<>(
-                            Arrays.asList(
-                                    TYPE_NAME,
-                                    TYPE_EMAIL_ADDRESS,
-                                    TYPE_PHONE_NUMBER,
-                                    TYPE_RACE_ETHNICITY,
-                                    TYPE_POLITICAL_OR_RELIGIOUS_BELIEFS,
-                                    TYPE_SEXUAL_ORIENTATION_OR_GENDER_IDENTITY,
-                                    TYPE_PERSONAL_IDENTIFIERS,
-                                    TYPE_OTHER,
-                                    TYPE_CARD_BANK_ACCOUNT,
-                                    TYPE_PURCHASE_HISTORY,
-                                    TYPE_CREDIT_SCORE,
-                                    TYPE_FINANCIAL_OTHER,
-                                    TYPE_APPROX_LOCATION,
-                                    TYPE_PRECISE_LOCATION,
-                                    TYPE_EMAILS,
-                                    TYPE_TEXT_MESSAGES,
-                                    TYPE_EMAIL_TEXT_MESSAGE_OTHER,
-                                    TYPE_PHOTOS,
-                                    TYPE_VIDEOS,
-                                    TYPE_SOUND_RECORDINGS,
-                                    TYPE_MUSIC_FILES,
-                                    TYPE_AUDIO_OTHER,
-                                    TYPE_FILES_DOCS,
-                                    TYPE_HEALTH,
-                                    TYPE_FITNESS,
-                                    TYPE_CONTACTS,
-                                    TYPE_CALENDAR,
-                                    TYPE_IDENTIFIERS_OTHER,
-                                    TYPE_CRASH_LOGS,
-                                    TYPE_PERFORMANCE_DIAGNOSTICS,
-                                    TYPE_APP_PERFORMANCE_OTHER,
-                                    TYPE_USER_INTERACTION,
-                                    TYPE_IN_APP_SEARCH_HISTORY,
-                                    TYPE_INSTALLED_APPS,
-                                    TYPE_USER_GENERATED_CONTENT,
-                                    TYPE_ACTIONS_IN_APP_OTHER,
-                                    TYPE_WEB_BROWSING_HISTORY)));
-
-    /** Returns {@link Set} of valid {@link String} category keys */
-    public static Set<String> getValidDataTypes() {
-        return VALID_TYPES;
-    }
-
-    private DataTypeConstants() {
-        /* do nothing - hide constructor */
-    }
-}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataTypeFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataTypeFactory.java
deleted file mode 100644
index e3d1587..0000000
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataTypeFactory.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.asllib;
-
-import org.w3c.dom.Element;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-public class DataTypeFactory implements AslMarshallableFactory<DataType> {
-    /** Creates a {@link DataType} from the human-readable DOM element. */
-    @Override
-    public DataType createFromHrElements(List<Element> elements) {
-        Element hrDataTypeEle = XmlUtils.getSingleElement(elements);
-        String dataTypeName = hrDataTypeEle.getAttribute(XmlUtils.HR_ATTR_DATA_TYPE);
-        Set<DataType.Purpose> purposeSet =
-                Arrays.stream(hrDataTypeEle.getAttribute(XmlUtils.HR_ATTR_PURPOSES).split("\\|"))
-                        .map(DataType.Purpose::forString)
-                        .collect(Collectors.toUnmodifiableSet());
-        Boolean isCollectionOptional =
-                XmlUtils.fromString(
-                        hrDataTypeEle.getAttribute(XmlUtils.HR_ATTR_IS_COLLECTION_OPTIONAL));
-        Boolean isSharingOptional =
-                XmlUtils.fromString(
-                        hrDataTypeEle.getAttribute(XmlUtils.HR_ATTR_IS_SHARING_OPTIONAL));
-        Boolean ephemeral =
-                XmlUtils.fromString(hrDataTypeEle.getAttribute(XmlUtils.HR_ATTR_EPHEMERAL));
-        return new DataType(
-                dataTypeName, purposeSet, isCollectionOptional, isSharingOptional, ephemeral);
-    }
-}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/XmlUtils.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/XmlUtils.java
deleted file mode 100644
index 3bc9ccc..0000000
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/XmlUtils.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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.asllib;
-
-import com.android.asllib.util.MalformedXmlException;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class XmlUtils {
-    public static final String HR_TAG_APP_METADATA_BUNDLES = "app-metadata-bundles";
-    public static final String HR_TAG_SAFETY_LABELS = "safety-labels";
-    public static final String HR_TAG_DATA_LABELS = "data-labels";
-    public static final String HR_TAG_DATA_ACCESSED = "data-accessed";
-    public static final String HR_TAG_DATA_COLLECTED = "data-collected";
-    public static final String HR_TAG_DATA_SHARED = "data-shared";
-
-    public static final String HR_ATTR_DATA_CATEGORY = "dataCategory";
-    public static final String HR_ATTR_DATA_TYPE = "dataType";
-    public static final String HR_ATTR_IS_COLLECTION_OPTIONAL = "isCollectionOptional";
-    public static final String HR_ATTR_IS_SHARING_OPTIONAL = "isSharingOptional";
-    public static final String HR_ATTR_EPHEMERAL = "ephemeral";
-    public static final String HR_ATTR_PURPOSES = "purposes";
-    public static final String HR_ATTR_VERSION = "version";
-
-    public static final String OD_TAG_BUNDLE = "bundle";
-    public static final String OD_TAG_PBUNDLE_AS_MAP = "pbundle_as_map";
-    public static final String OD_TAG_BOOLEAN = "boolean";
-    public static final String OD_TAG_INT_ARRAY = "int-array";
-    public static final String OD_TAG_ITEM = "item";
-    public static final String OD_ATTR_NAME = "name";
-    public static final String OD_ATTR_VALUE = "value";
-    public static final String OD_ATTR_NUM = "num";
-    public static final String OD_NAME_SAFETY_LABELS = "safety_labels";
-    public static final String OD_NAME_DATA_LABELS = "data_labels";
-    public static final String OD_NAME_DATA_ACCESSED = "data_accessed";
-    public static final String OD_NAME_DATA_COLLECTED = "data_collected";
-    public static final String OD_NAME_DATA_SHARED = "data_shared";
-    public static final String OD_NAME_PURPOSES = "purposes";
-    public static final String OD_NAME_IS_COLLECTION_OPTIONAL = "is_collection_optional";
-    public static final String OD_NAME_IS_SHARING_OPTIONAL = "is_sharing_optional";
-    public static final String OD_NAME_EPHEMERAL = "ephemeral";
-
-    public static final String TRUE_STR = "true";
-    public static final String FALSE_STR = "false";
-
-    /** Gets the single top-level {@link Element} having the {@param tagName}. */
-    public static Element getSingleElement(Document doc, String tagName)
-            throws MalformedXmlException {
-        var elements = doc.getElementsByTagName(tagName);
-        return getSingleElement(elements, tagName);
-    }
-
-    /**
-     * Gets the single {@link Element} within {@param parentEle} and having the {@param tagName}.
-     */
-    public static Element getSingleChildElement(Element parentEle, String tagName)
-            throws MalformedXmlException {
-        var elements = parentEle.getElementsByTagName(tagName);
-        return getSingleElement(elements, tagName);
-    }
-
-    /** Gets the single {@link Element} from {@param elements} */
-    public static Element getSingleElement(NodeList elements, String tagName)
-            throws MalformedXmlException {
-        if (elements.getLength() != 1) {
-            throw new MalformedXmlException(
-                    String.format(
-                            "Expected 1 element \"%s\" in NodeList but got %s.",
-                            tagName, elements.getLength()));
-        }
-        var elementAsNode = elements.item(0);
-        if (!(elementAsNode instanceof Element)) {
-            throw new MalformedXmlException(
-                    String.format("%s was not a valid XML element.", tagName));
-        }
-        return ((Element) elementAsNode);
-    }
-
-    /** Gets the single {@link Element} within {@param elements}. */
-    public static Element getSingleElement(List<Element> elements) {
-        if (elements.size() != 1) {
-            throw new IllegalStateException(
-                    String.format("Expected 1 element in list but got %s.", elements.size()));
-        }
-        return elements.get(0);
-    }
-
-    /** Converts {@param nodeList} into List of {@link Element}. */
-    public static List<Element> asElementList(NodeList nodeList) {
-        List<Element> elementList = new ArrayList<Element>();
-        for (int i = 0; i < nodeList.getLength(); i++) {
-            var elementAsNode = nodeList.item(0);
-            if (elementAsNode instanceof Element) {
-                elementList.add(((Element) elementAsNode));
-            }
-        }
-        return elementList;
-    }
-
-    /** Appends {@param children} to the {@param ele}. */
-    public static void appendChildren(Element ele, List<Element> children) {
-        for (Element c : children) {
-            ele.appendChild(c);
-        }
-    }
-
-    /** Gets the Boolean from the String value. */
-    public static Boolean fromString(String s) {
-        if (s == null) {
-            return null;
-        }
-        if (s.equals(TRUE_STR)) {
-            return true;
-        } else if (s.equals(FALSE_STR)) {
-            return false;
-        }
-        return null;
-    }
-
-    /** Creates an on-device PBundle DOM Element with the given attribute name. */
-    public static Element createPbundleEleWithName(Document doc, String name) {
-        var ele = doc.createElement(XmlUtils.OD_TAG_PBUNDLE_AS_MAP);
-        ele.setAttribute(XmlUtils.OD_ATTR_NAME, name);
-        return ele;
-    }
-
-    /** Create an on-device Boolean DOM Element with the given attribute name. */
-    public static Element createOdBooleanEle(Document doc, String name, boolean b) {
-        var ele = doc.createElement(XmlUtils.OD_TAG_BOOLEAN);
-        ele.setAttribute(XmlUtils.OD_ATTR_NAME, name);
-        ele.setAttribute(XmlUtils.OD_ATTR_VALUE, String.valueOf(b));
-        return ele;
-    }
-
-    /** Returns whether the String is null or empty. */
-    public static boolean isNullOrEmpty(String s) {
-        return s == null || s.isEmpty();
-    }
-}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabel.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabel.java
new file mode 100644
index 0000000..112b92c
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabel.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib.marshallable;
+
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+public class AndroidSafetyLabel implements AslMarshallable {
+
+    private final Long mVersion;
+    private final SystemAppSafetyLabel mSystemAppSafetyLabel;
+    private final SafetyLabels mSafetyLabels;
+    private final TransparencyInfo mTransparencyInfo;
+
+    public SafetyLabels getSafetyLabels() {
+        return mSafetyLabels;
+    }
+
+    public AndroidSafetyLabel(
+            Long version,
+            SystemAppSafetyLabel systemAppSafetyLabel,
+            SafetyLabels safetyLabels,
+            TransparencyInfo transparencyInfo) {
+        this.mVersion = version;
+        this.mSystemAppSafetyLabel = systemAppSafetyLabel;
+        this.mSafetyLabels = safetyLabels;
+        this.mTransparencyInfo = transparencyInfo;
+    }
+
+    /** Creates an on-device DOM element from an {@link AndroidSafetyLabel} */
+    @Override
+    public List<Element> toOdDomElements(Document doc) {
+        Element aslEle = doc.createElement(XmlUtils.OD_TAG_BUNDLE);
+        aslEle.appendChild(XmlUtils.createOdLongEle(doc, XmlUtils.OD_NAME_VERSION, mVersion));
+        if (mSafetyLabels != null) {
+            XmlUtils.appendChildren(aslEle, mSafetyLabels.toOdDomElements(doc));
+        }
+        if (mSystemAppSafetyLabel != null) {
+            XmlUtils.appendChildren(aslEle, mSystemAppSafetyLabel.toOdDomElements(doc));
+        }
+        if (mTransparencyInfo != null) {
+            XmlUtils.appendChildren(aslEle, mTransparencyInfo.toOdDomElements(doc));
+        }
+        return XmlUtils.listOf(aslEle);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabelFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabelFactory.java
new file mode 100644
index 0000000..b69c30f
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AndroidSafetyLabelFactory.java
@@ -0,0 +1,58 @@
+/*
+ * 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.asllib.marshallable;
+
+import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+public class AndroidSafetyLabelFactory implements AslMarshallableFactory<AndroidSafetyLabel> {
+
+    /** Creates an {@link AndroidSafetyLabel} from human-readable DOM element */
+    @Override
+    public AndroidSafetyLabel createFromHrElements(List<Element> appMetadataBundles)
+            throws MalformedXmlException {
+        Element appMetadataBundlesEle = XmlUtils.getSingleElement(appMetadataBundles);
+        long version = XmlUtils.tryGetVersion(appMetadataBundlesEle);
+
+        Element safetyLabelsEle =
+                XmlUtils.getSingleChildElement(
+                        appMetadataBundlesEle, XmlUtils.HR_TAG_SAFETY_LABELS, false);
+        SafetyLabels safetyLabels =
+                new SafetyLabelsFactory().createFromHrElements(XmlUtils.listOf(safetyLabelsEle));
+
+        Element systemAppSafetyLabelEle =
+                XmlUtils.getSingleChildElement(
+                        appMetadataBundlesEle, XmlUtils.HR_TAG_SYSTEM_APP_SAFETY_LABEL, false);
+        SystemAppSafetyLabel systemAppSafetyLabel =
+                new SystemAppSafetyLabelFactory()
+                        .createFromHrElements(XmlUtils.listOf(systemAppSafetyLabelEle));
+
+        Element transparencyInfoEle =
+                XmlUtils.getSingleChildElement(
+                        appMetadataBundlesEle, XmlUtils.HR_TAG_TRANSPARENCY_INFO, false);
+        TransparencyInfo transparencyInfo =
+                new TransparencyInfoFactory()
+                        .createFromHrElements(XmlUtils.listOf(transparencyInfoEle));
+
+        return new AndroidSafetyLabel(
+                version, systemAppSafetyLabel, safetyLabels, transparencyInfo);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java
new file mode 100644
index 0000000..3f1ddeb
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfo.java
@@ -0,0 +1,145 @@
+/*
+ * 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.asllib.marshallable;
+
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+/** AppInfo representation */
+public class AppInfo implements AslMarshallable {
+    private final String mTitle;
+    private final String mDescription;
+    private final Boolean mContainsAds;
+    private final Boolean mObeyAps;
+    private final Boolean mAdsFingerprinting;
+    private final Boolean mSecurityFingerprinting;
+    private final String mPrivacyPolicy;
+    private final List<String> mSecurityEndpoints;
+    private final List<String> mFirstPartyEndpoints;
+    private final List<String> mServiceProviderEndpoints;
+    private final String mCategory;
+    private final String mEmail;
+    private final String mWebsite;
+
+    public AppInfo(
+            String title,
+            String description,
+            Boolean containsAds,
+            Boolean obeyAps,
+            Boolean adsFingerprinting,
+            Boolean securityFingerprinting,
+            String privacyPolicy,
+            List<String> securityEndpoints,
+            List<String> firstPartyEndpoints,
+            List<String> serviceProviderEndpoints,
+            String category,
+            String email,
+            String website) {
+        this.mTitle = title;
+        this.mDescription = description;
+        this.mContainsAds = containsAds;
+        this.mObeyAps = obeyAps;
+        this.mAdsFingerprinting = adsFingerprinting;
+        this.mSecurityFingerprinting = securityFingerprinting;
+        this.mPrivacyPolicy = privacyPolicy;
+        this.mSecurityEndpoints = securityEndpoints;
+        this.mFirstPartyEndpoints = firstPartyEndpoints;
+        this.mServiceProviderEndpoints = serviceProviderEndpoints;
+        this.mCategory = category;
+        this.mEmail = email;
+        this.mWebsite = website;
+    }
+
+    /** Creates an on-device DOM element from the {@link SafetyLabels}. */
+    @Override
+    public List<Element> toOdDomElements(Document doc) {
+        Element appInfoEle = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_APP_INFO);
+        if (this.mTitle != null) {
+            appInfoEle.appendChild(XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_TITLE, mTitle));
+        }
+        if (this.mDescription != null) {
+            appInfoEle.appendChild(
+                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_DESCRIPTION, mDescription));
+        }
+        if (this.mContainsAds != null) {
+            appInfoEle.appendChild(
+                    XmlUtils.createOdBooleanEle(doc, XmlUtils.OD_NAME_CONTAINS_ADS, mContainsAds));
+        }
+        if (this.mObeyAps != null) {
+            appInfoEle.appendChild(
+                    XmlUtils.createOdBooleanEle(doc, XmlUtils.OD_NAME_OBEY_APS, mObeyAps));
+        }
+        if (this.mAdsFingerprinting != null) {
+            appInfoEle.appendChild(
+                    XmlUtils.createOdBooleanEle(
+                            doc, XmlUtils.OD_NAME_ADS_FINGERPRINTING, mAdsFingerprinting));
+        }
+        if (this.mSecurityFingerprinting != null) {
+            appInfoEle.appendChild(
+                    XmlUtils.createOdBooleanEle(
+                            doc,
+                            XmlUtils.OD_NAME_SECURITY_FINGERPRINTING,
+                            mSecurityFingerprinting));
+        }
+        if (this.mPrivacyPolicy != null) {
+            appInfoEle.appendChild(
+                    XmlUtils.createOdStringEle(
+                            doc, XmlUtils.OD_NAME_PRIVACY_POLICY, mPrivacyPolicy));
+        }
+        if (this.mSecurityEndpoints != null) {
+            appInfoEle.appendChild(
+                    XmlUtils.createOdArray(
+                            doc,
+                            XmlUtils.OD_TAG_STRING_ARRAY,
+                            XmlUtils.OD_NAME_SECURITY_ENDPOINT,
+                            mSecurityEndpoints));
+        }
+        if (this.mFirstPartyEndpoints != null) {
+            appInfoEle.appendChild(
+                    XmlUtils.createOdArray(
+                            doc,
+                            XmlUtils.OD_TAG_STRING_ARRAY,
+                            XmlUtils.OD_NAME_FIRST_PARTY_ENDPOINT,
+                            mFirstPartyEndpoints));
+        }
+        if (this.mServiceProviderEndpoints != null) {
+            appInfoEle.appendChild(
+                    XmlUtils.createOdArray(
+                            doc,
+                            XmlUtils.OD_TAG_STRING_ARRAY,
+                            XmlUtils.OD_NAME_SERVICE_PROVIDER_ENDPOINT,
+                            mServiceProviderEndpoints));
+        }
+        if (this.mCategory != null) {
+            appInfoEle.appendChild(
+                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_CATEGORY, this.mCategory));
+        }
+        if (this.mEmail != null) {
+            appInfoEle.appendChild(
+                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_EMAIL, this.mEmail));
+        }
+        if (this.mWebsite != null) {
+            appInfoEle.appendChild(
+                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_WEBSITE, this.mWebsite));
+        }
+        return XmlUtils.listOf(appInfoEle);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java
new file mode 100644
index 0000000..59a437d
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AppInfoFactory.java
@@ -0,0 +1,75 @@
+/*
+ * 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.asllib.marshallable;
+
+import com.android.asllib.util.AslgenUtil;
+import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+public class AppInfoFactory implements AslMarshallableFactory<AppInfo> {
+
+    /** Creates a {@link AppInfo} from the human-readable DOM element. */
+    @Override
+    public AppInfo createFromHrElements(List<Element> elements) throws MalformedXmlException {
+        Element appInfoEle = XmlUtils.getSingleElement(elements);
+        if (appInfoEle == null) {
+            AslgenUtil.logI("No AppInfo found in hr format.");
+            return null;
+        }
+
+        String title = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_TITLE);
+        String description = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_DESCRIPTION);
+        Boolean containsAds = XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_CONTAINS_ADS, true);
+        Boolean obeyAps = XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_OBEY_APS, true);
+        Boolean adsFingerprinting =
+                XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_ADS_FINGERPRINTING, true);
+        Boolean securityFingerprinting =
+                XmlUtils.getBoolAttr(appInfoEle, XmlUtils.HR_ATTR_SECURITY_FINGERPRINTING, true);
+        String privacyPolicy = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_PRIVACY_POLICY);
+        List<String> securityEndpoints =
+                XmlUtils.getPipelineSplitAttr(
+                        appInfoEle, XmlUtils.HR_ATTR_SECURITY_ENDPOINTS, true);
+        List<String> firstPartyEndpoints =
+                XmlUtils.getPipelineSplitAttr(
+                        appInfoEle, XmlUtils.HR_ATTR_FIRST_PARTY_ENDPOINTS, true);
+        List<String> serviceProviderEndpoints =
+                XmlUtils.getPipelineSplitAttr(
+                        appInfoEle, XmlUtils.HR_ATTR_SERVICE_PROVIDER_ENDPOINTS, true);
+        String category = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_CATEGORY);
+        String email = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_EMAIL);
+        String website = XmlUtils.getStringAttr(appInfoEle, XmlUtils.HR_ATTR_WEBSITE, false);
+
+        return new AppInfo(
+                title,
+                description,
+                containsAds,
+                obeyAps,
+                adsFingerprinting,
+                securityFingerprinting,
+                privacyPolicy,
+                securityEndpoints,
+                firstPartyEndpoints,
+                serviceProviderEndpoints,
+                category,
+                email,
+                website);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallable.java
similarity index 95%
rename from tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
rename to tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallable.java
index 4e64ab0..48747cc 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallable.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallable.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.asllib.marshallable;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallableFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallableFactory.java
similarity index 95%
rename from tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallableFactory.java
rename to tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallableFactory.java
index b8f9f0e..a49b3e7 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/AslMarshallableFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/AslMarshallableFactory.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.asllib.marshallable;
 
 import com.android.asllib.util.MalformedXmlException;
 
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataCategory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategory.java
similarity index 88%
rename from tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataCategory.java
rename to tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategory.java
index e5ed63b..4d67162 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataCategory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategory.java
@@ -14,7 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.asllib.marshallable;
+
+import com.android.asllib.util.DataCategoryConstants;
+import com.android.asllib.util.DataTypeConstants;
+import com.android.asllib.util.XmlUtils;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -53,6 +57,6 @@
         for (DataType dataType : mDataTypes.values()) {
             XmlUtils.appendChildren(dataCategoryEle, dataType.toOdDomElements(doc));
         }
-        return List.of(dataCategoryEle);
+        return XmlUtils.listOf(dataCategoryEle);
     }
 }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategoryFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategoryFactory.java
new file mode 100644
index 0000000..37d99e7
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataCategoryFactory.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib.marshallable;
+
+import com.android.asllib.util.DataTypeConstants;
+import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Element;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class DataCategoryFactory implements AslMarshallableFactory<DataCategory> {
+    @Override
+    public DataCategory createFromHrElements(List<Element> elements) throws MalformedXmlException {
+        String categoryName = null;
+        Map<String, DataType> dataTypeMap = new LinkedHashMap<String, DataType>();
+        for (Element ele : elements) {
+            categoryName = XmlUtils.getStringAttr(ele, XmlUtils.HR_ATTR_DATA_CATEGORY, true);
+            String dataTypeName = XmlUtils.getStringAttr(ele, XmlUtils.HR_ATTR_DATA_TYPE, true);
+            if (!DataTypeConstants.getValidDataTypes().containsKey(categoryName)) {
+                throw new MalformedXmlException(
+                        String.format("Unrecognized data category %s", categoryName));
+            }
+            if (!DataTypeConstants.getValidDataTypes().get(categoryName).contains(dataTypeName)) {
+                throw new MalformedXmlException(
+                        String.format(
+                                "Unrecognized data type name %s for category %s",
+                                dataTypeName, categoryName));
+            }
+            dataTypeMap.put(
+                    dataTypeName, new DataTypeFactory().createFromHrElements(XmlUtils.listOf(ele)));
+        }
+
+        return new DataCategory(categoryName, dataTypeMap);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataLabels.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java
similarity index 83%
rename from tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataLabels.java
rename to tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java
index d2fffc0..7516faf 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataLabels.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabels.java
@@ -14,7 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.asllib.marshallable;
+
+import com.android.asllib.util.DataCategoryConstants;
+import com.android.asllib.util.XmlUtils;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -41,24 +44,23 @@
     }
 
     /**
-     * Returns the data accessed {@link Map} of {@link com.android.asllib.DataCategoryConstants} to
-     * {@link DataCategory}
+     * Returns the data accessed {@link Map} of {@link DataCategoryConstants} to {@link
+     * DataCategory}
      */
     public Map<String, DataCategory> getDataAccessed() {
         return mDataAccessed;
     }
 
     /**
-     * Returns the data collected {@link Map} of {@link com.android.asllib.DataCategoryConstants} to
-     * {@link DataCategory}
+     * Returns the data collected {@link Map} of {@link DataCategoryConstants} to {@link
+     * DataCategory}
      */
     public Map<String, DataCategory> getDataCollected() {
         return mDataCollected;
     }
 
     /**
-     * Returns the data shared {@link Map} of {@link com.android.asllib.DataCategoryConstants} to
-     * {@link DataCategory}
+     * Returns the data shared {@link Map} of {@link DataCategoryConstants} to {@link DataCategory}
      */
     public Map<String, DataCategory> getDataShared() {
         return mDataShared;
@@ -70,11 +72,11 @@
         Element dataLabelsEle =
                 XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_DATA_LABELS);
 
-        maybeAppendDataUsages(doc, dataLabelsEle, mDataCollected, XmlUtils.OD_NAME_DATA_ACCESSED);
+        maybeAppendDataUsages(doc, dataLabelsEle, mDataAccessed, XmlUtils.OD_NAME_DATA_ACCESSED);
         maybeAppendDataUsages(doc, dataLabelsEle, mDataCollected, XmlUtils.OD_NAME_DATA_COLLECTED);
         maybeAppendDataUsages(doc, dataLabelsEle, mDataShared, XmlUtils.OD_NAME_DATA_SHARED);
 
-        return List.of(dataLabelsEle);
+        return XmlUtils.listOf(dataLabelsEle);
     }
 
     private void maybeAppendDataUsages(
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataLabelsFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabelsFactory.java
similarity index 92%
rename from tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataLabelsFactory.java
rename to tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabelsFactory.java
index 1adb140..dc77fd0 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataLabelsFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataLabelsFactory.java
@@ -14,15 +14,18 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.asllib.marshallable;
 
+import com.android.asllib.util.AslgenUtil;
+import com.android.asllib.util.DataCategoryConstants;
 import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
 
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
-import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -33,6 +36,10 @@
     @Override
     public DataLabels createFromHrElements(List<Element> elements) throws MalformedXmlException {
         Element ele = XmlUtils.getSingleElement(elements);
+        if (ele == null) {
+            AslgenUtil.logI("Found no DataLabels in hr format.");
+            return null;
+        }
         Map<String, DataCategory> dataAccessed =
                 getDataCategoriesWithTag(ele, XmlUtils.HR_TAG_DATA_ACCESSED);
         Map<String, DataCategory> dataCollected =
@@ -88,7 +95,7 @@
     private static Map<String, DataCategory> getDataCategoriesWithTag(
             Element dataLabelsEle, String dataCategoryUsageTypeTag) throws MalformedXmlException {
         NodeList dataUsedNodeList = dataLabelsEle.getElementsByTagName(dataCategoryUsageTypeTag);
-        Map<String, DataCategory> dataCategoryMap = new HashMap<String, DataCategory>();
+        Map<String, DataCategory> dataCategoryMap = new LinkedHashMap<String, DataCategory>();
 
         Set<String> dataCategoryNames = new HashSet<String>();
         for (int i = 0; i < dataUsedNodeList.getLength(); i++) {
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataType.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java
similarity index 73%
rename from tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataType.java
rename to tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java
index 5ba2975..3471362 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataType.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataType.java
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.asllib.marshallable;
+
+import com.android.asllib.util.XmlUtils;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -29,15 +31,13 @@
 public class DataType implements AslMarshallable {
 
     public enum Purpose {
-        PURPOSE_APP_FUNCTIONALITY(1),
-        PURPOSE_ANALYTICS(2),
-        PURPOSE_DEVELOPER_COMMUNICATIONS(3),
-        PURPOSE_FRAUD_PREVENTION_SECURITY(4),
-        PURPOSE_ADVERTISING(5),
-        PURPOSE_PERSONALIZATION(6),
-        PURPOSE_ACCOUNT_MANAGEMENT(7);
-
-        private static final String PURPOSE_PREFIX = "PURPOSE_";
+        APP_FUNCTIONALITY(1),
+        ANALYTICS(2),
+        DEVELOPER_COMMUNICATIONS(3),
+        FRAUD_PREVENTION_SECURITY(4),
+        ADVERTISING(5),
+        PERSONALIZATION(6),
+        ACCOUNT_MANAGEMENT(7);
 
         private final int mValue;
 
@@ -57,7 +57,7 @@
                     return e;
                 }
             }
-            throw new IllegalArgumentException("No enum for value: " + value);
+            throw new IllegalArgumentException("No Purpose enum for value: " + value);
         }
 
         /** Get the Purpose associated with the human-readable String. */
@@ -67,33 +67,30 @@
                     return e;
                 }
             }
-            throw new IllegalArgumentException("No enum for str: " + s);
+            throw new IllegalArgumentException("No Purpose enum for str: " + s);
         }
 
         /** Human-readable String representation of Purpose. */
         public String toString() {
-            if (!this.name().startsWith(PURPOSE_PREFIX)) {
-                return this.name();
-            }
-            return this.name().substring(PURPOSE_PREFIX.length()).toLowerCase();
+            return this.name().toLowerCase();
         }
     }
 
     private final String mDataTypeName;
 
-    private final Set<Purpose> mPurposeSet;
+    private final List<Purpose> mPurposes;
     private final Boolean mIsCollectionOptional;
     private final Boolean mIsSharingOptional;
     private final Boolean mEphemeral;
 
     public DataType(
             String dataTypeName,
-            Set<Purpose> purposeSet,
+            List<Purpose> purposes,
             Boolean isCollectionOptional,
             Boolean isSharingOptional,
             Boolean ephemeral) {
         this.mDataTypeName = dataTypeName;
-        this.mPurposeSet = purposeSet;
+        this.mPurposes = purposes;
         this.mIsCollectionOptional = isCollectionOptional;
         this.mIsSharingOptional = isSharingOptional;
         this.mEphemeral = ephemeral;
@@ -107,8 +104,8 @@
      * Returns {@link Set} of valid {@link Integer} purposes for using the associated data category
      * and type
      */
-    public Set<Purpose> getPurposeSet() {
-        return mPurposeSet;
+    public List<Purpose> getPurposes() {
+        return mPurposes;
     }
 
     /**
@@ -138,17 +135,15 @@
     @Override
     public List<Element> toOdDomElements(Document doc) {
         Element dataTypeEle = XmlUtils.createPbundleEleWithName(doc, this.getDataTypeName());
-        if (!this.getPurposeSet().isEmpty()) {
-            Element purposesEle = doc.createElement(XmlUtils.OD_TAG_INT_ARRAY);
-            purposesEle.setAttribute(XmlUtils.OD_ATTR_NAME, XmlUtils.OD_NAME_PURPOSES);
-            purposesEle.setAttribute(
-                    XmlUtils.OD_ATTR_NUM, String.valueOf(this.getPurposeSet().size()));
-            for (DataType.Purpose purpose : this.getPurposeSet()) {
-                Element purposeEle = doc.createElement(XmlUtils.OD_TAG_ITEM);
-                purposeEle.setAttribute(XmlUtils.OD_ATTR_VALUE, String.valueOf(purpose.getValue()));
-                purposesEle.appendChild(purposeEle);
-            }
-            dataTypeEle.appendChild(purposesEle);
+        if (!this.getPurposes().isEmpty()) {
+            dataTypeEle.appendChild(
+                    XmlUtils.createOdArray(
+                            doc,
+                            XmlUtils.OD_TAG_INT_ARRAY,
+                            XmlUtils.OD_NAME_PURPOSES,
+                            this.getPurposes().stream()
+                                    .map(p -> String.valueOf(p.getValue()))
+                                    .toList()));
         }
 
         maybeAddBoolToOdElement(
@@ -162,7 +157,7 @@
                 this.getIsSharingOptional(),
                 XmlUtils.OD_NAME_IS_SHARING_OPTIONAL);
         maybeAddBoolToOdElement(doc, dataTypeEle, this.getEphemeral(), XmlUtils.OD_NAME_EPHEMERAL);
-        return List.of(dataTypeEle);
+        return XmlUtils.listOf(dataTypeEle);
     }
 
     private static void maybeAddBoolToOdElement(
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataTypeFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataTypeFactory.java
new file mode 100644
index 0000000..ed434cd
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DataTypeFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib.marshallable;
+
+import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Element;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class DataTypeFactory implements AslMarshallableFactory<DataType> {
+    /** Creates a {@link DataType} from the human-readable DOM element. */
+    @Override
+    public DataType createFromHrElements(List<Element> elements) throws MalformedXmlException {
+        Element hrDataTypeEle = XmlUtils.getSingleElement(elements);
+        String dataTypeName = hrDataTypeEle.getAttribute(XmlUtils.HR_ATTR_DATA_TYPE);
+        List<DataType.Purpose> purposes =
+                XmlUtils.getPipelineSplitAttr(hrDataTypeEle, XmlUtils.HR_ATTR_PURPOSES, true)
+                        .stream()
+                        .map(DataType.Purpose::forString)
+                        .collect(Collectors.toList());
+        if (purposes.isEmpty()) {
+            throw new MalformedXmlException(String.format("Found no purpose in: %s", dataTypeName));
+        }
+        if (new HashSet<>(purposes).size() != purposes.size()) {
+            throw new MalformedXmlException(
+                    String.format("Found non-unique purposes in: %s", dataTypeName));
+        }
+        Boolean isCollectionOptional =
+                XmlUtils.getBoolAttr(hrDataTypeEle, XmlUtils.HR_ATTR_IS_COLLECTION_OPTIONAL, false);
+        Boolean isSharingOptional =
+                XmlUtils.getBoolAttr(hrDataTypeEle, XmlUtils.HR_ATTR_IS_SHARING_OPTIONAL, false);
+        Boolean ephemeral = XmlUtils.getBoolAttr(hrDataTypeEle, XmlUtils.HR_ATTR_EPHEMERAL, false);
+        return new DataType(
+                dataTypeName, purposes, isCollectionOptional, isSharingOptional, ephemeral);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfo.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfo.java
new file mode 100644
index 0000000..382a1f0
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfo.java
@@ -0,0 +1,142 @@
+/*
+ * 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.asllib.marshallable;
+
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+/** DeveloperInfo representation */
+public class DeveloperInfo implements AslMarshallable {
+    public enum DeveloperRelationship {
+        OEM(0),
+        ODM(1),
+        SOC(2),
+        OTA(3),
+        CARRIER(4),
+        AOSP(5),
+        OTHER(6);
+
+        private final int mValue;
+
+        DeveloperRelationship(int value) {
+            this.mValue = value;
+        }
+
+        /** Get the int value associated with the DeveloperRelationship. */
+        public int getValue() {
+            return mValue;
+        }
+
+        /** Get the DeveloperRelationship associated with the int value. */
+        public static DeveloperInfo.DeveloperRelationship forValue(int value) {
+            for (DeveloperInfo.DeveloperRelationship e : values()) {
+                if (e.getValue() == value) {
+                    return e;
+                }
+            }
+            throw new IllegalArgumentException("No DeveloperRelationship enum for value: " + value);
+        }
+
+        /** Get the DeveloperRelationship associated with the human-readable String. */
+        public static DeveloperInfo.DeveloperRelationship forString(String s) {
+            for (DeveloperInfo.DeveloperRelationship e : values()) {
+                if (e.toString().equals(s)) {
+                    return e;
+                }
+            }
+            throw new IllegalArgumentException("No DeveloperRelationship enum for str: " + s);
+        }
+
+        /** Human-readable String representation of DeveloperRelationship. */
+        public String toString() {
+            return this.name().toLowerCase();
+        }
+    }
+
+    private final String mName;
+    private final String mEmail;
+    private final String mAddress;
+    private final String mCountryRegion;
+    private final DeveloperRelationship mDeveloperRelationship;
+    private final String mWebsite;
+    private final String mAppDeveloperRegistryId;
+
+    public DeveloperInfo(
+            String name,
+            String email,
+            String address,
+            String countryRegion,
+            DeveloperRelationship developerRelationship,
+            String website,
+            String appDeveloperRegistryId) {
+        this.mName = name;
+        this.mEmail = email;
+        this.mAddress = address;
+        this.mCountryRegion = countryRegion;
+        this.mDeveloperRelationship = developerRelationship;
+        this.mWebsite = website;
+        this.mAppDeveloperRegistryId = appDeveloperRegistryId;
+    }
+
+    /** Creates an on-device DOM element from the {@link SafetyLabels}. */
+    @Override
+    public List<Element> toOdDomElements(Document doc) {
+        Element developerInfoEle =
+                XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_DEVELOPER_INFO);
+        if (mName != null) {
+            developerInfoEle.appendChild(
+                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_NAME, mName));
+        }
+        if (mEmail != null) {
+            developerInfoEle.appendChild(
+                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_EMAIL, mEmail));
+        }
+        if (mAddress != null) {
+            developerInfoEle.appendChild(
+                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_ADDRESS, mAddress));
+        }
+        if (mCountryRegion != null) {
+            developerInfoEle.appendChild(
+                    XmlUtils.createOdStringEle(
+                            doc, XmlUtils.OD_NAME_COUNTRY_REGION, mCountryRegion));
+        }
+        if (mDeveloperRelationship != null) {
+            developerInfoEle.appendChild(
+                    XmlUtils.createOdLongEle(
+                            doc,
+                            XmlUtils.OD_NAME_DEVELOPER_RELATIONSHIP,
+                            mDeveloperRelationship.getValue()));
+        }
+        if (mWebsite != null) {
+            developerInfoEle.appendChild(
+                    XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_WEBSITE, mWebsite));
+        }
+        if (mAppDeveloperRegistryId != null) {
+            developerInfoEle.appendChild(
+                    XmlUtils.createOdStringEle(
+                            doc,
+                            XmlUtils.OD_NAME_APP_DEVELOPER_REGISTRY_ID,
+                            mAppDeveloperRegistryId));
+        }
+
+        return XmlUtils.listOf(developerInfoEle);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfoFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfoFactory.java
new file mode 100644
index 0000000..b5310ba
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/DeveloperInfoFactory.java
@@ -0,0 +1,60 @@
+/*
+ * 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.asllib.marshallable;
+
+import com.android.asllib.util.AslgenUtil;
+import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+public class DeveloperInfoFactory implements AslMarshallableFactory<DeveloperInfo> {
+
+    /** Creates a {@link DeveloperInfo} from the human-readable DOM element. */
+    @Override
+    public DeveloperInfo createFromHrElements(List<Element> elements) throws MalformedXmlException {
+        Element developerInfoEle = XmlUtils.getSingleElement(elements);
+        if (developerInfoEle == null) {
+            AslgenUtil.logI("No DeveloperInfo found in hr format.");
+            return null;
+        }
+        String name = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_NAME);
+        String email = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_EMAIL);
+        String address = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_ADDRESS);
+        String countryRegion =
+                XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_COUNTRY_REGION);
+        DeveloperInfo.DeveloperRelationship developerRelationship =
+                DeveloperInfo.DeveloperRelationship.forString(
+                        XmlUtils.getStringAttr(
+                                developerInfoEle, XmlUtils.HR_ATTR_DEVELOPER_RELATIONSHIP));
+        String website = XmlUtils.getStringAttr(developerInfoEle, XmlUtils.HR_ATTR_WEBSITE, false);
+        String appDeveloperRegistryId =
+                XmlUtils.getStringAttr(
+                        developerInfoEle, XmlUtils.HR_ATTR_APP_DEVELOPER_REGISTRY_ID, false);
+
+        return new DeveloperInfo(
+                name,
+                email,
+                address,
+                countryRegion,
+                developerRelationship,
+                website,
+                appDeveloperRegistryId);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/SafetyLabels.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java
similarity index 80%
rename from tools/app_metadata_bundles/src/lib/java/com/android/asllib/SafetyLabels.java
rename to tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java
index f06522f..22c3fd8 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/SafetyLabels.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.asllib.marshallable;
+
+import com.android.asllib.util.XmlUtils;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -47,7 +49,11 @@
     public List<Element> toOdDomElements(Document doc) {
         Element safetyLabelsEle =
                 XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_SAFETY_LABELS);
-        XmlUtils.appendChildren(safetyLabelsEle, mDataLabels.toOdDomElements(doc));
-        return List.of(safetyLabelsEle);
+        safetyLabelsEle.appendChild(
+                XmlUtils.createOdLongEle(doc, XmlUtils.OD_NAME_VERSION, mVersion));
+        if (mDataLabels != null) {
+            XmlUtils.appendChildren(safetyLabelsEle, mDataLabels.toOdDomElements(doc));
+        }
+        return XmlUtils.listOf(safetyLabelsEle);
     }
 }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/SafetyLabelsFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java
similarity index 73%
rename from tools/app_metadata_bundles/src/lib/java/com/android/asllib/SafetyLabelsFactory.java
rename to tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java
index 80b9f57..6bf8ef3 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/SafetyLabelsFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java
@@ -14,9 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.asllib.marshallable;
 
+import com.android.asllib.util.AslgenUtil;
 import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
 
 import org.w3c.dom.Element;
 
@@ -28,20 +30,20 @@
     @Override
     public SafetyLabels createFromHrElements(List<Element> elements) throws MalformedXmlException {
         Element safetyLabelsEle = XmlUtils.getSingleElement(elements);
-        Long version;
-        try {
-            version = Long.parseLong(safetyLabelsEle.getAttribute(XmlUtils.HR_ATTR_VERSION));
-        } catch (Exception e) {
-            throw new IllegalArgumentException(
-                    "Malformed or missing required version in safety labels.");
+        if (safetyLabelsEle == null) {
+            AslgenUtil.logI("No SafetyLabels found in hr format.");
+            return null;
         }
+        long version = XmlUtils.tryGetVersion(safetyLabelsEle);
 
         DataLabels dataLabels =
                 new DataLabelsFactory()
                         .createFromHrElements(
-                                List.of(
+                                XmlUtils.listOf(
                                         XmlUtils.getSingleChildElement(
-                                                safetyLabelsEle, XmlUtils.HR_TAG_DATA_LABELS)));
+                                                safetyLabelsEle,
+                                                XmlUtils.HR_TAG_DATA_LABELS,
+                                                false)));
         return new SafetyLabels(version, dataLabels);
     }
 }
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabel.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabel.java
new file mode 100644
index 0000000..595d748
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabel.java
@@ -0,0 +1,49 @@
+/*
+ * 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.asllib.marshallable;
+
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+/** Safety Label representation containing zero or more {@link DataCategory} for data shared */
+public class SystemAppSafetyLabel implements AslMarshallable {
+
+    private final String mUrl;
+
+    public SystemAppSafetyLabel(String url) {
+        this.mUrl = url;
+    }
+
+    /** Returns the system app safety label URL. */
+    public String getUrl() {
+        return mUrl;
+    }
+
+    /** Creates an on-device DOM element from the {@link SystemAppSafetyLabel}. */
+    @Override
+    public List<Element> toOdDomElements(Document doc) {
+        Element systemAppSafetyLabelEle =
+                XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_SYSTEM_APP_SAFETY_LABEL);
+        systemAppSafetyLabelEle.appendChild(
+                XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_URL, mUrl));
+        return XmlUtils.listOf(systemAppSafetyLabelEle);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabelFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabelFactory.java
new file mode 100644
index 0000000..f999559
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SystemAppSafetyLabelFactory.java
@@ -0,0 +1,42 @@
+/*
+ * 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.asllib.marshallable;
+
+import com.android.asllib.util.AslgenUtil;
+import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+public class SystemAppSafetyLabelFactory implements AslMarshallableFactory<SystemAppSafetyLabel> {
+
+    /** Creates a {@link SystemAppSafetyLabel} from the human-readable DOM element. */
+    @Override
+    public SystemAppSafetyLabel createFromHrElements(List<Element> elements)
+            throws MalformedXmlException {
+        Element systemAppSafetyLabelEle = XmlUtils.getSingleElement(elements);
+        if (systemAppSafetyLabelEle == null) {
+            AslgenUtil.logI("No SystemAppSafetyLabel found in hr format.");
+            return null;
+        }
+
+        String url = XmlUtils.getStringAttr(systemAppSafetyLabelEle, XmlUtils.HR_ATTR_URL);
+        return new SystemAppSafetyLabel(url);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java
new file mode 100644
index 0000000..ddd3557
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfo.java
@@ -0,0 +1,60 @@
+/*
+ * 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.asllib.marshallable;
+
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+/** TransparencyInfo representation containing {@link DeveloperInfo} and {@link AppInfo} */
+public class TransparencyInfo implements AslMarshallable {
+
+    private final DeveloperInfo mDeveloperInfo;
+    private final AppInfo mAppInfo;
+
+    public TransparencyInfo(DeveloperInfo developerInfo, AppInfo appInfo) {
+        this.mDeveloperInfo = developerInfo;
+        this.mAppInfo = appInfo;
+    }
+
+    /** Gets the {@link DeveloperInfo} of the {@link TransparencyInfo}. */
+    public DeveloperInfo getDeveloperInfo() {
+        return mDeveloperInfo;
+    }
+
+    /** Gets the {@link AppInfo} of the {@link TransparencyInfo}. */
+    public AppInfo getAppInfo() {
+        return mAppInfo;
+    }
+
+    /** Creates an on-device DOM element from the {@link TransparencyInfo}. */
+    @Override
+    public List<Element> toOdDomElements(Document doc) {
+        Element transparencyInfoEle =
+                XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_TRANSPARENCY_INFO);
+        if (mDeveloperInfo != null) {
+            XmlUtils.appendChildren(transparencyInfoEle, mDeveloperInfo.toOdDomElements(doc));
+        }
+        if (mAppInfo != null) {
+            XmlUtils.appendChildren(transparencyInfoEle, mAppInfo.toOdDomElements(doc));
+        }
+        return XmlUtils.listOf(transparencyInfoEle);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java
new file mode 100644
index 0000000..d9c2af4
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/TransparencyInfoFactory.java
@@ -0,0 +1,52 @@
+/*
+ * 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.asllib.marshallable;
+
+import com.android.asllib.util.AslgenUtil;
+import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+public class TransparencyInfoFactory implements AslMarshallableFactory<TransparencyInfo> {
+
+    /** Creates a {@link TransparencyInfo} from the human-readable DOM element. */
+    @Override
+    public TransparencyInfo createFromHrElements(List<Element> elements)
+            throws MalformedXmlException {
+        Element transparencyInfoEle = XmlUtils.getSingleElement(elements);
+        if (transparencyInfoEle == null) {
+            AslgenUtil.logI("No TransparencyInfo found in hr format.");
+            return null;
+        }
+
+        Element developerInfoEle =
+                XmlUtils.getSingleChildElement(
+                        transparencyInfoEle, XmlUtils.HR_TAG_DEVELOPER_INFO, false);
+        DeveloperInfo developerInfo =
+                new DeveloperInfoFactory().createFromHrElements(XmlUtils.listOf(developerInfoEle));
+
+        Element appInfoEle =
+                XmlUtils.getSingleChildElement(
+                        transparencyInfoEle, XmlUtils.HR_TAG_APP_INFO, false);
+        AppInfo appInfo = new AppInfoFactory().createFromHrElements(XmlUtils.listOf(appInfoEle));
+
+        return new TransparencyInfo(developerInfo, appInfo);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/AslgenUtil.java
similarity index 69%
copy from packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
copy to tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/AslgenUtil.java
index 0c92b50..7d54215 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/shared/model/StackClipping.kt
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/AslgenUtil.java
@@ -14,7 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.statusbar.notification.stack.shared.model
+package com.android.asllib.util;
 
-/** Models the clipping rounded rectangle of the notification stack */
-data class StackClipping(val bounds: StackBounds, val rounding: StackRounding)
+public class AslgenUtil {
+    private static final String ASLGEN_TAG = "ASLGEN";
+
+    /** Log info. */
+    public static void logI(String s) {
+        System.out.println(String.format("%s -- INFO: %s", ASLGEN_TAG, s));
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataCategoryConstants.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/DataCategoryConstants.java
similarity index 94%
rename from tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataCategoryConstants.java
rename to tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/DataCategoryConstants.java
index b364c8b..b5ae54c 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/DataCategoryConstants.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/DataCategoryConstants.java
@@ -14,8 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.asllib;
+package com.android.asllib.util;
 
+import com.android.asllib.marshallable.DataCategory;
+import com.android.asllib.marshallable.DataType;
+import com.android.asllib.marshallable.SafetyLabels;
 
 import java.util.Arrays;
 import java.util.Collections;
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/DataTypeConstants.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/DataTypeConstants.java
new file mode 100644
index 0000000..358d575
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/DataTypeConstants.java
@@ -0,0 +1,197 @@
+/*
+ * 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.asllib.util;
+
+import com.android.asllib.marshallable.DataCategory;
+import com.android.asllib.marshallable.DataType;
+import com.android.asllib.marshallable.SafetyLabels;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Constants for determining valid {@link String} data types for usage within {@link SafetyLabels},
+ * {@link DataCategory}, and {@link DataType}
+ */
+public class DataTypeConstants {
+    /** Data types for {@link DataCategoryConstants.CATEGORY_PERSONAL} */
+    public static final String TYPE_NAME = "name";
+
+    public static final String TYPE_EMAIL_ADDRESS = "email_address";
+    public static final String TYPE_PHYSICAL_ADDRESS = "physical_address";
+    public static final String TYPE_PHONE_NUMBER = "phone_number";
+    public static final String TYPE_RACE_ETHNICITY = "race_ethnicity";
+    public static final String TYPE_POLITICAL_OR_RELIGIOUS_BELIEFS =
+            "political_or_religious_beliefs";
+    public static final String TYPE_SEXUAL_ORIENTATION_OR_GENDER_IDENTITY =
+            "sexual_orientation_or_gender_identity";
+    public static final String TYPE_PERSONAL_IDENTIFIERS = "personal_identifiers";
+    public static final String TYPE_OTHER = "other";
+
+    /** Data types for {@link DataCategoryConstants.CATEGORY_FINANCIAL} */
+    public static final String TYPE_CARD_BANK_ACCOUNT = "card_bank_account";
+
+    public static final String TYPE_PURCHASE_HISTORY = "purchase_history";
+    public static final String TYPE_CREDIT_SCORE = "credit_score";
+    public static final String TYPE_FINANCIAL_OTHER = "other";
+
+    /** Data types for {@link DataCategoryConstants.CATEGORY_LOCATION} */
+    public static final String TYPE_APPROX_LOCATION = "approx_location";
+
+    public static final String TYPE_PRECISE_LOCATION = "precise_location";
+
+    /** Data types for {@link DataCategoryConstants.CATEGORY_EMAIL_TEXT_MESSAGE} */
+    public static final String TYPE_EMAILS = "emails";
+
+    public static final String TYPE_TEXT_MESSAGES = "text_messages";
+    public static final String TYPE_EMAIL_TEXT_MESSAGE_OTHER = "other";
+
+    /** Data types for {@link DataCategoryConstants.CATEGORY_PHOTO_VIDEO} */
+    public static final String TYPE_PHOTOS = "photos";
+
+    public static final String TYPE_VIDEOS = "videos";
+
+    /** Data types for {@link DataCategoryConstants.CATEGORY_AUDIO} */
+    public static final String TYPE_SOUND_RECORDINGS = "sound_recordings";
+
+    public static final String TYPE_MUSIC_FILES = "music_files";
+    public static final String TYPE_AUDIO_OTHER = "other";
+
+    /** Data types for {@link DataCategoryConstants.CATEGORY_STORAGE} */
+    public static final String TYPE_FILES_DOCS = "files_docs";
+
+    /** Data types for {@link DataCategoryConstants.CATEGORY_HEALTH_FITNESS} */
+    public static final String TYPE_HEALTH = "health";
+
+    public static final String TYPE_FITNESS = "fitness";
+
+    /** Data types for {@link DataCategoryConstants.CATEGORY_CONTACTS} */
+    public static final String TYPE_CONTACTS = "contacts";
+
+    /** Data types for {@link DataCategoryConstants.CATEGORY_CALENDAR} */
+    public static final String TYPE_CALENDAR = "calendar";
+
+    /** Data types for {@link DataCategoryConstants.CATEGORY_IDENTIFIERS} */
+    public static final String TYPE_IDENTIFIERS_OTHER = "other";
+
+    /** Data types for {@link DataCategoryConstants.CATEGORY_APP_PERFORMANCE} */
+    public static final String TYPE_CRASH_LOGS = "crash_logs";
+
+    public static final String TYPE_PERFORMANCE_DIAGNOSTICS = "performance_diagnostics";
+    public static final String TYPE_APP_PERFORMANCE_OTHER = "other";
+
+    /** Data types for {@link DataCategoryConstants.CATEGORY_ACTIONS_IN_APP} */
+    public static final String TYPE_USER_INTERACTION = "user_interaction";
+
+    public static final String TYPE_IN_APP_SEARCH_HISTORY = "in_app_search_history";
+    public static final String TYPE_INSTALLED_APPS = "installed_apps";
+    public static final String TYPE_USER_GENERATED_CONTENT = "user_generated_content";
+    public static final String TYPE_ACTIONS_IN_APP_OTHER = "other";
+
+    /** Data types for {@link DataCategoryConstants.CATEGORY_SEARCH_AND_BROWSING} */
+    public static final String TYPE_WEB_BROWSING_HISTORY = "web_browsing_history";
+
+    /** Set of valid categories */
+    private static final Map<String, Set<String>> VALID_DATA_TYPES =
+            new ImmutableMap.Builder<String, Set<String>>()
+                    .put(
+                            DataCategoryConstants.CATEGORY_PERSONAL,
+                            ImmutableSet.of(
+                                    DataTypeConstants.TYPE_NAME,
+                                    DataTypeConstants.TYPE_EMAIL_ADDRESS,
+                                    DataTypeConstants.TYPE_PHYSICAL_ADDRESS,
+                                    DataTypeConstants.TYPE_PHONE_NUMBER,
+                                    DataTypeConstants.TYPE_RACE_ETHNICITY,
+                                    DataTypeConstants.TYPE_POLITICAL_OR_RELIGIOUS_BELIEFS,
+                                    DataTypeConstants.TYPE_SEXUAL_ORIENTATION_OR_GENDER_IDENTITY,
+                                    DataTypeConstants.TYPE_PERSONAL_IDENTIFIERS,
+                                    DataTypeConstants.TYPE_OTHER))
+                    .put(
+                            DataCategoryConstants.CATEGORY_FINANCIAL,
+                            ImmutableSet.of(
+                                    DataTypeConstants.TYPE_CARD_BANK_ACCOUNT,
+                                    DataTypeConstants.TYPE_PURCHASE_HISTORY,
+                                    DataTypeConstants.TYPE_CREDIT_SCORE,
+                                    DataTypeConstants.TYPE_OTHER))
+                    .put(
+                            DataCategoryConstants.CATEGORY_LOCATION,
+                            ImmutableSet.of(
+                                    DataTypeConstants.TYPE_APPROX_LOCATION,
+                                    DataTypeConstants.TYPE_PRECISE_LOCATION))
+                    .put(
+                            DataCategoryConstants.CATEGORY_EMAIL_TEXT_MESSAGE,
+                            ImmutableSet.of(
+                                    DataTypeConstants.TYPE_EMAILS,
+                                    DataTypeConstants.TYPE_TEXT_MESSAGES,
+                                    DataTypeConstants.TYPE_OTHER))
+                    .put(
+                            DataCategoryConstants.CATEGORY_PHOTO_VIDEO,
+                            ImmutableSet.of(
+                                    DataTypeConstants.TYPE_PHOTOS, DataTypeConstants.TYPE_VIDEOS))
+                    .put(
+                            DataCategoryConstants.CATEGORY_AUDIO,
+                            ImmutableSet.of(
+                                    DataTypeConstants.TYPE_SOUND_RECORDINGS,
+                                    DataTypeConstants.TYPE_MUSIC_FILES,
+                                    DataTypeConstants.TYPE_OTHER))
+                    .put(
+                            DataCategoryConstants.CATEGORY_STORAGE,
+                            ImmutableSet.of(DataTypeConstants.TYPE_FILES_DOCS))
+                    .put(
+                            DataCategoryConstants.CATEGORY_HEALTH_FITNESS,
+                            ImmutableSet.of(
+                                    DataTypeConstants.TYPE_HEALTH, DataTypeConstants.TYPE_FITNESS))
+                    .put(
+                            DataCategoryConstants.CATEGORY_CONTACTS,
+                            ImmutableSet.of(DataTypeConstants.TYPE_CONTACTS))
+                    .put(
+                            DataCategoryConstants.CATEGORY_CALENDAR,
+                            ImmutableSet.of(DataTypeConstants.TYPE_CALENDAR))
+                    .put(
+                            DataCategoryConstants.CATEGORY_IDENTIFIERS,
+                            ImmutableSet.of(DataTypeConstants.TYPE_OTHER))
+                    .put(
+                            DataCategoryConstants.CATEGORY_APP_PERFORMANCE,
+                            ImmutableSet.of(
+                                    DataTypeConstants.TYPE_CRASH_LOGS,
+                                    DataTypeConstants.TYPE_PERFORMANCE_DIAGNOSTICS,
+                                    DataTypeConstants.TYPE_OTHER))
+                    .put(
+                            DataCategoryConstants.CATEGORY_ACTIONS_IN_APP,
+                            ImmutableSet.of(
+                                    DataTypeConstants.TYPE_USER_INTERACTION,
+                                    DataTypeConstants.TYPE_IN_APP_SEARCH_HISTORY,
+                                    DataTypeConstants.TYPE_INSTALLED_APPS,
+                                    DataTypeConstants.TYPE_USER_GENERATED_CONTENT,
+                                    DataTypeConstants.TYPE_OTHER))
+                    .put(
+                            DataCategoryConstants.CATEGORY_SEARCH_AND_BROWSING,
+                            ImmutableSet.of(DataTypeConstants.TYPE_WEB_BROWSING_HISTORY))
+                    .buildOrThrow();
+
+    /** Returns {@link Set} of valid {@link String} category keys */
+    public static Map<String, Set<String>> getValidDataTypes() {
+        return VALID_DATA_TYPES;
+    }
+
+    private DataTypeConstants() {
+        /* do nothing - hide constructor */
+    }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java
new file mode 100644
index 0000000..691f92f
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java
@@ -0,0 +1,327 @@
+/*
+ * 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.asllib.util;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class XmlUtils {
+    public static final String HR_TAG_APP_METADATA_BUNDLES = "app-metadata-bundles";
+    public static final String HR_TAG_SYSTEM_APP_SAFETY_LABEL = "system-app-safety-label";
+    public static final String HR_TAG_SAFETY_LABELS = "safety-labels";
+    public static final String HR_TAG_TRANSPARENCY_INFO = "transparency-info";
+    public static final String HR_TAG_DEVELOPER_INFO = "developer-info";
+    public static final String HR_TAG_APP_INFO = "app-info";
+    public static final String HR_TAG_DATA_LABELS = "data-labels";
+    public static final String HR_TAG_DATA_ACCESSED = "data-accessed";
+    public static final String HR_TAG_DATA_COLLECTED = "data-collected";
+    public static final String HR_TAG_DATA_SHARED = "data-shared";
+    public static final String HR_ATTR_NAME = "name";
+    public static final String HR_ATTR_EMAIL = "email";
+    public static final String HR_ATTR_ADDRESS = "address";
+    public static final String HR_ATTR_COUNTRY_REGION = "countryRegion";
+    public static final String HR_ATTR_DEVELOPER_RELATIONSHIP = "relationship";
+    public static final String HR_ATTR_WEBSITE = "website";
+    public static final String HR_ATTR_APP_DEVELOPER_REGISTRY_ID = "registryId";
+    public static final String HR_ATTR_DATA_CATEGORY = "dataCategory";
+    public static final String HR_ATTR_DATA_TYPE = "dataType";
+    public static final String HR_ATTR_IS_COLLECTION_OPTIONAL = "isCollectionOptional";
+    public static final String HR_ATTR_IS_SHARING_OPTIONAL = "isSharingOptional";
+    public static final String HR_ATTR_EPHEMERAL = "ephemeral";
+    public static final String HR_ATTR_PURPOSES = "purposes";
+    public static final String HR_ATTR_VERSION = "version";
+    public static final String HR_ATTR_URL = "url";
+    public static final String HR_ATTR_TITLE = "title";
+    public static final String HR_ATTR_DESCRIPTION = "description";
+    public static final String HR_ATTR_CONTAINS_ADS = "containsAds";
+    public static final String HR_ATTR_OBEY_APS = "obeyAps";
+    public static final String HR_ATTR_ADS_FINGERPRINTING = "adsFingerprinting";
+    public static final String HR_ATTR_SECURITY_FINGERPRINTING = "securityFingerprinting";
+    public static final String HR_ATTR_PRIVACY_POLICY = "privacyPolicy";
+    public static final String HR_ATTR_SECURITY_ENDPOINTS = "securityEndpoints";
+    public static final String HR_ATTR_FIRST_PARTY_ENDPOINTS = "firstPartyEndpoints";
+    public static final String HR_ATTR_SERVICE_PROVIDER_ENDPOINTS = "serviceProviderEndpoints";
+    public static final String HR_ATTR_CATEGORY = "category";
+
+    public static final String OD_TAG_BUNDLE = "bundle";
+    public static final String OD_TAG_PBUNDLE_AS_MAP = "pbundle_as_map";
+    public static final String OD_TAG_BOOLEAN = "boolean";
+    public static final String OD_TAG_LONG = "long";
+    public static final String OD_TAG_STRING = "string";
+    public static final String OD_TAG_INT_ARRAY = "int-array";
+    public static final String OD_TAG_STRING_ARRAY = "string-array";
+    public static final String OD_TAG_ITEM = "item";
+    public static final String OD_ATTR_NAME = "name";
+    public static final String OD_ATTR_VALUE = "value";
+    public static final String OD_ATTR_NUM = "num";
+    public static final String OD_NAME_SAFETY_LABELS = "safety_labels";
+    public static final String OD_NAME_TRANSPARENCY_INFO = "transparency_info";
+    public static final String OD_NAME_DEVELOPER_INFO = "developer_info";
+    public static final String OD_NAME_NAME = "name";
+    public static final String OD_NAME_EMAIL = "email";
+    public static final String OD_NAME_ADDRESS = "address";
+    public static final String OD_NAME_COUNTRY_REGION = "country_region";
+    public static final String OD_NAME_DEVELOPER_RELATIONSHIP = "relationship";
+    public static final String OD_NAME_WEBSITE = "website";
+    public static final String OD_NAME_APP_DEVELOPER_REGISTRY_ID = "app_developer_registry_id";
+    public static final String OD_NAME_APP_INFO = "app_info";
+    public static final String OD_NAME_TITLE = "title";
+    public static final String OD_NAME_DESCRIPTION = "description";
+    public static final String OD_NAME_CONTAINS_ADS = "contains_ads";
+    public static final String OD_NAME_OBEY_APS = "obey_aps";
+    public static final String OD_NAME_ADS_FINGERPRINTING = "ads_fingerprinting";
+    public static final String OD_NAME_SECURITY_FINGERPRINTING = "security_fingerprinting";
+    public static final String OD_NAME_PRIVACY_POLICY = "privacy_policy";
+    public static final String OD_NAME_SECURITY_ENDPOINT = "security_endpoint";
+    public static final String OD_NAME_FIRST_PARTY_ENDPOINT = "first_party_endpoint";
+    public static final String OD_NAME_SERVICE_PROVIDER_ENDPOINT = "service_provider_endpoint";
+    public static final String OD_NAME_CATEGORY = "category";
+    public static final String OD_NAME_VERSION = "version";
+    public static final String OD_NAME_URL = "url";
+    public static final String OD_NAME_SYSTEM_APP_SAFETY_LABEL = "system_app_safety_label";
+    public static final String OD_NAME_DATA_LABELS = "data_labels";
+    public static final String OD_NAME_DATA_ACCESSED = "data_accessed";
+    public static final String OD_NAME_DATA_COLLECTED = "data_collected";
+    public static final String OD_NAME_DATA_SHARED = "data_shared";
+    public static final String OD_NAME_PURPOSES = "purposes";
+    public static final String OD_NAME_IS_COLLECTION_OPTIONAL = "is_collection_optional";
+    public static final String OD_NAME_IS_SHARING_OPTIONAL = "is_sharing_optional";
+    public static final String OD_NAME_EPHEMERAL = "ephemeral";
+
+    public static final String TRUE_STR = "true";
+    public static final String FALSE_STR = "false";
+
+    /** Gets the single top-level {@link Element} having the {@param tagName}. */
+    public static Element getSingleElement(Document doc, String tagName)
+            throws MalformedXmlException {
+        var elements = doc.getElementsByTagName(tagName);
+        return getSingleElement(elements, tagName);
+    }
+
+    /**
+     * Gets the single {@link Element} within {@param parentEle} and having the {@param tagName}.
+     */
+    public static Element getSingleChildElement(Element parentEle, String tagName)
+            throws MalformedXmlException {
+        var elements = parentEle.getElementsByTagName(tagName);
+        return getSingleElement(elements, tagName, true);
+    }
+
+    /**
+     * Gets the single {@link Element} within {@param parentEle} and having the {@param tagName}.
+     */
+    public static Element getSingleChildElement(Element parentEle, String tagName, boolean required)
+            throws MalformedXmlException {
+        var elements = parentEle.getElementsByTagName(tagName);
+        return getSingleElement(elements, tagName, required);
+    }
+
+    /** Gets the single {@link Element} from {@param elements} */
+    public static Element getSingleElement(NodeList elements, String tagName)
+            throws MalformedXmlException {
+        return getSingleElement(elements, tagName, true);
+    }
+
+    /** Gets the single {@link Element} from {@param elements} */
+    public static Element getSingleElement(NodeList elements, String tagName, boolean required)
+            throws MalformedXmlException {
+        if (elements.getLength() > 1) {
+            throw new MalformedXmlException(
+                    String.format(
+                            "Expected 1 element \"%s\" in NodeList but got %s.",
+                            tagName, elements.getLength()));
+        } else if (elements.getLength() == 0) {
+            if (required) {
+                throw new MalformedXmlException(
+                        String.format("Found no element \"%s\" in NodeList.", tagName));
+            } else {
+                return null;
+            }
+        }
+        var elementAsNode = elements.item(0);
+        if (!(elementAsNode instanceof Element)) {
+            throw new MalformedXmlException(
+                    String.format("%s was not a valid XML element.", tagName));
+        }
+        return ((Element) elementAsNode);
+    }
+
+    /** Gets the single {@link Element} within {@param elements}. */
+    public static Element getSingleElement(List<Element> elements) {
+        if (elements.size() != 1) {
+            throw new IllegalStateException(
+                    String.format("Expected 1 element in list but got %s.", elements.size()));
+        }
+        return elements.get(0);
+    }
+
+    /** Converts {@param nodeList} into List of {@link Element}. */
+    public static List<Element> asElementList(NodeList nodeList) {
+        List<Element> elementList = new ArrayList<Element>();
+        for (int i = 0; i < nodeList.getLength(); i++) {
+            var elementAsNode = nodeList.item(i);
+            if (elementAsNode instanceof Element) {
+                elementList.add(((Element) elementAsNode));
+            }
+        }
+        return elementList;
+    }
+
+    /** Appends {@param children} to the {@param ele}. */
+    public static void appendChildren(Element ele, List<Element> children) {
+        for (Element c : children) {
+            ele.appendChild(c);
+        }
+    }
+
+    /** Gets the Boolean from the String value. */
+    private static Boolean fromString(String s) {
+        if (s == null) {
+            return null;
+        }
+        if (s.equals(TRUE_STR)) {
+            return true;
+        } else if (s.equals(FALSE_STR)) {
+            return false;
+        }
+        return null;
+    }
+
+    /** Creates an on-device PBundle DOM Element with the given attribute name. */
+    public static Element createPbundleEleWithName(Document doc, String name) {
+        var ele = doc.createElement(XmlUtils.OD_TAG_PBUNDLE_AS_MAP);
+        ele.setAttribute(XmlUtils.OD_ATTR_NAME, name);
+        return ele;
+    }
+
+    /** Create an on-device Boolean DOM Element with the given attribute name. */
+    public static Element createOdBooleanEle(Document doc, String name, boolean b) {
+        var ele = doc.createElement(XmlUtils.OD_TAG_BOOLEAN);
+        ele.setAttribute(XmlUtils.OD_ATTR_NAME, name);
+        ele.setAttribute(XmlUtils.OD_ATTR_VALUE, String.valueOf(b));
+        return ele;
+    }
+
+    /** Create an on-device Long DOM Element with the given attribute name. */
+    public static Element createOdLongEle(Document doc, String name, long l) {
+        var ele = doc.createElement(XmlUtils.OD_TAG_LONG);
+        ele.setAttribute(XmlUtils.OD_ATTR_NAME, name);
+        ele.setAttribute(XmlUtils.OD_ATTR_VALUE, String.valueOf(l));
+        return ele;
+    }
+
+    /** Create an on-device Long DOM Element with the given attribute name. */
+    public static Element createOdStringEle(Document doc, String name, String val) {
+        var ele = doc.createElement(XmlUtils.OD_TAG_STRING);
+        ele.setAttribute(XmlUtils.OD_ATTR_NAME, name);
+        ele.setAttribute(XmlUtils.OD_ATTR_VALUE, val);
+        return ele;
+    }
+
+    /** Create OD style array DOM Element, which can represent any time but is stored as Strings. */
+    public static Element createOdArray(
+            Document doc, String arrayTag, String arrayName, List<String> arrayVals) {
+        Element arrEle = doc.createElement(arrayTag);
+        arrEle.setAttribute(XmlUtils.OD_ATTR_NAME, arrayName);
+        arrEle.setAttribute(XmlUtils.OD_ATTR_NUM, String.valueOf(arrayVals.size()));
+        for (String s : arrayVals) {
+            Element itemEle = doc.createElement(XmlUtils.OD_TAG_ITEM);
+            itemEle.setAttribute(XmlUtils.OD_ATTR_VALUE, s);
+            arrEle.appendChild(itemEle);
+        }
+        return arrEle;
+    }
+
+    /** Returns whether the String is null or empty. */
+    public static boolean isNullOrEmpty(String s) {
+        return s == null || s.isEmpty();
+    }
+
+    /** Tries getting required version attribute and throws exception if it doesn't exist */
+    public static Long tryGetVersion(Element ele) throws MalformedXmlException {
+        long version;
+        try {
+            version = Long.parseLong(ele.getAttribute(XmlUtils.HR_ATTR_VERSION));
+        } catch (Exception e) {
+            throw new MalformedXmlException(
+                    String.format(
+                            "Malformed or missing required version in: %s", ele.getTagName()));
+        }
+        return version;
+    }
+
+    /** Gets a pipeline-split attribute. */
+    public static List<String> getPipelineSplitAttr(Element ele, String attrName, boolean required)
+            throws MalformedXmlException {
+        List<String> list = Arrays.stream(ele.getAttribute(attrName).split("\\|")).toList();
+        if ((list.isEmpty() || list.get(0).isEmpty()) && required) {
+            throw new MalformedXmlException(
+                    String.format(
+                            "Delimited string %s was required but missing, in %s.",
+                            attrName, ele.getTagName()));
+        }
+        return list;
+    }
+
+    /** Gets a Boolean attribute. */
+    public static Boolean getBoolAttr(Element ele, String attrName, boolean required)
+            throws MalformedXmlException {
+        Boolean b = XmlUtils.fromString(ele.getAttribute(attrName));
+        if (b == null && required) {
+            throw new MalformedXmlException(
+                    String.format(
+                            "Boolean %s was required but missing, in %s.",
+                            attrName, ele.getTagName()));
+        }
+        return b;
+    }
+
+    /** Gets a required String attribute. */
+    public static String getStringAttr(Element ele, String attrName) throws MalformedXmlException {
+        return getStringAttr(ele, attrName, true);
+    }
+
+    /** Gets a String attribute; throws exception if required and non-existent. */
+    public static String getStringAttr(Element ele, String attrName, boolean required)
+            throws MalformedXmlException {
+        String s = ele.getAttribute(attrName);
+        if (isNullOrEmpty(s)) {
+            if (required) {
+                throw new MalformedXmlException(
+                        String.format(
+                                "Malformed or missing required %s in: %s",
+                                attrName, ele.getTagName()));
+            } else {
+                return null;
+            }
+        }
+        return s;
+    }
+
+    /**
+     * Utility method for making a List from one element, to support easier refactoring if needed.
+     * For example, List.of() doesn't support null elements.
+     */
+    public static List<Element> listOf(Element e) {
+        return Arrays.asList(e);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java
new file mode 100644
index 0000000..03e8ac6
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib;
+
+import com.android.asllib.marshallable.AndroidSafetyLabelTest;
+import com.android.asllib.marshallable.DataCategoryTest;
+import com.android.asllib.marshallable.DataLabelsTest;
+import com.android.asllib.marshallable.DeveloperInfoTest;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+    AslgenTests.class,
+    AndroidSafetyLabelTest.class,
+    DeveloperInfoTest.class,
+    DataCategoryTest.class,
+    DataLabelsTest.class,
+})
+public class AllTests {}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java
new file mode 100644
index 0000000..5f43008
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.asllib.marshallable.AndroidSafetyLabel;
+import com.android.asllib.testutils.TestUtils;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+
+@RunWith(JUnit4.class)
+public class AslgenTests {
+    private static final String VALID_MAPPINGS_PATH = "com/android/asllib/validmappings";
+    private static final List<String> VALID_MAPPINGS_SUBDIRS = List.of("location", "contacts");
+    private static final String HR_XML_FILENAME = "hr.xml";
+    private static final String OD_XML_FILENAME = "od.xml";
+
+    /** Logic for setting up tests (empty if not yet needed). */
+    public static void main(String[] params) throws Exception {}
+
+    /** Tests valid mappings between HR and OD. */
+    @Test
+    public void testValidMappings() throws Exception {
+        System.out.println("start testing valid mappings.");
+
+        for (String subdir : VALID_MAPPINGS_SUBDIRS) {
+            Path hrPath = Paths.get(VALID_MAPPINGS_PATH, subdir, HR_XML_FILENAME);
+            Path odPath = Paths.get(VALID_MAPPINGS_PATH, subdir, OD_XML_FILENAME);
+
+            System.out.println("hr path: " + hrPath.toString());
+            System.out.println("od path: " + odPath.toString());
+
+            InputStream hrStream =
+                    getClass().getClassLoader().getResourceAsStream(hrPath.toString());
+            String hrContents = new String(hrStream.readAllBytes(), StandardCharsets.UTF_8);
+            InputStream odStream =
+                    getClass().getClassLoader().getResourceAsStream(odPath.toString());
+            String odContents = new String(odStream.readAllBytes(), StandardCharsets.UTF_8);
+            AndroidSafetyLabel asl =
+                    AslConverter.readFromString(hrContents, AslConverter.Format.HUMAN_READABLE);
+            String out = AslConverter.getXmlAsString(asl, AslConverter.Format.ON_DEVICE);
+            System.out.println("out: " + out);
+
+            assertEquals(
+                    TestUtils.getFormattedXml(out, false),
+                    TestUtils.getFormattedXml(odContents, false));
+        }
+    }
+}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AndroidSafetyLabelTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AndroidSafetyLabelTest.java
new file mode 100644
index 0000000..0137007
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AndroidSafetyLabelTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib.marshallable;
+
+import com.android.asllib.testutils.TestUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.w3c.dom.Document;
+
+@RunWith(JUnit4.class)
+public class AndroidSafetyLabelTest {
+    private static final String ANDROID_SAFETY_LABEL_HR_PATH =
+            "com/android/asllib/androidsafetylabel/hr";
+    private static final String ANDROID_SAFETY_LABEL_OD_PATH =
+            "com/android/asllib/androidsafetylabel/od";
+
+    private static final String MISSING_VERSION_FILE_NAME = "missing-version.xml";
+    private static final String VALID_EMPTY_FILE_NAME = "valid-empty.xml";
+    private static final String WITH_SAFETY_LABELS_FILE_NAME = "with-safety-labels.xml";
+    private static final String WITH_SYSTEM_APP_SAFETY_LABEL_FILE_NAME =
+            "with-system-app-safety-label.xml";
+    private static final String WITH_TRANSPARENCY_INFO_FILE_NAME = "with-transparency-info.xml";
+
+    private Document mDoc = null;
+
+    @Before
+    public void setUp() throws Exception {
+        System.out.println("set up.");
+        mDoc = TestUtils.document();
+    }
+
+    /** Test for android safety label missing version. */
+    @Test
+    public void testAndroidSafetyLabelMissingVersion() throws Exception {
+        System.out.println("starting testAndroidSafetyLabelMissingVersion.");
+        hrToOdExpectException(MISSING_VERSION_FILE_NAME);
+    }
+
+    /** Test for android safety label valid empty. */
+    @Test
+    public void testAndroidSafetyLabelValidEmptyFile() throws Exception {
+        System.out.println("starting testAndroidSafetyLabelValidEmptyFile.");
+        testHrToOdAndroidSafetyLabel(VALID_EMPTY_FILE_NAME);
+    }
+
+    /** Test for android safety label with safety labels. */
+    @Test
+    public void testAndroidSafetyLabelWithSafetyLabels() throws Exception {
+        System.out.println("starting testAndroidSafetyLabelWithSafetyLabels.");
+        testHrToOdAndroidSafetyLabel(WITH_SAFETY_LABELS_FILE_NAME);
+    }
+
+    /** Test for android safety label with system app safety label. */
+    @Test
+    public void testAndroidSafetyLabelWithSystemAppSafetyLabel() throws Exception {
+        System.out.println("starting testAndroidSafetyLabelWithSystemAppSafetyLabel.");
+        testHrToOdAndroidSafetyLabel(WITH_SYSTEM_APP_SAFETY_LABEL_FILE_NAME);
+    }
+
+    /** Test for android safety label with transparency info. */
+    @Test
+    public void testAndroidSafetyLabelWithTransparencyInfo() throws Exception {
+        System.out.println("starting testAndroidSafetyLabelWithTransparencyInfo.");
+        testHrToOdAndroidSafetyLabel(WITH_TRANSPARENCY_INFO_FILE_NAME);
+    }
+
+    private void hrToOdExpectException(String fileName) {
+        TestUtils.hrToOdExpectException(
+                new AndroidSafetyLabelFactory(), ANDROID_SAFETY_LABEL_HR_PATH, fileName);
+    }
+
+    private void testHrToOdAndroidSafetyLabel(String fileName) throws Exception {
+        TestUtils.testHrToOd(
+                mDoc,
+                new AndroidSafetyLabelFactory(),
+                ANDROID_SAFETY_LABEL_HR_PATH,
+                ANDROID_SAFETY_LABEL_OD_PATH,
+                fileName);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java
new file mode 100644
index 0000000..a015e2e
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/AppInfoTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib.marshallable;
+
+import static org.junit.Assert.assertThrows;
+
+import com.android.asllib.testutils.TestUtils;
+import com.android.asllib.util.MalformedXmlException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.w3c.dom.Document;
+
+import java.nio.file.Paths;
+import java.util.List;
+
+@RunWith(JUnit4.class)
+public class AppInfoTest {
+    private static final String APP_INFO_HR_PATH = "com/android/asllib/appinfo/hr";
+    private static final String APP_INFO_OD_PATH = "com/android/asllib/appinfo/od";
+    public static final List<String> REQUIRED_FIELD_NAMES =
+            List.of(
+                    "title",
+                    "description",
+                    "containsAds",
+                    "obeyAps",
+                    "adsFingerprinting",
+                    "securityFingerprinting",
+                    "privacyPolicy",
+                    "securityEndpoints",
+                    "firstPartyEndpoints",
+                    "serviceProviderEndpoints",
+                    "category",
+                    "email");
+    public static final List<String> OPTIONAL_FIELD_NAMES = List.of("website");
+
+    private static final String ALL_FIELDS_VALID_FILE_NAME = "all-fields-valid.xml";
+
+    private Document mDoc = null;
+
+    /** Logic for setting up tests (empty if not yet needed). */
+    public static void main(String[] params) throws Exception {}
+
+    @Before
+    public void setUp() throws Exception {
+        System.out.println("set up.");
+        mDoc = TestUtils.document();
+    }
+
+    /** Test for all fields valid. */
+    @Test
+    public void testAllFieldsValid() throws Exception {
+        System.out.println("starting testAllFieldsValid.");
+        testHrToOdAppInfo(ALL_FIELDS_VALID_FILE_NAME);
+    }
+
+    /** Tests missing required fields fails. */
+    @Test
+    public void testMissingRequiredFields() throws Exception {
+        System.out.println("Starting testMissingRequiredFields");
+        for (String reqField : REQUIRED_FIELD_NAMES) {
+            System.out.println("testing missing required field: " + reqField);
+            var appInfoEle =
+                    TestUtils.getElementsFromResource(
+                            Paths.get(APP_INFO_HR_PATH, ALL_FIELDS_VALID_FILE_NAME));
+            appInfoEle.get(0).removeAttribute(reqField);
+
+            assertThrows(
+                    MalformedXmlException.class,
+                    () -> new AppInfoFactory().createFromHrElements(appInfoEle));
+        }
+    }
+
+    /** Tests missing optional fields passes. */
+    @Test
+    public void testMissingOptionalFields() throws Exception {
+        for (String optField : OPTIONAL_FIELD_NAMES) {
+            var ele =
+                    TestUtils.getElementsFromResource(
+                            Paths.get(APP_INFO_HR_PATH, ALL_FIELDS_VALID_FILE_NAME));
+            ele.get(0).removeAttribute(optField);
+            AppInfo appInfo = new AppInfoFactory().createFromHrElements(ele);
+            appInfo.toOdDomElements(mDoc);
+        }
+    }
+
+    private void testHrToOdAppInfo(String fileName) throws Exception {
+        TestUtils.testHrToOd(
+                mDoc, new AppInfoFactory(), APP_INFO_HR_PATH, APP_INFO_OD_PATH, fileName);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataCategoryTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataCategoryTest.java
new file mode 100644
index 0000000..822f175
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataCategoryTest.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib.marshallable;
+
+import com.android.asllib.testutils.TestUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.w3c.dom.Document;
+
+@RunWith(JUnit4.class)
+public class DataCategoryTest {
+    private static final String DATA_CATEGORY_HR_PATH = "com/android/asllib/datacategory/hr";
+    private static final String DATA_CATEGORY_OD_PATH = "com/android/asllib/datacategory/od";
+
+    private static final String VALID_PERSONAL_FILE_NAME = "data-category-personal.xml";
+    private static final String VALID_PARTIAL_PERSONAL_FILE_NAME =
+            "data-category-personal-partial.xml";
+    private static final String VALID_FINANCIAL_FILE_NAME = "data-category-financial.xml";
+    private static final String VALID_LOCATION_FILE_NAME = "data-category-location.xml";
+    private static final String VALID_EMAIL_TEXT_MESSAGE_FILE_NAME =
+            "data-category-email-text-message.xml";
+    private static final String VALID_PHOTO_VIDEO_FILE_NAME = "data-category-photo-video.xml";
+    private static final String VALID_AUDIO_FILE_NAME = "data-category-audio.xml";
+    private static final String VALID_STORAGE_FILE_NAME = "data-category-storage.xml";
+    private static final String VALID_HEALTH_FITNESS_FILE_NAME = "data-category-health-fitness.xml";
+    private static final String VALID_CONTACTS_FILE_NAME = "data-category-contacts.xml";
+    private static final String VALID_CALENDAR_FILE_NAME = "data-category-calendar.xml";
+    private static final String VALID_IDENTIFIERS_FILE_NAME = "data-category-identifiers.xml";
+    private static final String VALID_APP_PERFORMANCE_FILE_NAME =
+            "data-category-app-performance.xml";
+    private static final String VALID_ACTIONS_IN_APP_FILE_NAME = "data-category-actions-in-app.xml";
+    private static final String VALID_SEARCH_AND_BROWSING_FILE_NAME =
+            "data-category-search-and-browsing.xml";
+
+    private static final String EMPTY_PURPOSE_PERSONAL_FILE_NAME =
+            "data-category-personal-empty-purpose.xml";
+    private static final String MISSING_PURPOSE_PERSONAL_FILE_NAME =
+            "data-category-personal-missing-purpose.xml";
+    private static final String UNRECOGNIZED_TYPE_PERSONAL_FILE_NAME =
+            "data-category-personal-unrecognized-type.xml";
+    private static final String UNRECOGNIZED_CATEGORY_FILE_NAME = "data-category-unrecognized.xml";
+
+    private Document mDoc = null;
+
+    /** Logic for setting up tests (empty if not yet needed). */
+    public static void main(String[] params) throws Exception {}
+
+    @Before
+    public void setUp() throws Exception {
+        System.out.println("set up.");
+        mDoc = TestUtils.document();
+    }
+
+    /** Test for data category personal. */
+    @Test
+    public void testDataCategoryPersonal() throws Exception {
+        System.out.println("starting testDataCategoryPersonal.");
+        testHrToOdDataCategory(VALID_PERSONAL_FILE_NAME);
+    }
+
+    /** Test for data category financial. */
+    @Test
+    public void testDataCategoryFinancial() throws Exception {
+        System.out.println("starting testDataCategoryFinancial.");
+        testHrToOdDataCategory(VALID_FINANCIAL_FILE_NAME);
+    }
+
+    /** Test for data category location. */
+    @Test
+    public void testDataCategoryLocation() throws Exception {
+        System.out.println("starting testDataCategoryLocation.");
+        testHrToOdDataCategory(VALID_LOCATION_FILE_NAME);
+    }
+
+    /** Test for data category email text message. */
+    @Test
+    public void testDataCategoryEmailTextMessage() throws Exception {
+        System.out.println("starting testDataCategoryEmailTextMessage.");
+        testHrToOdDataCategory(VALID_EMAIL_TEXT_MESSAGE_FILE_NAME);
+    }
+
+    /** Test for data category photo video. */
+    @Test
+    public void testDataCategoryPhotoVideo() throws Exception {
+        System.out.println("starting testDataCategoryPhotoVideo.");
+        testHrToOdDataCategory(VALID_PHOTO_VIDEO_FILE_NAME);
+    }
+
+    /** Test for data category audio. */
+    @Test
+    public void testDataCategoryAudio() throws Exception {
+        System.out.println("starting testDataCategoryAudio.");
+        testHrToOdDataCategory(VALID_AUDIO_FILE_NAME);
+    }
+
+    /** Test for data category storage. */
+    @Test
+    public void testDataCategoryStorage() throws Exception {
+        System.out.println("starting testDataCategoryStorage.");
+        testHrToOdDataCategory(VALID_STORAGE_FILE_NAME);
+    }
+
+    /** Test for data category health fitness. */
+    @Test
+    public void testDataCategoryHealthFitness() throws Exception {
+        System.out.println("starting testDataCategoryHealthFitness.");
+        testHrToOdDataCategory(VALID_HEALTH_FITNESS_FILE_NAME);
+    }
+
+    /** Test for data category contacts. */
+    @Test
+    public void testDataCategoryContacts() throws Exception {
+        System.out.println("starting testDataCategoryContacts.");
+        testHrToOdDataCategory(VALID_CONTACTS_FILE_NAME);
+    }
+
+    /** Test for data category calendar. */
+    @Test
+    public void testDataCategoryCalendar() throws Exception {
+        System.out.println("starting testDataCategoryCalendar.");
+        testHrToOdDataCategory(VALID_CALENDAR_FILE_NAME);
+    }
+
+    /** Test for data category identifiers. */
+    @Test
+    public void testDataCategoryIdentifiers() throws Exception {
+        System.out.println("starting testDataCategoryIdentifiers.");
+        testHrToOdDataCategory(VALID_IDENTIFIERS_FILE_NAME);
+    }
+
+    /** Test for data category app performance. */
+    @Test
+    public void testDataCategoryAppPerformance() throws Exception {
+        System.out.println("starting testDataCategoryAppPerformance.");
+        testHrToOdDataCategory(VALID_APP_PERFORMANCE_FILE_NAME);
+    }
+
+    /** Test for data category actions in app. */
+    @Test
+    public void testDataCategoryActionsInApp() throws Exception {
+        System.out.println("starting testDataCategoryActionsInApp.");
+        testHrToOdDataCategory(VALID_ACTIONS_IN_APP_FILE_NAME);
+    }
+
+    /** Test for data category search and browsing. */
+    @Test
+    public void testDataCategorySearchAndBrowsing() throws Exception {
+        System.out.println("starting testDataCategorySearchAndBrowsing.");
+        testHrToOdDataCategory(VALID_SEARCH_AND_BROWSING_FILE_NAME);
+    }
+
+    /** Test for data category search and browsing. */
+    @Test
+    public void testMissingOptionalsAllowed() throws Exception {
+        System.out.println("starting testMissingOptionalsAllowed.");
+        testHrToOdDataCategory(VALID_PARTIAL_PERSONAL_FILE_NAME);
+    }
+
+    /** Test for empty purposes. */
+    @Test
+    public void testEmptyPurposesNotAllowed() throws Exception {
+        System.out.println("starting testEmptyPurposesNotAllowed.");
+        hrToOdExpectException(EMPTY_PURPOSE_PERSONAL_FILE_NAME);
+    }
+
+    /** Test for missing purposes. */
+    @Test
+    public void testMissingPurposesNotAllowed() throws Exception {
+        System.out.println("starting testMissingPurposesNotAllowed.");
+        hrToOdExpectException(MISSING_PURPOSE_PERSONAL_FILE_NAME);
+    }
+
+    /** Test for unrecognized type. */
+    @Test
+    public void testUnrecognizedTypeNotAllowed() throws Exception {
+        System.out.println("starting testUnrecognizedTypeNotAllowed.");
+        hrToOdExpectException(UNRECOGNIZED_TYPE_PERSONAL_FILE_NAME);
+    }
+
+    /** Test for unrecognized category. */
+    @Test
+    public void testUnrecognizedCategoryNotAllowed() throws Exception {
+        System.out.println("starting testUnrecognizedCategoryNotAllowed.");
+        hrToOdExpectException(UNRECOGNIZED_CATEGORY_FILE_NAME);
+    }
+
+    private void hrToOdExpectException(String fileName) {
+        TestUtils.hrToOdExpectException(new DataCategoryFactory(), DATA_CATEGORY_HR_PATH, fileName);
+    }
+
+    private void testHrToOdDataCategory(String fileName) throws Exception {
+        TestUtils.testHrToOd(
+                mDoc,
+                new DataCategoryFactory(),
+                DATA_CATEGORY_HR_PATH,
+                DATA_CATEGORY_OD_PATH,
+                fileName);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataLabelsTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataLabelsTest.java
new file mode 100644
index 0000000..2be447e
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DataLabelsTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib.marshallable;
+
+import com.android.asllib.testutils.TestUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.w3c.dom.Document;
+
+@RunWith(JUnit4.class)
+public class DataLabelsTest {
+    private static final String DATA_LABELS_HR_PATH = "com/android/asllib/datalabels/hr";
+    private static final String DATA_LABELS_OD_PATH = "com/android/asllib/datalabels/od";
+
+    private static final String ACCESSED_VALID_BOOL_FILE_NAME =
+            "data-labels-accessed-valid-bool.xml";
+    private static final String ACCESSED_INVALID_BOOL_FILE_NAME =
+            "data-labels-accessed-invalid-bool.xml";
+    private static final String COLLECTED_VALID_BOOL_FILE_NAME =
+            "data-labels-collected-valid-bool.xml";
+    private static final String COLLECTED_INVALID_BOOL_FILE_NAME =
+            "data-labels-collected-invalid-bool.xml";
+    private static final String SHARED_VALID_BOOL_FILE_NAME = "data-labels-shared-valid-bool.xml";
+    private static final String SHARED_INVALID_BOOL_FILE_NAME =
+            "data-labels-shared-invalid-bool.xml";
+
+    private Document mDoc = null;
+
+    @Before
+    public void setUp() throws Exception {
+        System.out.println("set up.");
+        mDoc = TestUtils.document();
+    }
+
+    /** Test for data labels accessed valid bool. */
+    @Test
+    public void testDataLabelsAccessedValidBool() throws Exception {
+        System.out.println("starting testDataLabelsAccessedValidBool.");
+        testHrToOdDataLabels(ACCESSED_VALID_BOOL_FILE_NAME);
+    }
+
+    /** Test for data labels accessed invalid bool. */
+    @Test
+    public void testDataLabelsAccessedInvalidBool() throws Exception {
+        System.out.println("starting testDataLabelsAccessedInvalidBool.");
+        hrToOdExpectException(ACCESSED_INVALID_BOOL_FILE_NAME);
+    }
+
+    /** Test for data labels collected valid bool. */
+    @Test
+    public void testDataLabelsCollectedValidBool() throws Exception {
+        System.out.println("starting testDataLabelsCollectedValidBool.");
+        testHrToOdDataLabels(COLLECTED_VALID_BOOL_FILE_NAME);
+    }
+
+    /** Test for data labels collected invalid bool. */
+    @Test
+    public void testDataLabelsCollectedInvalidBool() throws Exception {
+        System.out.println("starting testDataLabelsCollectedInvalidBool.");
+        hrToOdExpectException(COLLECTED_INVALID_BOOL_FILE_NAME);
+    }
+
+    /** Test for data labels shared valid bool. */
+    @Test
+    public void testDataLabelsSharedValidBool() throws Exception {
+        System.out.println("starting testDataLabelsSharedValidBool.");
+        testHrToOdDataLabels(SHARED_VALID_BOOL_FILE_NAME);
+    }
+
+    /** Test for data labels shared invalid bool. */
+    @Test
+    public void testDataLabelsSharedInvalidBool() throws Exception {
+        System.out.println("starting testDataLabelsSharedInvalidBool.");
+        hrToOdExpectException(SHARED_INVALID_BOOL_FILE_NAME);
+    }
+
+    private void hrToOdExpectException(String fileName) {
+        TestUtils.hrToOdExpectException(new DataLabelsFactory(), DATA_LABELS_HR_PATH, fileName);
+    }
+
+    private void testHrToOdDataLabels(String fileName) throws Exception {
+        TestUtils.testHrToOd(
+                mDoc, new DataLabelsFactory(), DATA_LABELS_HR_PATH, DATA_LABELS_OD_PATH, fileName);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DeveloperInfoTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DeveloperInfoTest.java
new file mode 100644
index 0000000..ff8346a
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/DeveloperInfoTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib.marshallable;
+
+import static org.junit.Assert.assertThrows;
+
+import com.android.asllib.testutils.TestUtils;
+import com.android.asllib.util.MalformedXmlException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.w3c.dom.Document;
+
+import java.nio.file.Paths;
+import java.util.List;
+
+@RunWith(JUnit4.class)
+public class DeveloperInfoTest {
+    private static final String DEVELOPER_INFO_HR_PATH = "com/android/asllib/developerinfo/hr";
+    private static final String DEVELOPER_INFO_OD_PATH = "com/android/asllib/developerinfo/od";
+    public static final List<String> REQUIRED_FIELD_NAMES =
+            List.of("address", "countryRegion", "email", "name", "relationship");
+    public static final List<String> OPTIONAL_FIELD_NAMES = List.of("website", "registryId");
+
+    private static final String ALL_FIELDS_VALID_FILE_NAME = "all-fields-valid.xml";
+
+    private Document mDoc = null;
+
+    /** Logic for setting up tests (empty if not yet needed). */
+    public static void main(String[] params) throws Exception {}
+
+    @Before
+    public void setUp() throws Exception {
+        System.out.println("set up.");
+        mDoc = TestUtils.document();
+    }
+
+    /** Test for all fields valid. */
+    @Test
+    public void testAllFieldsValid() throws Exception {
+        System.out.println("starting testAllFieldsValid.");
+        testHrToOdDeveloperInfo(ALL_FIELDS_VALID_FILE_NAME);
+    }
+
+    /** Tests missing required fields fails. */
+    @Test
+    public void testMissingRequiredFields() throws Exception {
+        System.out.println("Starting testMissingRequiredFields");
+        for (String reqField : REQUIRED_FIELD_NAMES) {
+            System.out.println("testing missing required field: " + reqField);
+            var developerInfoEle =
+                    TestUtils.getElementsFromResource(
+                            Paths.get(DEVELOPER_INFO_HR_PATH, ALL_FIELDS_VALID_FILE_NAME));
+            developerInfoEle.get(0).removeAttribute(reqField);
+
+            assertThrows(
+                    MalformedXmlException.class,
+                    () -> new DeveloperInfoFactory().createFromHrElements(developerInfoEle));
+        }
+    }
+
+    /** Tests missing optional fields passes. */
+    @Test
+    public void testMissingOptionalFields() throws Exception {
+        for (String optField : OPTIONAL_FIELD_NAMES) {
+            var developerInfoEle =
+                    TestUtils.getElementsFromResource(
+                            Paths.get(DEVELOPER_INFO_HR_PATH, ALL_FIELDS_VALID_FILE_NAME));
+            developerInfoEle.get(0).removeAttribute(optField);
+            DeveloperInfo developerInfo =
+                    new DeveloperInfoFactory().createFromHrElements(developerInfoEle);
+            developerInfo.toOdDomElements(mDoc);
+        }
+    }
+
+    private void testHrToOdDeveloperInfo(String fileName) throws Exception {
+        TestUtils.testHrToOd(
+                mDoc,
+                new DeveloperInfoFactory(),
+                DEVELOPER_INFO_HR_PATH,
+                DEVELOPER_INFO_OD_PATH,
+                fileName);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java
new file mode 100644
index 0000000..b62620e
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib.marshallable;
+
+import com.android.asllib.testutils.TestUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.w3c.dom.Document;
+
+@RunWith(JUnit4.class)
+public class SafetyLabelsTest {
+    private static final String SAFETY_LABELS_HR_PATH = "com/android/asllib/safetylabels/hr";
+    private static final String SAFETY_LABELS_OD_PATH = "com/android/asllib/safetylabels/od";
+
+    private static final String MISSING_VERSION_FILE_NAME = "missing-version.xml";
+    private static final String VALID_EMPTY_FILE_NAME = "valid-empty.xml";
+    private static final String WITH_DATA_LABELS_FILE_NAME = "with-data-labels.xml";
+
+    private Document mDoc = null;
+
+    @Before
+    public void setUp() throws Exception {
+        System.out.println("set up.");
+        mDoc = TestUtils.document();
+    }
+
+    /** Test for safety labels missing version. */
+    @Test
+    public void testSafetyLabelsMissingVersion() throws Exception {
+        System.out.println("starting testSafetyLabelsMissingVersion.");
+        hrToOdExpectException(MISSING_VERSION_FILE_NAME);
+    }
+
+    /** Test for safety labels valid empty. */
+    @Test
+    public void testSafetyLabelsValidEmptyFile() throws Exception {
+        System.out.println("starting testSafetyLabelsValidEmptyFile.");
+        testHrToOdSafetyLabels(VALID_EMPTY_FILE_NAME);
+    }
+
+    /** Test for safety labels with data labels. */
+    @Test
+    public void testSafetyLabelsWithDataLabels() throws Exception {
+        System.out.println("starting testSafetyLabelsWithDataLabels.");
+        testHrToOdSafetyLabels(WITH_DATA_LABELS_FILE_NAME);
+    }
+
+    private void hrToOdExpectException(String fileName) {
+        TestUtils.hrToOdExpectException(new SafetyLabelsFactory(), SAFETY_LABELS_HR_PATH, fileName);
+    }
+
+    private void testHrToOdSafetyLabels(String fileName) throws Exception {
+        TestUtils.testHrToOd(
+                mDoc,
+                new SafetyLabelsFactory(),
+                SAFETY_LABELS_HR_PATH,
+                SAFETY_LABELS_OD_PATH,
+                fileName);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SystemAppSafetyLabelTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SystemAppSafetyLabelTest.java
new file mode 100644
index 0000000..191091a
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SystemAppSafetyLabelTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib.marshallable;
+
+import com.android.asllib.testutils.TestUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.w3c.dom.Document;
+
+@RunWith(JUnit4.class)
+public class SystemAppSafetyLabelTest {
+    private static final String SYSTEM_APP_SAFETY_LABEL_HR_PATH =
+            "com/android/asllib/systemappsafetylabel/hr";
+    private static final String SYSTEM_APP_SAFETY_LABEL_OD_PATH =
+            "com/android/asllib/systemappsafetylabel/od";
+
+    private static final String VALID_FILE_NAME = "valid.xml";
+    private static final String MISSING_URL_FILE_NAME = "missing-url.xml";
+
+    private Document mDoc = null;
+
+    /** Logic for setting up tests (empty if not yet needed). */
+    public static void main(String[] params) throws Exception {}
+
+    @Before
+    public void setUp() throws Exception {
+        System.out.println("set up.");
+        mDoc = TestUtils.document();
+    }
+
+    /** Test for valid. */
+    @Test
+    public void testValid() throws Exception {
+        System.out.println("starting testValid.");
+        testHrToOdSystemAppSafetyLabel(VALID_FILE_NAME);
+    }
+
+    /** Tests missing url. */
+    @Test
+    public void testMissingUrl() throws Exception {
+        System.out.println("starting testMissingUrl.");
+        hrToOdExpectException(MISSING_URL_FILE_NAME);
+    }
+
+    private void hrToOdExpectException(String fileName) {
+        TestUtils.hrToOdExpectException(
+                new SystemAppSafetyLabelFactory(), SYSTEM_APP_SAFETY_LABEL_HR_PATH, fileName);
+    }
+
+    private void testHrToOdSystemAppSafetyLabel(String fileName) throws Exception {
+        TestUtils.testHrToOd(
+                mDoc,
+                new SystemAppSafetyLabelFactory(),
+                SYSTEM_APP_SAFETY_LABEL_HR_PATH,
+                SYSTEM_APP_SAFETY_LABEL_OD_PATH,
+                fileName);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java
new file mode 100644
index 0000000..56503f7
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/TransparencyInfoTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib.marshallable;
+
+import com.android.asllib.testutils.TestUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.w3c.dom.Document;
+
+@RunWith(JUnit4.class)
+public class TransparencyInfoTest {
+    private static final String TRANSPARENCY_INFO_HR_PATH =
+            "com/android/asllib/transparencyinfo/hr";
+    private static final String TRANSPARENCY_INFO_OD_PATH =
+            "com/android/asllib/transparencyinfo/od";
+
+    private static final String VALID_EMPTY_FILE_NAME = "valid-empty.xml";
+    private static final String WITH_DEVELOPER_INFO_FILE_NAME = "with-developer-info.xml";
+    private static final String WITH_APP_INFO_FILE_NAME = "with-app-info.xml";
+
+    private Document mDoc = null;
+
+    @Before
+    public void setUp() throws Exception {
+        System.out.println("set up.");
+        mDoc = TestUtils.document();
+    }
+
+    /** Test for transparency info valid empty. */
+    @Test
+    public void testTransparencyInfoValidEmptyFile() throws Exception {
+        System.out.println("starting testTransparencyInfoValidEmptyFile.");
+        testHrToOdTransparencyInfo(VALID_EMPTY_FILE_NAME);
+    }
+
+    /** Test for transparency info with developer info. */
+    @Test
+    public void testTransparencyInfoWithDeveloperInfo() throws Exception {
+        System.out.println("starting testTransparencyInfoWithDeveloperInfo.");
+        testHrToOdTransparencyInfo(WITH_DEVELOPER_INFO_FILE_NAME);
+    }
+
+    /** Test for transparency info with app info. */
+    @Test
+    public void testTransparencyInfoWithAppInfo() throws Exception {
+        System.out.println("starting testTransparencyInfoWithAppInfo.");
+        testHrToOdTransparencyInfo(WITH_APP_INFO_FILE_NAME);
+    }
+
+    private void testHrToOdTransparencyInfo(String fileName) throws Exception {
+        TestUtils.testHrToOd(
+                mDoc,
+                new TransparencyInfoFactory(),
+                TRANSPARENCY_INFO_HR_PATH,
+                TRANSPARENCY_INFO_OD_PATH,
+                fileName);
+    }
+}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/testutils/TestUtils.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/testutils/TestUtils.java
new file mode 100644
index 0000000..faea340
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/testutils/TestUtils.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.asllib.testutils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+
+import com.android.asllib.marshallable.AslMarshallable;
+import com.android.asllib.marshallable.AslMarshallableFactory;
+import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+public class TestUtils {
+    public static final String HOLDER_TAG_NAME = "holder_of_flattened_for_testing";
+
+    /** Reads a Resource file into a String. */
+    public static String readStrFromResource(Path filePath) throws IOException {
+        InputStream hrStream =
+                TestUtils.class.getClassLoader().getResourceAsStream(filePath.toString());
+        return new String(hrStream.readAllBytes(), StandardCharsets.UTF_8);
+    }
+
+    /** Gets List of Element from a path to an existing Resource. */
+    public static List<Element> getElementsFromResource(Path filePath)
+            throws ParserConfigurationException, IOException, SAXException {
+        String str = readStrFromResource(filePath);
+        InputStream stream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
+
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document document = factory.newDocumentBuilder().parse(stream);
+        Element root = document.getDocumentElement();
+        if (root.getTagName().equals(HOLDER_TAG_NAME)) {
+            String tagName =
+                    XmlUtils.asElementList(root.getChildNodes()).stream()
+                            .findFirst()
+                            .get()
+                            .getTagName();
+            return XmlUtils.asElementList(root.getElementsByTagName(tagName));
+        } else {
+            return List.of(root);
+        }
+    }
+
+    /** Reads a Document into a String. */
+    public static String docToStr(Document doc, boolean omitXmlDeclaration)
+            throws TransformerException {
+        TransformerFactory transformerFactory = TransformerFactory.newInstance();
+        Transformer transformer = transformerFactory.newTransformer();
+        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+        transformer.setOutputProperty(
+                OutputKeys.OMIT_XML_DECLARATION, omitXmlDeclaration ? "yes" : "no");
+
+        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+        StreamResult streamResult = new StreamResult(outStream); // out
+        DOMSource domSource = new DOMSource(doc);
+        transformer.transform(domSource, streamResult);
+
+        return outStream.toString(StandardCharsets.UTF_8);
+    }
+
+    /**
+     * Gets formatted XML for slightly more robust comparison checking than naive string comparison.
+     */
+    public static String getFormattedXml(String xmlStr, boolean omitXmlDeclaration)
+            throws ParserConfigurationException, IOException, SAXException, TransformerException {
+        InputStream stream = new ByteArrayInputStream(xmlStr.getBytes(StandardCharsets.UTF_8));
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document document = factory.newDocumentBuilder().parse(stream);
+
+        return docToStr(document, omitXmlDeclaration);
+    }
+
+    /** Helper for getting a new Document */
+    public static Document document() throws ParserConfigurationException {
+        return DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+    }
+
+    /** Helper for testing human-readable to on-device conversion expecting exception */
+    public static <T extends AslMarshallable> void hrToOdExpectException(
+            AslMarshallableFactory<T> factory, String hrFolderPath, String fileName) {
+        assertThrows(
+                MalformedXmlException.class,
+                () -> {
+                    factory.createFromHrElements(
+                            TestUtils.getElementsFromResource(Paths.get(hrFolderPath, fileName)));
+                });
+    }
+
+    /** Helper for testing human-readable to on-device conversion */
+    public static <T extends AslMarshallable> void testHrToOd(
+            Document doc,
+            AslMarshallableFactory<T> factory,
+            String hrFolderPath,
+            String odFolderPath,
+            String fileName)
+            throws Exception {
+        AslMarshallable marshallable =
+                factory.createFromHrElements(
+                        TestUtils.getElementsFromResource(Paths.get(hrFolderPath, fileName)));
+
+        for (var child : marshallable.toOdDomElements(doc)) {
+            doc.appendChild(child);
+        }
+        String converted = TestUtils.docToStr(doc, true);
+        System.out.println("converted: " + converted);
+
+        String expectedOdContents =
+                TestUtils.readStrFromResource(Paths.get(odFolderPath, fileName));
+        assertEquals(
+                TestUtils.getFormattedXml(expectedOdContents, true),
+                TestUtils.getFormattedXml(converted, true));
+    }
+}
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/missing-version.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/missing-version.xml
new file mode 100644
index 0000000..ec0cd70
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/missing-version.xml
@@ -0,0 +1,3 @@
+<app-metadata-bundles>
+
+</app-metadata-bundles>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/valid-empty.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/valid-empty.xml
new file mode 100644
index 0000000..19bfd82
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/valid-empty.xml
@@ -0,0 +1 @@
+<app-metadata-bundles version="123456"></app-metadata-bundles>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml
new file mode 100644
index 0000000..53794a1
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-safety-labels.xml
@@ -0,0 +1,4 @@
+<app-metadata-bundles version="123456">
+    <safety-labels version="12345">
+    </safety-labels>
+</app-metadata-bundles>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-system-app-safety-label.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-system-app-safety-label.xml
new file mode 100644
index 0000000..7bcde45
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-system-app-safety-label.xml
@@ -0,0 +1,4 @@
+<app-metadata-bundles version="123456">
+<system-app-safety-label url="www.example.com">
+</system-app-safety-label>
+</app-metadata-bundles>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-transparency-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-transparency-info.xml
new file mode 100644
index 0000000..00bcfa8
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/hr/with-transparency-info.xml
@@ -0,0 +1,4 @@
+<app-metadata-bundles version="123456">
+<transparency-info>
+</transparency-info>
+</app-metadata-bundles>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/valid-empty.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/valid-empty.xml
new file mode 100644
index 0000000..37bdfad
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/valid-empty.xml
@@ -0,0 +1,3 @@
+<bundle>
+    <long name="version" value="123456"/>
+</bundle>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml
new file mode 100644
index 0000000..74644ed
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-safety-labels.xml
@@ -0,0 +1,6 @@
+<bundle>
+    <long name="version" value="123456"/>
+    <pbundle_as_map name="safety_labels">
+        <long name="version" value="12345"/>
+    </pbundle_as_map>
+</bundle>
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-system-app-safety-label.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-system-app-safety-label.xml
new file mode 100644
index 0000000..ef0f549
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-system-app-safety-label.xml
@@ -0,0 +1,6 @@
+<bundle>
+    <long name="version" value="123456"/>
+    <pbundle_as_map name="system_app_safety_label">
+        <string name="url" value="www.example.com"/>
+    </pbundle_as_map>
+</bundle>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-transparency-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-transparency-info.xml
new file mode 100644
index 0000000..63c5094
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/androidsafetylabel/od/with-transparency-info.xml
@@ -0,0 +1,4 @@
+<bundle>
+    <long name="version" value="123456"/>
+    <pbundle_as_map name="transparency_info"/>
+</bundle>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml
new file mode 100644
index 0000000..883170a2
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/hr/all-fields-valid.xml
@@ -0,0 +1,14 @@
+<app-info
+    title="beervision"
+    description="a beer app"
+    containsAds="true"
+    obeyAps="false"
+    adsFingerprinting="false"
+    securityFingerprinting="false"
+    privacyPolicy="www.example.com"
+    securityEndpoints="url1|url2|url3"
+    firstPartyEndpoints="url1"
+    serviceProviderEndpoints="url55|url56"
+    category="Food and drink"
+    email="max@maxloh.com"
+    website="www.example.com" />
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml
new file mode 100644
index 0000000..6e976a3
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/appinfo/od/all-fields-valid.xml
@@ -0,0 +1,25 @@
+
+<pbundle_as_map name="app_info">
+    <string name="title" value="beervision"/>
+    <string name="description" value="a beer app"/>
+    <boolean name="contains_ads" value="true"/>
+    <boolean name="obey_aps" value="false"/>
+    <boolean name="ads_fingerprinting" value="false"/>
+    <boolean name="security_fingerprinting" value="false"/>
+    <string name="privacy_policy" value="www.example.com"/>
+    <string-array name="security_endpoint" num="3">
+        <item value="url1"/>
+        <item value="url2"/>
+        <item value="url3"/>
+    </string-array>
+    <string-array name="first_party_endpoint" num="1">
+        <item value="url1"/>
+    </string-array>
+    <string-array name="service_provider_endpoint" num="2">
+        <item value="url55"/>
+        <item value="url56"/>
+    </string-array>
+    <string name="category" value="Food and drink"/>
+    <string name="email" value="max@maxloh.com"/>
+    <string name="website" value="www.example.com"/>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-actions-in-app.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-actions-in-app.xml
new file mode 100644
index 0000000..520e525
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-actions-in-app.xml
@@ -0,0 +1,17 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="actions_in_app"
+        dataType="user_interaction"
+        purposes="analytics" />
+    <data-shared dataCategory="actions_in_app"
+        dataType="in_app_search_history"
+        purposes="analytics" />
+    <data-shared dataCategory="actions_in_app"
+        dataType="installed_apps"
+        purposes="analytics" />
+    <data-shared dataCategory="actions_in_app"
+        dataType="user_generated_content"
+        purposes="analytics" />
+    <data-shared dataCategory="actions_in_app"
+        dataType="other"
+        purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-app-performance.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-app-performance.xml
new file mode 100644
index 0000000..0d08e5b
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-app-performance.xml
@@ -0,0 +1,11 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="app_performance"
+        dataType="crash_logs"
+        purposes="analytics" />
+    <data-shared dataCategory="app_performance"
+        dataType="performance_diagnostics"
+        purposes="analytics" />
+    <data-shared dataCategory="app_performance"
+        dataType="other"
+        purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-audio.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-audio.xml
new file mode 100644
index 0000000..b1cf3b4
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-audio.xml
@@ -0,0 +1,11 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="audio"
+        dataType="sound_recordings"
+        purposes="analytics" />
+    <data-shared dataCategory="audio"
+        dataType="music_files"
+        purposes="analytics" />
+    <data-shared dataCategory="audio"
+        dataType="other"
+        purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-calendar.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-calendar.xml
new file mode 100644
index 0000000..a723070
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-calendar.xml
@@ -0,0 +1,5 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="calendar"
+        dataType="calendar"
+        purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-contacts.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-contacts.xml
new file mode 100644
index 0000000..2fe28ff
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-contacts.xml
@@ -0,0 +1,5 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="contacts"
+        dataType="contacts"
+        purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-email-text-message.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-email-text-message.xml
new file mode 100644
index 0000000..49a326f
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-email-text-message.xml
@@ -0,0 +1,11 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="email_text_message"
+        dataType="emails"
+        purposes="analytics" />
+    <data-shared dataCategory="email_text_message"
+        dataType="text_messages"
+        purposes="analytics" />
+    <data-shared dataCategory="email_text_message"
+        dataType="other"
+        purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-financial.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-financial.xml
new file mode 100644
index 0000000..f5de370
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-financial.xml
@@ -0,0 +1,14 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="financial"
+        dataType="card_bank_account"
+        purposes="analytics" />
+    <data-shared dataCategory="financial"
+    dataType="purchase_history"
+    purposes="analytics" />
+    <data-shared dataCategory="financial"
+        dataType="credit_score"
+        purposes="analytics" />
+    <data-shared dataCategory="financial"
+        dataType="other"
+        purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-health-fitness.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-health-fitness.xml
new file mode 100644
index 0000000..9891f81
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-health-fitness.xml
@@ -0,0 +1,8 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="health_fitness"
+        dataType="health"
+        purposes="analytics" />
+    <data-shared dataCategory="health_fitness"
+        dataType="fitness"
+        purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-identifiers.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-identifiers.xml
new file mode 100644
index 0000000..3e74da1
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-identifiers.xml
@@ -0,0 +1,5 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="identifiers"
+        dataType="other"
+        purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-location.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-location.xml
new file mode 100644
index 0000000..4762f16
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-location.xml
@@ -0,0 +1,8 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="location"
+        dataType="approx_location"
+        purposes="analytics" />
+    <data-shared dataCategory="location"
+        dataType="precise_location"
+        purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal-empty-purpose.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal-empty-purpose.xml
new file mode 100644
index 0000000..964e178
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal-empty-purpose.xml
@@ -0,0 +1,5 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="personal"
+    dataType="email_address"
+    purposes="" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal-missing-purpose.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal-missing-purpose.xml
new file mode 100644
index 0000000..3ce1288
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal-missing-purpose.xml
@@ -0,0 +1,4 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="personal"
+    dataType="email_address" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal-partial.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal-partial.xml
new file mode 100644
index 0000000..68baae3
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal-partial.xml
@@ -0,0 +1,8 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="personal"
+        dataType="name"
+        purposes="analytics|developer_communications" />
+    <data-shared dataCategory="personal"
+    dataType="email_address"
+    purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal-unrecognized-type.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal-unrecognized-type.xml
new file mode 100644
index 0000000..921a90a
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal-unrecognized-type.xml
@@ -0,0 +1,5 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="personal"
+    dataType="unrecognized"
+    purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal.xml
new file mode 100644
index 0000000..4533773
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-personal.xml
@@ -0,0 +1,31 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="personal"
+        dataType="name"
+        ephemeral="true"
+        isCollectionOptional="true"
+        purposes="analytics|developer_communications" />
+    <data-shared dataCategory="personal"
+    dataType="email_address"
+    purposes="analytics" />
+    <data-shared dataCategory="personal"
+    dataType="physical_address"
+    purposes="analytics" />
+    <data-shared dataCategory="personal"
+    dataType="phone_number"
+    purposes="analytics" />
+    <data-shared dataCategory="personal"
+    dataType="race_ethnicity"
+    purposes="analytics" />
+    <data-shared dataCategory="personal"
+    dataType="political_or_religious_beliefs"
+    purposes="analytics" />
+    <data-shared dataCategory="personal"
+    dataType="sexual_orientation_or_gender_identity"
+    purposes="analytics" />
+    <data-shared dataCategory="personal"
+    dataType="personal_identifiers"
+    purposes="analytics" />
+    <data-shared dataCategory="personal"
+    dataType="other"
+    purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-photo-video.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-photo-video.xml
new file mode 100644
index 0000000..234fb26
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-photo-video.xml
@@ -0,0 +1,8 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="photo_video"
+        dataType="photos"
+        purposes="analytics" />
+    <data-shared dataCategory="photo_video"
+        dataType="videos"
+        purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-search-and-browsing.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-search-and-browsing.xml
new file mode 100644
index 0000000..db85163
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-search-and-browsing.xml
@@ -0,0 +1,5 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="search_and_browsing"
+        dataType="web_browsing_history"
+        purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-storage.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-storage.xml
new file mode 100644
index 0000000..9aad02d
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-storage.xml
@@ -0,0 +1,5 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="storage"
+        dataType="files_docs"
+        purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-unrecognized.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-unrecognized.xml
new file mode 100644
index 0000000..64b9ea7
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/hr/data-category-unrecognized.xml
@@ -0,0 +1,5 @@
+<holder_of_flattened_for_testing>
+    <data-shared dataCategory="unrecognized"
+    dataType="email_address"
+    purposes="analytics" />
+</holder_of_flattened_for_testing>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-actions-in-app.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-actions-in-app.xml
new file mode 100644
index 0000000..5b99900
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-actions-in-app.xml
@@ -0,0 +1,27 @@
+<pbundle_as_map name="actions_in_app">
+    <pbundle_as_map name="user_interaction">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="in_app_search_history">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="installed_apps">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="user_generated_content">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="other">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-app-performance.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-app-performance.xml
new file mode 100644
index 0000000..0fe1022
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-app-performance.xml
@@ -0,0 +1,17 @@
+<pbundle_as_map name="app_performance">
+    <pbundle_as_map name="crash_logs">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="performance_diagnostics">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="other">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-audio.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-audio.xml
new file mode 100644
index 0000000..51f1dfd
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-audio.xml
@@ -0,0 +1,17 @@
+<pbundle_as_map name="audio">
+    <pbundle_as_map name="sound_recordings">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="music_files">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="other">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-calendar.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-calendar.xml
new file mode 100644
index 0000000..326da47
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-calendar.xml
@@ -0,0 +1,7 @@
+<pbundle_as_map name="calendar">
+    <pbundle_as_map name="calendar">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-contacts.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-contacts.xml
new file mode 100644
index 0000000..5d4387d
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-contacts.xml
@@ -0,0 +1,7 @@
+<pbundle_as_map name="contacts">
+    <pbundle_as_map name="contacts">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-email-text-message.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-email-text-message.xml
new file mode 100644
index 0000000..5ac98f5
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-email-text-message.xml
@@ -0,0 +1,17 @@
+<pbundle_as_map name="email_text_message">
+    <pbundle_as_map name="emails">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="text_messages">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="other">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-financial.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-financial.xml
new file mode 100644
index 0000000..a66f1a4
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-financial.xml
@@ -0,0 +1,22 @@
+<pbundle_as_map name="financial">
+    <pbundle_as_map name="card_bank_account">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="purchase_history">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="credit_score">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="other">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-health-fitness.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-health-fitness.xml
new file mode 100644
index 0000000..8e697b4
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-health-fitness.xml
@@ -0,0 +1,12 @@
+<pbundle_as_map name="health_fitness">
+    <pbundle_as_map name="health">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="fitness">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-identifiers.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-identifiers.xml
new file mode 100644
index 0000000..34b4016
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-identifiers.xml
@@ -0,0 +1,7 @@
+<pbundle_as_map name="identifiers">
+    <pbundle_as_map name="other">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-location.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-location.xml
new file mode 100644
index 0000000..db2e696
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-location.xml
@@ -0,0 +1,12 @@
+<pbundle_as_map name="location">
+    <pbundle_as_map name="approx_location">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="precise_location">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-personal-partial.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-personal-partial.xml
new file mode 100644
index 0000000..839922a
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-personal-partial.xml
@@ -0,0 +1,13 @@
+<pbundle_as_map name="personal">
+    <pbundle_as_map name="name">
+        <int-array name="purposes" num="2">
+            <item value="2" />
+            <item value="3" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="email_address">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-personal.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-personal.xml
new file mode 100644
index 0000000..43650b6
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-personal.xml
@@ -0,0 +1,50 @@
+<pbundle_as_map name="personal">
+    <pbundle_as_map name="name">
+        <int-array name="purposes" num="2">
+            <item value="2" />
+            <item value="3" />
+        </int-array>
+        <boolean name="is_collection_optional" value="true" />
+        <boolean name="ephemeral" value="true" />
+    </pbundle_as_map>
+    <pbundle_as_map name="email_address">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="physical_address">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="phone_number">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="race_ethnicity">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="political_or_religious_beliefs">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="sexual_orientation_or_gender_identity">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="personal_identifiers">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="other">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-photo-video.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-photo-video.xml
new file mode 100644
index 0000000..2a31780
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-photo-video.xml
@@ -0,0 +1,12 @@
+<pbundle_as_map name="photo_video">
+    <pbundle_as_map name="photos">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+    <pbundle_as_map name="videos">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-search-and-browsing.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-search-and-browsing.xml
new file mode 100644
index 0000000..9e654ef
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-search-and-browsing.xml
@@ -0,0 +1,7 @@
+<pbundle_as_map name="search_and_browsing">
+    <pbundle_as_map name="web_browsing_history">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-storage.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-storage.xml
new file mode 100644
index 0000000..9abc37f
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datacategory/od/data-category-storage.xml
@@ -0,0 +1,7 @@
+<pbundle_as_map name="storage">
+    <pbundle_as_map name="files_docs">
+        <int-array name="purposes" num="1">
+            <item value="2" />
+        </int-array>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-accessed-invalid-bool.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-accessed-invalid-bool.xml
new file mode 100644
index 0000000..bb45f42
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-accessed-invalid-bool.xml
@@ -0,0 +1,7 @@
+<data-labels>
+    <data-accessed dataCategory="location"
+        dataType="approx_location"
+        ephemeral="false"
+        isSharingOptional="false"
+        purposes="app_functionality" />
+</data-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-accessed-valid-bool.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-accessed-valid-bool.xml
new file mode 100644
index 0000000..f927bba
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-accessed-valid-bool.xml
@@ -0,0 +1,6 @@
+<data-labels>
+    <data-accessed dataCategory="location"
+        dataType="approx_location"
+        ephemeral="false"
+        purposes="app_functionality" />
+</data-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-collected-invalid-bool.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-collected-invalid-bool.xml
new file mode 100644
index 0000000..ba11afb
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-collected-invalid-bool.xml
@@ -0,0 +1,7 @@
+<data-labels>
+    <data-collected dataCategory="location"
+        dataType="approx_location"
+        ephemeral="false"
+        isSharingOptional="false"
+        purposes="app_functionality" />
+</data-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-collected-valid-bool.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-collected-valid-bool.xml
new file mode 100644
index 0000000..4b6d3977
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-collected-valid-bool.xml
@@ -0,0 +1,7 @@
+<data-labels>
+    <data-collected dataCategory="location"
+        dataType="approx_location"
+        ephemeral="false"
+        isCollectionOptional="false"
+        purposes="app_functionality" />
+</data-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-shared-invalid-bool.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-shared-invalid-bool.xml
new file mode 100644
index 0000000..7840b98
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-shared-invalid-bool.xml
@@ -0,0 +1,7 @@
+<data-labels>
+    <data-shared dataCategory="location"
+        dataType="approx_location"
+        ephemeral="false"
+        isCollectionOptional="false"
+        purposes="app_functionality" />
+</data-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-shared-valid-bool.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-shared-valid-bool.xml
new file mode 100644
index 0000000..ccf77b0
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/hr/data-labels-shared-valid-bool.xml
@@ -0,0 +1,7 @@
+<data-labels>
+    <data-shared dataCategory="location"
+        dataType="approx_location"
+        ephemeral="false"
+        isSharingOptional="false"
+        purposes="app_functionality" />
+</data-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/od/data-labels-accessed-valid-bool.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/od/data-labels-accessed-valid-bool.xml
new file mode 100644
index 0000000..ddefc18
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/od/data-labels-accessed-valid-bool.xml
@@ -0,0 +1,12 @@
+<pbundle_as_map name="data_labels">
+    <pbundle_as_map name="data_accessed">
+        <pbundle_as_map name="location">
+            <pbundle_as_map name="approx_location">
+                <int-array name="purposes" num="1">
+                    <item value="1"/>
+                </int-array>
+                <boolean name="ephemeral" value="false"/>
+            </pbundle_as_map>
+        </pbundle_as_map>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/od/data-labels-collected-valid-bool.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/od/data-labels-collected-valid-bool.xml
new file mode 100644
index 0000000..252c728
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/od/data-labels-collected-valid-bool.xml
@@ -0,0 +1,13 @@
+<pbundle_as_map name="data_labels">
+    <pbundle_as_map name="data_collected">
+        <pbundle_as_map name="location">
+            <pbundle_as_map name="approx_location">
+                <int-array name="purposes" num="1">
+                    <item value="1"/>
+                </int-array>
+                <boolean name="is_collection_optional" value="false"/>
+                <boolean name="ephemeral" value="false"/>
+            </pbundle_as_map>
+        </pbundle_as_map>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/od/data-labels-shared-valid-bool.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/od/data-labels-shared-valid-bool.xml
new file mode 100644
index 0000000..d1d4e33
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/datalabels/od/data-labels-shared-valid-bool.xml
@@ -0,0 +1,13 @@
+<pbundle_as_map name="data_labels">
+    <pbundle_as_map name="data_shared">
+        <pbundle_as_map name="location">
+            <pbundle_as_map name="approx_location">
+                <int-array name="purposes" num="1">
+                    <item value="1"/>
+                </int-array>
+                <boolean name="is_sharing_optional" value="false"/>
+                <boolean name="ephemeral" value="false"/>
+            </pbundle_as_map>
+        </pbundle_as_map>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/developerinfo/hr/all-fields-valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/developerinfo/hr/all-fields-valid.xml
new file mode 100644
index 0000000..908d8ea2
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/developerinfo/hr/all-fields-valid.xml
@@ -0,0 +1,8 @@
+<developer-info
+    name="max"
+    email="max@example.com"
+    address="111 blah lane"
+    countryRegion="US"
+    relationship="aosp"
+    website="example.com"
+    registryId="registry_id" />
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/developerinfo/od/all-fields-valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/developerinfo/od/all-fields-valid.xml
new file mode 100644
index 0000000..784ec61
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/developerinfo/od/all-fields-valid.xml
@@ -0,0 +1,9 @@
+<pbundle_as_map name="developer_info">
+    <string name="name" value="max"/>
+    <string name="email" value="max@example.com"/>
+    <string name="address" value="111 blah lane"/>
+    <string name="country_region" value="US"/>
+    <long name="relationship" value="5"/>
+    <string name="website" value="example.com"/>
+    <string name="app_developer_registry_id" value="registry_id"/>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/missing-version.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/missing-version.xml
new file mode 100644
index 0000000..762f3bd
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/missing-version.xml
@@ -0,0 +1,2 @@
+<safety-labels>
+</safety-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/valid-empty.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/valid-empty.xml
new file mode 100644
index 0000000..7decfd4
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/valid-empty.xml
@@ -0,0 +1 @@
+<safety-labels version="12345"></safety-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-data-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-data-labels.xml
new file mode 100644
index 0000000..8997f4f
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-data-labels.xml
@@ -0,0 +1,9 @@
+<safety-labels version="12345">
+    <data-labels>
+        <data-shared dataCategory="location"
+            dataType="approx_location"
+            isSharingOptional="false"
+            ephemeral="false"
+            purposes="app_functionality" />
+    </data-labels>
+</safety-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/valid-empty.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/valid-empty.xml
new file mode 100644
index 0000000..4f03d88
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/valid-empty.xml
@@ -0,0 +1,3 @@
+<pbundle_as_map name="safety_labels">
+    <long name="version" value="12345"/>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-data-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-data-labels.xml
new file mode 100644
index 0000000..a966fda
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-data-labels.xml
@@ -0,0 +1,16 @@
+<pbundle_as_map name="safety_labels">
+    <long name="version" value="12345"/>
+    <pbundle_as_map name="data_labels">
+        <pbundle_as_map name="data_shared">
+            <pbundle_as_map name="location">
+                <pbundle_as_map name="approx_location">
+                    <int-array name="purposes" num="1">
+                        <item value="1"/>
+                    </int-array>
+                    <boolean name="is_sharing_optional" value="false"/>
+                    <boolean name="ephemeral" value="false"/>
+                </pbundle_as_map>
+            </pbundle_as_map>
+        </pbundle_as_map>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/systemappsafetylabel/hr/missing-url.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/systemappsafetylabel/hr/missing-url.xml
new file mode 100644
index 0000000..ff26c05
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/systemappsafetylabel/hr/missing-url.xml
@@ -0,0 +1 @@
+<system-app-safety-label></system-app-safety-label>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/systemappsafetylabel/hr/valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/systemappsafetylabel/hr/valid.xml
new file mode 100644
index 0000000..6fe86c3
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/systemappsafetylabel/hr/valid.xml
@@ -0,0 +1 @@
+<system-app-safety-label url="www.example.com"></system-app-safety-label>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/systemappsafetylabel/od/valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/systemappsafetylabel/od/valid.xml
new file mode 100644
index 0000000..f96535b
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/systemappsafetylabel/od/valid.xml
@@ -0,0 +1,3 @@
+<pbundle_as_map name="system_app_safety_label">
+    <string name="url" value="www.example.com"/>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/valid-empty.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/valid-empty.xml
new file mode 100644
index 0000000..254a37f
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/valid-empty.xml
@@ -0,0 +1,4 @@
+
+<transparency-info>
+
+</transparency-info>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml
new file mode 100644
index 0000000..a7c48fc
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-app-info.xml
@@ -0,0 +1,4 @@
+
+<transparency-info>
+    <app-info title="beervision" description="a beer app" containsAds="true" obeyAps="false" adsFingerprinting="false" securityFingerprinting="false" privacyPolicy="www.example.com" securityEndpoints="url1|url2|url3" firstPartyEndpoints="url1" serviceProviderEndpoints="url55|url56" category="Food and drink" email="max@maxloh.com" />
+</transparency-info>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-developer-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-developer-info.xml
new file mode 100644
index 0000000..862bda4
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/hr/with-developer-info.xml
@@ -0,0 +1,11 @@
+
+<transparency-info>
+    <developer-info
+        name="max"
+        email="max@example.com"
+        address="111 blah lane"
+        countryRegion="US"
+        relationship="aosp"
+        website="example.com"
+        appDeveloperRegistryId="registry_id" />
+</transparency-info>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/valid-empty.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/valid-empty.xml
new file mode 100644
index 0000000..af574cf
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/valid-empty.xml
@@ -0,0 +1 @@
+<pbundle_as_map name="transparency_info"/>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml
new file mode 100644
index 0000000..b813641
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-app-info.xml
@@ -0,0 +1,26 @@
+
+<pbundle_as_map name="transparency_info">
+    <pbundle_as_map name="app_info">
+        <string name="title" value="beervision"/>
+        <string name="description" value="a beer app"/>
+        <boolean name="contains_ads" value="true"/>
+        <boolean name="obey_aps" value="false"/>
+        <boolean name="ads_fingerprinting" value="false"/>
+        <boolean name="security_fingerprinting" value="false"/>
+        <string name="privacy_policy" value="www.example.com"/>
+        <string-array name="security_endpoint" num="3">
+            <item value="url1"/>
+            <item value="url2"/>
+            <item value="url3"/>
+        </string-array>
+        <string-array name="first_party_endpoint" num="1">
+            <item value="url1"/>
+        </string-array>
+        <string-array name="service_provider_endpoint" num="2">
+            <item value="url55"/>
+            <item value="url56"/>
+        </string-array>
+        <string name="category" value="Food and drink"/>
+        <string name="email" value="max@maxloh.com"/>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-developer-info.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-developer-info.xml
new file mode 100644
index 0000000..101c98b
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/transparencyinfo/od/with-developer-info.xml
@@ -0,0 +1,11 @@
+
+<pbundle_as_map name="transparency_info">
+    <pbundle_as_map name="developer_info">
+        <string name="name" value="max"/>
+        <string name="email" value="max@example.com"/>
+        <string name="address" value="111 blah lane"/>
+        <string name="country_region" value="US"/>
+        <long name="relationship" value="5"/>
+        <string name="website" value="example.com"/>
+    </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/contacts/hr.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/contacts/hr.xml
new file mode 100644
index 0000000..b2ff449
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/contacts/hr.xml
@@ -0,0 +1,11 @@
+<app-metadata-bundles version="123">
+    <safety-labels version="12345">
+        <data-labels>
+            <data-shared dataCategory="contacts"
+                dataType="contacts"
+                isSharingOptional="false"
+                ephemeral="true"
+                purposes="analytics" />
+        </data-labels>
+    </safety-labels>
+</app-metadata-bundles>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/contacts/od.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/contacts/od.xml
new file mode 100644
index 0000000..81277bf
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/contacts/od.xml
@@ -0,0 +1,19 @@
+<bundle>
+    <long name="version" value="123"/>
+    <pbundle_as_map name="safety_labels">
+        <long name="version" value="12345"/>
+        <pbundle_as_map name="data_labels">
+            <pbundle_as_map name="data_shared">
+                <pbundle_as_map name="contacts">
+                    <pbundle_as_map name="contacts">
+                        <int-array name="purposes" num="1">
+                            <item value="2"/>
+                        </int-array>
+                        <boolean name="is_sharing_optional" value="false"/>
+                        <boolean name="ephemeral" value="true"/>
+                    </pbundle_as_map>
+                </pbundle_as_map>
+            </pbundle_as_map>
+        </pbundle_as_map>
+    </pbundle_as_map>
+</bundle>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/location/hr.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/location/hr.xml
new file mode 100644
index 0000000..ac844b3
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/location/hr.xml
@@ -0,0 +1,16 @@
+<app-metadata-bundles version="123">
+    <safety-labels version="12345">
+        <data-labels>
+            <data-shared dataCategory="location"
+                dataType="precise_location"
+                isSharingOptional="true"
+                ephemeral="true"
+                purposes="app_functionality|analytics" />
+            <data-shared dataCategory="location"
+                dataType="approx_location"
+                isSharingOptional="false"
+                ephemeral="false"
+                purposes="app_functionality" />
+        </data-labels>
+    </safety-labels>
+</app-metadata-bundles>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/location/od.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/location/od.xml
new file mode 100644
index 0000000..d0a3bfa
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/location/od.xml
@@ -0,0 +1,27 @@
+<bundle>
+    <long name="version" value="123"/>
+    <pbundle_as_map name="safety_labels">
+        <long name="version" value="12345"/>
+        <pbundle_as_map name="data_labels">
+            <pbundle_as_map name="data_shared">
+                <pbundle_as_map name="location">
+                    <pbundle_as_map name="precise_location">
+                        <int-array name="purposes" num="2">
+                            <item value="1"/>
+                            <item value="2"/>
+                        </int-array>
+                        <boolean name="is_sharing_optional" value="true"/>
+                        <boolean name="ephemeral" value="true"/>
+                    </pbundle_as_map>
+                    <pbundle_as_map name="approx_location">
+                        <int-array name="purposes" num="1">
+                            <item value="1"/>
+                        </int-array>
+                        <boolean name="is_sharing_optional" value="false"/>
+                        <boolean name="ephemeral" value="false"/>
+                    </pbundle_as_map>
+                </pbundle_as_map>
+            </pbundle_as_map>
+        </pbundle_as_map>
+    </pbundle_as_map>
+</bundle>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/test.xml b/tools/app_metadata_bundles/src/test/resources/test.xml
new file mode 100644
index 0000000..202cc1e
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/test.xml
@@ -0,0 +1,16 @@
+<app-metadata-bundles>
+    <safety-labels version="12345">
+        <data-labels>
+            <data-shared dataCategory="location"
+                dataType="precise_location"
+                isSharingOptional="true"
+                ephemeral="true"
+                purposes="app_functionality|analytics" />
+            <data-shared dataCategory="location"
+                dataType="approx_location"
+                isSharingOptional="false"
+                ephemeral="false"
+                purposes="app_functionality" />
+        </data-labels>
+    </safety-labels>
+</app-metadata-bundles>
\ No newline at end of file
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
index 837dae9..0f1373c 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
@@ -24,11 +24,20 @@
 import com.github.javaparser.ParserConfiguration
 import com.github.javaparser.StaticJavaParser
 import com.github.javaparser.ast.CompilationUnit
+import com.github.javaparser.ast.Modifier
 import com.github.javaparser.ast.NodeList
 import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
 import com.github.javaparser.ast.body.InitializerDeclaration
+import com.github.javaparser.ast.expr.ArrayAccessExpr
+import com.github.javaparser.ast.expr.ArrayCreationExpr
+import com.github.javaparser.ast.expr.ArrayInitializerExpr
+import com.github.javaparser.ast.expr.AssignExpr
+import com.github.javaparser.ast.expr.BooleanLiteralExpr
+import com.github.javaparser.ast.expr.Expression
 import com.github.javaparser.ast.expr.FieldAccessExpr
+import com.github.javaparser.ast.expr.IntegerLiteralExpr
 import com.github.javaparser.ast.expr.MethodCallExpr
+import com.github.javaparser.ast.expr.MethodReferenceExpr
 import com.github.javaparser.ast.expr.NameExpr
 import com.github.javaparser.ast.expr.NullLiteralExpr
 import com.github.javaparser.ast.expr.ObjectCreationExpr
@@ -168,6 +177,8 @@
         val classNameNode = classDeclaration.findFirst(SimpleName::class.java).get()
         classNameNode.setId(protoLogImplGenName)
 
+        injectCacheClass(classDeclaration, groups, protoLogGroupsClassName)
+
         injectConstants(classDeclaration,
             viewerConfigFilePath, legacyViewerConfigFilePath, legacyOutputFilePath, groups,
             protoLogGroupsClassName)
@@ -238,6 +249,12 @@
                                     field.setFinal(true)
                                     field.variables.first().setInitializer(treeMapCreation)
                                 }
+                                ProtoLogToolInjected.Value.CACHE_UPDATER.name -> {
+                                    field.setFinal(true)
+                                    field.variables.first().setInitializer(MethodReferenceExpr()
+                                            .setScope(NameExpr("Cache"))
+                                            .setIdentifier("update"))
+                                }
                                 else -> error("Unhandled ProtoLogToolInjected value: $valueName.")
                             }
                         }
@@ -245,6 +262,61 @@
         }
     }
 
+    private fun injectCacheClass(
+        classDeclaration: ClassOrInterfaceDeclaration,
+        groups: Map<String, LogGroup>,
+        protoLogGroupsClassName: String,
+    ) {
+        val cacheClass = ClassOrInterfaceDeclaration()
+            .setName("Cache")
+            .setPublic(true)
+            .setStatic(true)
+        for (group in groups) {
+            val nodeList = NodeList<Expression>()
+            val defaultVal = BooleanLiteralExpr(group.value.textEnabled || group.value.enabled)
+            repeat(LogLevel.entries.size) { nodeList.add(defaultVal) }
+            cacheClass.addFieldWithInitializer(
+                "boolean[]",
+                "${group.key}_enabled",
+                ArrayCreationExpr().setElementType("boolean[]").setInitializer(
+                    ArrayInitializerExpr().setValues(nodeList)
+                ),
+                Modifier.Keyword.PUBLIC,
+                Modifier.Keyword.STATIC
+            )
+        }
+
+        val updateBlockStmt = BlockStmt()
+        for (group in groups) {
+            for (level in LogLevel.entries) {
+                updateBlockStmt.addStatement(
+                    AssignExpr()
+                        .setTarget(
+                            ArrayAccessExpr()
+                                .setName(NameExpr("${group.key}_enabled"))
+                                .setIndex(IntegerLiteralExpr(level.ordinal))
+                        ).setValue(
+                            MethodCallExpr()
+                                .setName("isEnabled")
+                                .setArguments(NodeList(
+                                    FieldAccessExpr()
+                                        .setScope(NameExpr(protoLogGroupsClassName))
+                                        .setName(group.value.name),
+                                    FieldAccessExpr()
+                                        .setScope(NameExpr("LogLevel"))
+                                        .setName(level.toString()),
+                                ))
+                        )
+                )
+            }
+        }
+
+        cacheClass.addMethod("update").setPrivate(true).setStatic(true)
+            .setBody(updateBlockStmt)
+
+        classDeclaration.addMember(cacheClass)
+    }
+
     private fun tryParse(code: String, fileName: String): CompilationUnit {
         try {
             return StaticJavaParser.parse(code)
diff --git a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
index 2b71641..6a8a071 100644
--- a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
@@ -22,6 +22,7 @@
 import com.github.javaparser.ast.CompilationUnit
 import com.github.javaparser.ast.NodeList
 import com.github.javaparser.ast.body.VariableDeclarator
+import com.github.javaparser.ast.expr.ArrayAccessExpr
 import com.github.javaparser.ast.expr.CastExpr
 import com.github.javaparser.ast.expr.Expression
 import com.github.javaparser.ast.expr.FieldAccessExpr
@@ -35,6 +36,8 @@
 import com.github.javaparser.ast.expr.VariableDeclarationExpr
 import com.github.javaparser.ast.stmt.BlockStmt
 import com.github.javaparser.ast.stmt.ExpressionStmt
+import com.github.javaparser.ast.stmt.IfStmt
+import com.github.javaparser.ast.stmt.Statement
 import com.github.javaparser.ast.type.ArrayType
 import com.github.javaparser.ast.type.ClassOrInterfaceType
 import com.github.javaparser.ast.type.PrimitiveType
@@ -74,6 +77,8 @@
 
     private val protoLogImplClassNode =
             StaticJavaParser.parseExpression<FieldAccessExpr>(protoLogImplClassName)
+    private val protoLogImplCacheClassNode =
+        StaticJavaParser.parseExpression<FieldAccessExpr>("$protoLogImplClassName.Cache")
     private var processedCode: MutableList<String> = mutableListOf()
     private var offsets: IntArray = IntArray(0)
     /** The path of the file being processed, relative to $ANDROID_BUILD_TOP */
@@ -121,8 +126,9 @@
         group: LogGroup,
         level: LogLevel,
         messageString: String
-    ): BlockStmt {
+    ): Statement {
         val hash = CodeUtils.hash(packagePath, messageString, level, group)
+
         val newCall = call.clone()
         if (!group.textEnabled) {
             // Remove message string if text logging is not enabled by default.
@@ -166,11 +172,15 @@
         }
         blockStmt.addStatement(ExpressionStmt(newCall))
 
-        return blockStmt
+        val isLogEnabled = ArrayAccessExpr()
+            .setName(NameExpr("$protoLogImplCacheClassNode.${group.name}_enabled"))
+            .setIndex(IntegerLiteralExpr(level.ordinal))
+
+        return IfStmt(isLogEnabled, blockStmt, null)
     }
 
     private fun injectProcessedCallStatementInCode(
-        processedCallStatement: BlockStmt,
+        processedCallStatement: Statement,
         parentStmt: ExpressionStmt
     ) {
         // Inline the new statement.
diff --git a/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt b/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
index de0b5ba..82aa93d 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
@@ -76,7 +76,7 @@
 
             class Test {
                 void test() {
-                    { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
+                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
                 }
             }
             """.trimIndent()
@@ -86,7 +86,7 @@
 
             class Test {
                 void test() {
-                    { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, "test %d %f " + "abc %s\n test", protoLogParam0, protoLogParam1, protoLogParam2); 
+                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, "test %d %f " + "abc %s\n test", protoLogParam0, protoLogParam1, protoLogParam2); 
             
             }
                 }
@@ -98,8 +98,8 @@
 
             class Test {
                 void test() {
-                    { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); } /* ProtoLog.w(TEST_GROUP, "test %d %f", 100, 0.1); */ { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
-                    { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
+                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); } /* ProtoLog.w(TEST_GROUP, "test %d %f", 100, 0.1); */ if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
+                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, "test %d %f", protoLogParam0, protoLogParam1); }
                 }
             }
             """.trimIndent()
@@ -109,7 +109,7 @@
 
             class Test {
                 void test() {
-                    { org.example.ProtoLogImpl.w(TEST_GROUP, 3218600869538902408L, 0, "test", (Object[]) null); }
+                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { org.example.ProtoLogImpl.w(TEST_GROUP, 3218600869538902408L, 0, "test", (Object[]) null); }
                 }
             }
             """.trimIndent()
@@ -119,7 +119,7 @@
 
             class Test {
                 void test() {
-                    { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, null, protoLogParam0, protoLogParam1); }
+                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; org.example.ProtoLogImpl.w(TEST_GROUP, -1473209266730422156L, 9, null, protoLogParam0, protoLogParam1); }
                 }
             }
             """.trimIndent()
@@ -129,7 +129,7 @@
 
             class Test {
                 void test() {
-                    { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, null, protoLogParam0, protoLogParam1, protoLogParam2); 
+                    if (org.example.ProtoLogImpl.Cache.TEST_GROUP_enabled[3]) { long protoLogParam0 = 100; double protoLogParam1 = 0.1; String protoLogParam2 = String.valueOf("test"); org.example.ProtoLogImpl.w(TEST_GROUP, -4447034859795564700L, 9, null, protoLogParam0, protoLogParam1, protoLogParam2); 
             
             }
                 }
diff --git a/wifi/java/src/android/net/wifi/WifiBlobStore.java b/wifi/java/src/android/net/wifi/WifiBlobStore.java
index 8bfaae7..8737c7e9 100644
--- a/wifi/java/src/android/net/wifi/WifiBlobStore.java
+++ b/wifi/java/src/android/net/wifi/WifiBlobStore.java
@@ -16,6 +16,9 @@
 
 package android.net.wifi;
 
+import android.os.ServiceManager;
+import android.security.legacykeystore.ILegacyKeystore;
+
 import com.android.internal.net.ConnectivityBlobStore;
 
 /**
@@ -24,6 +27,7 @@
  */
 public class WifiBlobStore extends ConnectivityBlobStore {
     private static final String DB_NAME = "WifiBlobStore.db";
+    private static final String LEGACY_KEYSTORE_SERVICE_NAME = "android.security.legacykeystore";
     private static WifiBlobStore sInstance;
     private WifiBlobStore() {
         super(DB_NAME);
@@ -36,4 +40,10 @@
         }
         return sInstance;
     }
+
+    /** Returns an interface to access the Legacy Keystore service. */
+    public static ILegacyKeystore getLegacyKeystore() {
+        return ILegacyKeystore.Stub.asInterface(
+                ServiceManager.checkService(LEGACY_KEYSTORE_SERVICE_NAME));
+    }
 }
diff --git a/wifi/java/src/android/net/wifi/WifiKeystore.java b/wifi/java/src/android/net/wifi/WifiKeystore.java
index a06d0ee..2ba7468 100644
--- a/wifi/java/src/android/net/wifi/WifiKeystore.java
+++ b/wifi/java/src/android/net/wifi/WifiKeystore.java
@@ -20,7 +20,6 @@
 import android.annotation.SystemApi;
 import android.os.Binder;
 import android.os.Process;
-import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
 import android.security.legacykeystore.ILegacyKeystore;
 import android.util.Log;
@@ -37,12 +36,6 @@
 @SuppressLint("UnflaggedApi") // Promoting from @SystemApi(MODULE_LIBRARIES)
 public final class WifiKeystore {
     private static final String TAG = "WifiKeystore";
-    private static final String LEGACY_KEYSTORE_SERVICE_NAME = "android.security.legacykeystore";
-
-    private static ILegacyKeystore getLegacyKeystore() {
-        return ILegacyKeystore.Stub.asInterface(
-                ServiceManager.checkService(LEGACY_KEYSTORE_SERVICE_NAME));
-    }
 
     /** @hide */
     WifiKeystore() {
@@ -93,7 +86,7 @@
                 return blob;
             }
             Log.i(TAG, "Searching for blob in Legacy Keystore");
-            return getLegacyKeystore().get(alias, Process.WIFI_UID);
+            return WifiBlobStore.getLegacyKeystore().get(alias, Process.WIFI_UID);
         } catch (ServiceSpecificException e) {
             if (e.errorCode != ILegacyKeystore.ERROR_ENTRY_NOT_FOUND) {
                 Log.e(TAG, "Failed to get blob.", e);
@@ -122,7 +115,7 @@
             Log.i(TAG, "remove blob. alias " + alias);
             blobStoreSuccess = WifiBlobStore.getInstance().remove(alias);
             // Legacy Keystore will throw an exception if the alias is not found.
-            getLegacyKeystore().remove(alias, Process.WIFI_UID);
+            WifiBlobStore.getLegacyKeystore().remove(alias, Process.WIFI_UID);
             legacyKsSuccess = true;
         } catch (ServiceSpecificException e) {
             if (e.errorCode != ILegacyKeystore.ERROR_ENTRY_NOT_FOUND) {
@@ -151,7 +144,8 @@
         try {
             // Aliases from WifiBlobStore will be pre-trimmed.
             final String[] blobStoreAliases = WifiBlobStore.getInstance().list(prefix);
-            final String[] legacyAliases = getLegacyKeystore().list(prefix, Process.WIFI_UID);
+            final String[] legacyAliases =
+                    WifiBlobStore.getLegacyKeystore().list(prefix, Process.WIFI_UID);
             for (int i = 0; i < legacyAliases.length; ++i) {
                 legacyAliases[i] = legacyAliases[i].substring(prefix.length());
             }
diff --git a/wifi/tests/src/android/net/wifi/WifiKeystoreTest.java b/wifi/tests/src/android/net/wifi/WifiKeystoreTest.java
new file mode 100644
index 0000000..c28a0ae
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/WifiKeystoreTest.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.validateMockitoUsage;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
+
+import android.os.ServiceSpecificException;
+import android.security.legacykeystore.ILegacyKeystore;
+
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.MockitoSession;
+
+import java.util.Arrays;
+
+/** Unit tests for {@link WifiKeystore} */
+public class WifiKeystoreTest {
+    public static final String TEST_ALIAS = "someAliasString";
+    public static final byte[] TEST_VALUE = new byte[]{10, 11, 12};
+
+    @Mock private ILegacyKeystore mLegacyKeystore;
+    @Mock private WifiBlobStore mWifiBlobStore;
+
+    private MockitoSession mSession;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mSession = ExtendedMockito.mockitoSession()
+                .mockStatic(WifiBlobStore.class, withSettings().lenient())
+                .startMocking();
+        when(WifiBlobStore.getLegacyKeystore()).thenReturn(mLegacyKeystore);
+        when(WifiBlobStore.getInstance()).thenReturn(mWifiBlobStore);
+    }
+
+    @After
+    public void cleanup() {
+        validateMockitoUsage();
+        if (mSession != null) {
+            mSession.finishMocking();
+        }
+    }
+
+    /**
+     * Test that put() only writes to the WifiBlobStore database.
+     */
+    @Test
+    public void testPut() throws Exception {
+        WifiKeystore.put(TEST_ALIAS, TEST_VALUE);
+        verify(mWifiBlobStore).put(anyString(), any());
+        verify(mLegacyKeystore, never()).put(anyString(), anyInt(), any());
+    }
+
+    /**
+     * Test that if the alias is found in the WifiBlobStore database,
+     * then the legacy database is not searched.
+     */
+    @Test
+    public void testGet_wifiBlobStoreDb() throws Exception {
+        when(mWifiBlobStore.get(anyString())).thenReturn(TEST_VALUE);
+        assertArrayEquals(TEST_VALUE, WifiKeystore.get(TEST_ALIAS));
+
+        verify(mWifiBlobStore).get(anyString());
+        verify(mLegacyKeystore, never()).get(anyString(), anyInt());
+    }
+
+    /**
+     * Test that if the alias is not found in the WifiBlobStore database,
+     * then the legacy database is searched.
+     */
+    @Test
+    public void testGet_legacyDb() throws Exception {
+        when(mWifiBlobStore.get(anyString())).thenReturn(null);
+        when(mLegacyKeystore.get(anyString(), anyInt())).thenReturn(TEST_VALUE);
+        assertArrayEquals(TEST_VALUE, WifiKeystore.get(TEST_ALIAS));
+
+        verify(mWifiBlobStore).get(anyString());
+        verify(mLegacyKeystore).get(anyString(), anyInt());
+    }
+
+    /**
+     * Test that get() returns a non-null value if the alias is
+     * not found in either database.
+     */
+    @Test
+    public void testGet_notFound() throws Exception {
+        when(mWifiBlobStore.get(anyString())).thenReturn(null);
+        when(mLegacyKeystore.get(anyString(), anyInt()))
+                .thenThrow(new ServiceSpecificException(ILegacyKeystore.ERROR_ENTRY_NOT_FOUND));
+        assertNotNull(WifiKeystore.get(TEST_ALIAS));
+    }
+
+    /**
+     * Test that remove() returns true if the alias is removed
+     * from at least one database.
+     */
+    @Test
+    public void testRemove_success() throws Exception {
+        // Only removed from WifiBlobStore
+        when(mWifiBlobStore.remove(anyString())).thenReturn(true);
+        doThrow(new ServiceSpecificException(ILegacyKeystore.ERROR_ENTRY_NOT_FOUND))
+                .when(mLegacyKeystore).remove(anyString(), anyInt());
+        assertTrue(WifiKeystore.remove(TEST_ALIAS));
+
+        // Only removed from Legacy Keystore
+        when(mWifiBlobStore.remove(anyString())).thenReturn(false);
+        doNothing().when(mLegacyKeystore).remove(anyString(), anyInt());
+        assertTrue(WifiKeystore.remove(TEST_ALIAS));
+
+        // Removed from both WifiBlobStore and Legacy Keystore
+        when(mWifiBlobStore.remove(anyString())).thenReturn(true);
+        doNothing().when(mLegacyKeystore).remove(anyString(), anyInt());
+        assertTrue(WifiKeystore.remove(TEST_ALIAS));
+    }
+
+    /**
+     * Test that remove() returns false if the alias is not removed
+     * from any database.
+     */
+    @Test
+    public void testRemove_notFound() throws Exception {
+        when(mWifiBlobStore.remove(anyString())).thenReturn(false);
+        doThrow(new ServiceSpecificException(ILegacyKeystore.ERROR_ENTRY_NOT_FOUND))
+                .when(mLegacyKeystore).remove(anyString(), anyInt());
+        assertFalse(WifiKeystore.remove(TEST_ALIAS));
+    }
+
+    /**
+     * Test that list() retrieves aliases from both the WifiBlobStore
+     * and Legacy Keystore databases. The results should be de-duplicated.
+     */
+    @Test
+    public void testList() throws Exception {
+        // Aliases retrieved from WifiBlobStore will be pre-trimmed.
+        String[] blobStoreAliases = new String[]{"1", "2"};
+        String[] legacyDbAliases = new String[]{TEST_ALIAS + "2", TEST_ALIAS + "3"};
+        when(mWifiBlobStore.list(anyString())).thenReturn(blobStoreAliases);
+        when(mLegacyKeystore.list(anyString(), anyInt())).thenReturn(legacyDbAliases);
+
+        // Alias 2 exists in both DBs and should be de-duplicated.
+        String[] expected = new String[]{"1", "2", "3"};
+        String[] retrieved = WifiKeystore.list(TEST_ALIAS);
+        Arrays.sort(retrieved);
+        assertArrayEquals(expected, retrieved);
+    }
+}
diff --git a/wifi/wifi.aconfig b/wifi/wifi.aconfig
index 6c4e4c3..3c734bc 100644
--- a/wifi/wifi.aconfig
+++ b/wifi/wifi.aconfig
@@ -1,4 +1,5 @@
 package: "android.net.wifi.flags"
+container: "system"
 
 flag {
     name: "get_device_cross_akm_roaming_support"